Kubernetes 中的用户与RBAC中的关系图如下
接下来将依依讲述
Kubernetes 中的用户
Kubernetes 集群中包含两类用户:
用户类型 | 管理者 |
---|---|
ServiceAccount(服务账户) | 由Kubernetes API管理 |
User(普通用户) | 由外部独立服务管理,k8s没有代表普通用户账户的对象 |
由于k8s没有代表普通用户账号的对象.无法通过api调用的方式向集群添加普通用户 ServiceAccount是由Kubernetes API 管理的账户. 它们都绑定到了特定的namespace, 并由API server自动创建,或者通过调用api手动创建.ServiceAccount关联了一套凭证, 存储在Secret,这些凭证同时被挂载到pod中, 从而允许pod与kubernetes API之间的调用.
API请求被绑定到普通用户(User) 或者ServiceAccount上, 或者作为匿名请求对待.这意味着 集群内部或者外部的每个进程,无论从在工作站上输入 kubectl的用户到节点的kubelet,到控制 平面的成员,都必须在向API Server发出请求是进行身份验证,或者被视为匿名用户. kubectl使用的kubeconfig,其中kubeconfig中的User使用的就是普通用户(证书认证),在k8s对象里面查不到
RBAC 基于角色的访问控制
Role与ClusterRole
在RBAC API 中, 一个角色包含了一套表示一组权限的规则. 权限是以累加的形式累计(没有"否定"的规则). 角色可以由命名空间(namespace)内的Role对象定义, 而整个kubernetes集群范围内有效的角色则通过ClusterRole对象实现.
一个Role对象只能用于授予对某一单一命名空间中资源的访问权限. 下面实例描述了"default"命名空间中的一个Role对象的定义, 用于授予对Role的读访问权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: test-pod-reader
namespace: default
rules:
- apiGroups: [""] # 空字符串"" 表明使用core API group
resources: ["pods"]
verbs: ["get", "watch", "list" ]
ClusterRole 对象可以授予与Role 对象相同的权限, 但由于它们属于集群范围对象, 也可以使用它们授权以下几种资源的访问权限:
- 集群范围资源(例如: 节点, 即node)
- 非资源类型endpoint(例如: “/healthz”)
- 跨所有命名空间的命名空间范围资源(例如: pod, 需要运行命令: kubect get pods –all-namespaces来查询集群中所有的pod)
下面示例中的ClusterRole 定义可用于授权用户对某一特定命名空间, 或者所有命名空间中的secret(取决于其绑定方式)的读访问权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# 鉴于 ClusterRole是集群范围对象, 所有这里不需要定义"namespace" 字段
name: test-secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
RoleBinding与ClusterRolebinding
角色绑定将一个角色中定义的各种权限授予一个或者一组用户. 角色绑定包含了一组相关主体(即subject,包括用户–User,用户组–Group, 或者服务账户–Service Account)以及对被授予角色的引用. 在命名空间中可以通过RoleBinding 对象授予权限, 而集群范围的权限授予则 通过ClusterRoleBinding 对象完成.
RoleBinding 可以引用在同一命名空间内定义的Role对象. 下面示例中定义的RoleBinding 对象 在"default" 命名空间中将"test-pod-reader" 角色授予用户"richie". 这一授权将允许用户"richie" 从"default" 命名空间中读取pod。
# 以下角色绑定定义将允许用户"richie" 从"default"命名空间中读取pod.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test-read-pods
namespace: default
subjects:
- kind: User
name: richie
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: test-pod-reader
apiGroup: rbac.authorization.k8s.io
RoleBinding 对象也可以引用一个ClusterRole对象用于在RoleBding 所在的命名空间内授予用户对所引用的ClusterRole中定义的命名空间资源的访问. 这一点允许管理员在整个集群范围内首先定义一组通用的角色, 然后再在不同的命名空间中服用整个角色.
例如: 尽管下面示例中的RoleBinding 引用的是一个ClusterRole对象, 但是用户"zrq"(即角色绑定主体) 还是只能读取"development"命名空间中的 secret(即 RoleBinding所在的命名空间)
# 以下角色绑定允许用户"zrq" 读取"development" 命名空间中的secret
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-secrets
namespace: development # 这里表明仅授权读取"development" 命名空间中的资源
subjects:
- kind: User
name: zrq
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: test-secret-reader
apiGroup: rbac.authorization.k8s.io
最后, 可以使用ClusterRoleBinding 在集群级别和所有命名空间中授予权限. 下面示例中所定义的ClusterRoleBinding 允许用户组"manager"中的 任何用户都可以读取集群中任何命名空间中的secret.
# 以下ClusterRoleBinding 对象允许在用户组"manager" 中的任何用户都可以读取集群中任何命名空间的secret.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: test-secret-reader
apiGroup: rbac.authorization.k8s.io
对资源的引用
大多数资源由代表其名字的字符串表示, 例如"pods", 就像它们出现在相关API endpoint的URL中一样. 然而, 有些Kubernetes API 还包含了"子资源", 比如 pod的logs 在Kubernetes中, pod logs endpoint的URL 格式为:
GET /api/v1/namespaces/{namespace/pods/{name}/log
在这种情况下, “pods"是命名空间资源, 而"log"是pods的子资源. 为了在RBAC角色中表示出这一点, 我们需要使用斜线来划分 资源和子资源. 如果需要角色绑定主体读取pods以及pod log, 您需要定义以下角色:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-and-pod-logs-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pod", "pods/log"]
verbs: ["get", "list"]
通过resourceNames 列表, 角色可以针对不同种类的请求根据资源名称引用资源实例. 当指定了resourceName 列表时, 不同的 动作类型的权限, 如使用"get”, “delete”, “update"以及"patch"等动词的请求, 将被限定到资源列表中所包含的资源实例上. 例如,如果需要限定一个角色绑定主体只能"get” 或者"update" 一个configmap时, 您可以定义一下角色:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: configmap-updater
namespace: default
rules:
- apiGroups: [""]
resources: ["configmap"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
值得注意的是, 如果设置了 resourceNames, 则请求所使用的动词不能是list, watch, create或者deletecollection. 由于 资源名称不会出现在create, list, watch和deletecollection等API请求的URL中, 所以这些请求动词不会被设置了resourceNames的规则所允许, 因为规则中的resourceNames部分不会匹配这些请求.
一些角色定义的例子
以下示例中, 我们仅截取展示了rules部分的定义.
允许读取core API Group 中定义的资源"pods":
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
允许读写在"extensions" 和"apps" API Group中定义的"deployments":
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
允许读取"pods"以及读写"jobs":
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
允许读取一个名为"my-config"的configMap实例(需要将其通过RoleBinding绑定从而限制针对某一个命名空间中定义的一个ConfigMap实例的访问):
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-config"]
verbs: ["get"]
允许读取core API Group中的"nodes" 资源(由于Node是集群级别资源, 所以此ClusterRole 定义需要与一个ClusterRoleBinding绑定才能有效):
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
允许对非资源endpoint “/healthz"及其所有子路径的"GET"和"POST” 请求(此ClusterRole 定义需要与一个ClusterRoleBinding绑定才能有效):
rules:
- nonResourcesURLs: ["/healthz", "/healthz/*"] # 在非资源URL中, '*' 代表后缀通配符
verbs: ["get", "post"]
对角色绑定主体(Subject) 的引用
RoleBinding 或者ClusterRoleBinding 将角色绑定到角色绑定主体(Subject). 角色绑定主体可以是用户组(Group), 用户(User) 或者服务账户(Service Accounts).
用户由字符串来表示. 可以是纯粹的用户名, 例如: “richie”、电子邮件风格的名字, 如: “zrq@example.com"或者是用字符串表示的数字id. 有Kubernetes管理员配置认证以及产生所需格式的用户名. 对于用户名,RBAC授权系统不要求任何特定的格式.然而, 前缀system: 是为Kubernetes系统使用而保留的, 所以管理员应该确保用户名不会意外地包含这个前缀.
Kubernetes 中的用户组信息由授权模块提供. 用户组与用户一样由字符串来表示. Kubernetes 对用户组字符串没有格式要求, 但前缀system: 同样是被系统保留的.
服务账户(Service Account )拥有包含system:serviceaccount: 前缀的用户名, 并属于拥有system:serviceaccounts:前缀的用户组
角色绑定的一些例子
以下示例中, 仅截取展示了 RoleBinding的subjects字段.
一个名字为"zrq@example.com"的用户:
subjects:
- kind: User
name: "zrq@example.com"
apiGroup: rbac.authorization.k8s.io
一个名为"frontend-amins"的用户组:
subjects:
- kind: Group
name: "frontend-admins"
apiGroup: rbac.authorization.k8s.io
kube-system命名空间中的默认服务账户:
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
名为"galaxy” 命名空间中的所有服务账户:
subjects:
- kind: Group
name: system:serviceaccount:galaxy
apiGroup: rbac.authorization.k8s.io
在集群中的所有服务账户:
subjects:
- kind: Group
name: system-serviceaccounts
apiGroup: rbac.authorization.k8s.io
所有认证过的用户(version 1.5+):
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
所有未认证的用户(version 1.5+):
subjects:
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
所有用户(version 1.5+):
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: system.unauthenticated
apiGroup: rbac.authorization.k8s.io
默认角色与默认角色绑定
API Server 会创建一组默认的ClusterRole和ClusterRoleBinding对象. 这些默认对象中有许多包含system:前缀, 表明这些资源由Kubernetes基础组件"拥有". 对这些资源的修改可能导致非功能集群(non-functional cluster).一个 例子是 system:node ClusterRoled对象. 这个角色定义了kubernetes的quanx.如果这个角色被修改, 可能会导致kubeletes无法正常工作.
所有默认的ClusterRole和ClusterRoleBinding对象都会被标记为kubernetes.io/bootstrapping=rbac-defaults.
自动更新
每次启动时, API Server 都会更新默认ClusterRole所缺乏的各种权限, 并更新默认ClusterRoleBinding所缺乏的各个角色绑定主体.这种自动更新机制允许集群修复一些意外的修改.由于权限和角色绑定主体在Kubernetes释出版本中可能变化, 这也能够确保角色和角色绑定始终保持是最新的.
如果需要禁用自动更新, 请将默认ClusterRole以及ClusterRoleBinding的rbac.authorization.kubernetes.io/autoupdate设置为false. 请注意, 缺乏默认权限和角色绑定主体可能会导致非功能性集群问题.
自Kubernetes 1.6+起. 当集群RBAC授权器(RBAC Authorizer) 处于开启状态时,可以启用自动更新功能.
发现类角色
默认ClusterRole | 默认ClusterRoleBinding | 描述 |
---|---|---|
system:basic-user | system:authenticated and system:unauthenticated groups | 允许用户只读访问有关自己的基本信息 |
system:discovery | system: authenticated and system:unauthenticated groups | 允许只读访问API discovery endpoints,用于API级别进行发现和协商 |
面向用户的角色
一些默认角色并不包含system:前缀, 它们是面向用户的角色. 这些角色包含超级用户角色(cluster-admin),即旨在利用ClusterRoleBinding(cluster-status)在集群范围内授权的角色, 以及那些使用RoleBinding(admin, edit和view)在特定命名空间中授权的角色.
默认ClusterRole | 默认ClusterRoleBinding | 描述 |
---|---|---|
cluster-admin | system:masters group | 超级用户权限, 允许对任何资源执行任何操作.在ClusterRoleBinding中使用是, 可以完全控制集群和所有命名空间中的所有资源. 在RoleBinding 中使用时, 可以完全控制RoleBinding所在的命名空间中的所有资源,包括命名空间自己. |
admin | None | 管理员权限, 利用RoleBinding 在某一命名空间内部授予. 在RoleBinding 中使用时, 允许针对命名空间内大部分资源的读写访问, 包括在命名空间内创建角色与角色绑定的能力. 但不允许对资源配置(resource quota)或者命名空间本身的写访问 |
edit | None | 允许对某一个命名空间内大部分对象的读写访问, 但不允许查看或者修改角色或者角色绑定. |
view | Nonw | 允许对某一个命名空间内大部分对象的只读访问. 不允许查看角色或者角色绑定. 由于可扩散性等原因, 不允许查看secret资源. |
Core Component Roles
核心组件角色
默认ClusterRole | 默认ClusterRoleBinding | 描述 |
---|---|---|
system:kube-scheduler | system:kube-scheduler user | 允许访问kube-scheduler 组件所需要的资源 |
system:kube-controller-manager | system:kube-controller-manager user | 允许访问kube-controller-manager组件所需要的资源. |
system:node | system:nodes group(deprecated in 1.7) | 允许对kubelet组件所需要的资源的访问,包括读取所有secret和对所有pod的写访问。 自Kubernetes 1.7开始, 相比较于这个角色,更推荐使用Node authorizer 以及NodeRestriction admission plugin, 并允许根据调度运行在节点上的pod授予kubelets API访问的权限。 自Kubernetes 1.7开始,当启用Node授权模式时,对system:nodes用户组的绑定将不会被自动创建 |
system:node-proxier | system:kube-proxy user | 允许对kube-proxy 组件所需要资源的访问. |
其他组件角色
默认ClusterRole | 默认ClusterRoleBinding | 描述 |
---|---|---|
system:auth-delegator | None | 允许委托认证和授权检查. 通常由附加API Server用于统一认证和授权 |
system:heapster | None | Heapster 组件的角色 |
system:kube-aggregator | None | kube-aggregator 组件的角色 |
system:kube-dns | kube-dns service account in the kube-sysemnamespace | kube-dns 组件的角色 |
system:node-boostrapper | None | 允许对执行Kubelet TLS 引导(kubelet TLS boostrapping) 所需要资源的访问 |
system:node-problem-detector | None | node-problem-detector组件的角色 |
system: persistent-volume-provisioner | None | 允许对大部分动态存储卷创建组件(dynamic volume provisioner) 所需要资源的访问 |
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付
