kubernetes(k8s)之rbac权限管理详解

RBAC简介

RBAC(Role-Based Access Control)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C5QFijae-1660472909213)(C:\Users\83493\AppData\Roaming\Typora\typora-user-images\1659504463105.png)]

基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对 计算机或网络资源的访问的方法。

kubernetes集群相关所有操作都是通过apiserver来完成的,RBAC 鉴权机制使用 rbac.authorization.k8s.io API 组来驱动鉴权决定, 允许你通过 Kubernetes API 动态配置策略。

RBAC API 声明了四种 Kubernetes 对象,RoleClusterRoleRoleBindingClusterRoleBinding。可以像使用其他 Kubernetes 对象一样,通过类似 kubectl 这类工具描述对象, 或修补对象。

kubernetes启用rbac

启用rbac需要在apiserver启动添加参数--authorization-mode=RBAC

# grep 'authorization-mode' /opt/TLS/k8s/cfg/kube-apiserver.conf 
--authorization-mode=RBAC,Node \

API Server目前支持以下几种授权策略:

  • AlwaysDeny:表示拒绝所有请求,一般用于测试。
  • AlwaysAllow:允许接收所有请求。 如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。
  • ABAC(Attribute-Based Access Control):基于属性的访问控制。 表示使用用户配置的授权规则对用户请求进行匹配和控制。
  • Webhook:通过调用外部REST服务对用户进行授权。
  • RBAC:Role-Based Access Control,基于角色的访问控制。
  • Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。

用户分类

k8s用户分两种,一钟是普通用户,一种是serviceaccount服务账户

普通用户

普通用户是被外部或独立服务管理的,使用的kubectl命令则是普通用户,为Linux创建的用户

普通用户需求权限,通过role与user(或group)绑定,给用户使用

serviceaccount

serviceaccount使用kubernetes API管理的用户。它们绑定到特定的命名空间,并由api服务器自动创建或通过api调用手动创建

如果程序需求权限,通过role与serviceaccount指定,创建serviceaccount并且在资源对象钟指定serviceaccount,给程序使用

k8s角色和角色绑定

授权介绍

RBAC 的 RoleClusterRole 中包含一组代表相关权限的规则。 这些权限是纯粹累加的(不存在拒绝某操作的规则)。 通过定义角色、绑定角色进行授权

角色

  • Role:授权特定命名空间的访问权限
  • ClusterRole:授权所有命名空间的访问权限

角色绑定

  • RoleBinding:将角色绑定到主体(即subject)
  • ClusterRoleBinding:将集群角色绑定到主体

主体(subject)

  • User:用户
  • Group:用户组
  • ServiceAccount:服务账号

图解如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMeZdQBl-1660472909214)(C:\Users\83493\AppData\Roaming\Typora\typora-user-images\1659505770340.png)]

实例

role

role资源清单详解

官方:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/authorization-resources/role-v1/

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:   #标准的对象元数据。
  name:   #role名称。
  namespace:  #role权限对应的namespace。
rules:   #rules 包含了这个 Role 的所有 PolicyRule。
  apiGroups:   #apiGroups 是包含资源的 apiGroup 的名称。
  nonResourceURLs:   #nonResourceURLs 是用户应有权访问的一组部分 URL。
  resourceNames:   #resourceNames 是此规则所适用的资源名称白名单,空为所有资源。
  resources:   #resources 是此规则所适用的资源的列表。 “*” 表示所有资源。
  verbs:   #verbs 是适用于此规则中所包含的所有 ResourceKinds 的动作。 “*” 表示所有动作。
对某个资源类型的权限分配

编写yaml文件

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default   #位于default命名空间
  name: pod-reader   #role名称
rules:
- apiGroups: [""]   # "" 标明 core API 组
  resources: ["pods"]   #资源对象
  verbs: ["get", "watch", "list"]   #权限

查看

# kubectl describe role pod-reader
Name:         pod-reader
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get watch list]
获取某个资源的子资源

pods 对应名字空间作用域的 Pod 资源,而 logpods 的子资源。 在 RBAC 角色表达子资源时,使用斜线(/)来分隔资源和子资源。

编写yaml文件

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default   #位于default命名空间
  name: pod-and-pod-logs-reader   #role名称
rules:
- apiGroups: [""]   # "" 标明 core API 组
  resources: ["pods", "pods/log"]   #资源对象和资源对象的子资源
  verbs: ["get", "list"]   #权限

查看

# kubectl describe role pod-and-pod-logs-reader
Name:         pod-and-pod-logs-reader
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods/log   []                 []              [get list]
  pods       []                 []              [get list]
配置某一个具体资源的权限

对于某些请求,也可以通过 resourceNames 列表按名称引用资源。 在指定时,可以将请求限定为资源的单个实例。

编写yaml文件

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default   #位于default命名空间
  name: default-configmap-updater   #role名称
rules:
- apiGroups: [""]
  resources: ["configmaps"]   # 在 HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
  resourceNames: ["my-configmap"]   #名为my-configmap的configmap资源
  verbs: ["update", "get"]   #权限

查看

# kubectl describe role default-configmap-updater
Name:         default-configmap-updater
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources   Non-Resource URLs  Resource Names  Verbs
  ---------   -----------------  --------------  -----
  configmaps  []                 [my-configmap]  [update get]

clusterrole

clusterrole资源清单

官方:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/authorization-resources/cluster-role-v1/

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:   #标准的对象元数据。
  name:   #clusterrole名称。
aggregationRule:   #描述如何定位并聚合其它 ClusterRole 到此 ClusterRole。
  clusterRoleSelectors:   #保存了一个选择器列表,用于查找ClusterRoles和创建规则。
    matchLabels:   #选择运算符。
rules:   #rules 包含了这个 ClusterRole 的所有 PolicyRule。
  apiGroups:   #apiGroups 是包含资源的 apiGroup 的名称。
  nonResourceURLs:   #nonResourceURLs 是用户应有权访问的一组部分 URL。
  resourceNames:   #resourceNames 是此规则所适用的资源名称白名单,空为所有资源。
  resources:   #resources 是此规则所适用的资源的列表。“*” 表示所有资源。
  verbs:   #verbs 是适用于此规则中所包含的所有 ResourceKinds 的动作。 “*” 表示所有动作。
clusterrole示例

ClusterRole 可以和 Role 相同完成授权。 因为 ClusterRole 属于集群范围,所以它也可以为以下资源授予访问权限:

  • 集群范围资源(比如节点Node)

  • 非资源端点(比如 /healthz

  • 跨名字空间访问的名字空间作用域的资源(如 Pod)

    比如,你可以使用 ClusterRole 来允许某特定用户执行 kubectl get pods --all-namespaces

下面是一个 ClusterRole 的示例,可用来为任一特定名字空间中的 Secret授予读访问权限, 或者跨名字空间的访问权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
  name: secret-reader   #clusterrole集群名字
rules:
- apiGroups: [""]
  resources: ["secrets"]   # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
  verbs: ["get", "watch", "list"]   #权限

查看

# kubectl describe clusterrole secret-reader
Name:         secret-reader
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  secrets    []                 []              [get list watch]
aggregationRule聚合ClusteRole

你可以将若干 ClusterRole 聚合(Aggregate) 起来,形成一个复合的 ClusterRole。 作为集群控制面的一部分,控制器会监视带有 aggregationRule 的 ClusterRole 对象集合。aggregationRule 为控制器定义一个标签 选择算符供后者匹配 应该组合到当前 ClusterRole 的 roles 字段中的 ClusterRole 对象。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring   #clusterrole名称
aggregationRule:   #描述聚合其他clusterrole
  clusterRoleSelectors:   #clusterrole标签选择器
  - matchLabels:   #选择运算符
      rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # 控制面自动填充这里的规则

查看

# kubectl describe clusterrole monitoring
Name:         monitoring
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----

创建一个与某个已存在的聚合 ClusterRole 的标签选择算符匹配的 ClusterRole, 这一变化会触发新的规则被添加到聚合 ClusterRole 的操作。 下面的例子中,通过创建一个标签同样为 rbac.example.com/aggregate-to-monitoring: true 的 ClusterRole,新的规则可被添加到 “monitoring” ClusterRole 中。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-endpoints   #clusterrole名称
  labels:   #clusterrole标签
    rbac.example.com/aggregate-to-monitoring: "true"
# 当创建 "monitoring-endpoints" ClusterRole 时,
# 下面的规则会被添加到 "monitoring" ClusterRole 中
rules:
- apiGroups: [""]
  resources: ["services", "endpoints", "pods"]
  verbs: ["get", "list", "watch"]

查看monitoring-endpoints

# kubectl describe clusterrole monitoring-endpoints 
Name:         monitoring-endpoints
Labels:       rbac.example.com/aggregate-to-monitoring=true
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  endpoints  []                 []              [get list watch]
  pods       []                 []              [get list watch]
  services   []                 []              [get list watch]

再次查看monitoring

# kubectl describe clusterrole monitoring
Name:         monitoring
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  endpoints  []                 []              [get list watch]
  pods       []                 []              [get list watch]
  services   []                 []              [get list watch]

RoleBinding

RoleBinding资源清单

官方:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/authorization-resources/role-binding-v1/

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:   #标准的对象元数据。
  name:   #rolebinding名称。
roleRef:   #包含指向正被使用的角色的信息。
  apiGroup:   #被引用资源的组。
  kind:   #被引用的资源的类别。
  name:   #被引用的资源的名称。
subjects:   #角色所适用的对象的引用。
  apiGroup:   #apiGroup 包含被引用主体的 API 组。
  kind:   #被引用的对象的类别。
  name:   #被引用的对象的名称。
  namespace:   #被引用的对象的命名空间。
RoleBinding绑定Role
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pod
# 你需要在该命名空间中有一个名为 “pod-reader” 的 Role
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: User
  name: jane # "name" 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
  kind: Role        # 此字段必须是 Role 或 ClusterRole
  name: pod-reader  # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
  apiGroup: rbac.authorization.k8s.io

查看

# kubectl describe rolebinding read-pods
Name:         read-pods
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  pod-reader
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  jane  

检查是否

# useradd jane
# cp -rf /root/.kube/ /home/jane/
# chown -R jane:jane /home/jane/
# su jane
$ kubectl config get-contexts
CURRENT   NAME      CLUSTER      AUTHINFO        NAMESPACE
*         default   kubernetes   cluster-admin   

$ kubectl config set-context jane@kubernetes --cluster=kubernetes --user=jane --namespace=default
Context "jane@kubernetes" created.

$ kubectl config use-context jane@kubernetes
Switched to context "jane@kubernetes".

$ kubectl config get-contexts
CURRENT   NAME              CLUSTER      AUTHINFO        NAMESPACE
          default           kubernetes   cluster-admin   
*         jane@kubernetes   kubernetes   jane            default

RoleBinding绑定ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定使得用户 "dave" 能够读取 "development" 名字空间中的 Secrets
# 你需要一个名为 "secret-reader" 的 ClusterRole
kind: RoleBinding
metadata:
  name: read-secrets
  # RoleBinding 的名字空间决定了访问权限的授予范围。
  # 这里隐含授权仅在 "development" 名字空间内的访问权限。
  namespace: development
subjects:
- kind: User
  name: dave # 'name' 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

查看

# kubectl describe -n development rolebinding
Name:         read-secrets
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  secret-reader
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  dave  

ClusterRoleBinding

ClusterRoleBinding资源清单

官方:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/authorization-resources/cluster-role-binding-v1/

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:   #标准对象的元数据。
  name:   #clusterrolebinding名称。
roleRef:   #指向正被使用的角色的信息。
  apiGroup:   #被引用资源的组。
  kind:   #被引用的资源的类别。
  name:   #被引用的资源的名称
subjects:   #角色所适用的对象的引用。
  apiGroup:   #被引用主体的 API 组。
  kind:   #被引用的对象的类别。
  name:   #被引用的对象的名称。
  namespace:   #被引用对象的命名空间。
ClusterRoleBinding绑定某个组
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 Secret 资源
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager      # 'name' 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

查看

# kubectl describe clusterrolebinding read-secrets-global
Name:         read-secrets-global
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  secret-reader
Subjects:
  Kind   Name     Namespace
  ----   ----     ---------
  Group  manager  
ClusterRoleBinding绑定某个用户
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: user-read-secrets-global
subjects:
- kind: User
  name: manager-user     
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

查看

# kubectl describe clusterrolebinding user-read-secrets-global
Name:         user-read-secrets-global
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  secret-reader
Subjects:
  Kind  Name          Namespace
  ----  ----          ---------
  User  manager-user  

服务账号在 kube-system 命名空间中:

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

在名称为 “qa” 命名空间中所有的服务账号:

subjects:
- kind: Group
  name: system:serviceaccounts:qa
  apiGroup: rbac.authorization.k8s.io

所有的服务账号:

subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

所有认证过的用户 (版本 1.5+):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

所有未认证的用户 (版本 1.5+):

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

所有用户 (版本 1.5+):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

参考

Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io


所有认证过的用户 (版本 1.5+):

```javascript
subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

所有未认证的用户 (版本 1.5+):

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

所有用户 (版本 1.5+):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

参考

https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/#restrictions-on-role-creation-or-update

Logo

开源、云原生的融合云平台

更多推荐