Kubernetes RBAC权限控制
实际生产环境中,往往需要对不同运维人员赋预不同的权限.而根据实际情况也可能会赋予开发人员只读的权限.这一节我们将介绍如何创建不同权限的用户.
1.K8S RBAC
RBAC (Role-Based Access Control)是基于角色的访问控制。
K8S RBAC 框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过 API Server 配置来启用插件。
- Authentication 鉴权
- Authorization 授权
- Admission Control 准入控制
上面流程中 Authentication 鉴权插件将返回通过鉴权的主体;然后将其交给 Authorization 授权插件来检查主体是否有权限执行某个操作。
三种客户端 “访问用户” 类型:
- User 用户
- Group 用户组
- ServerAccount K8S 资源对象 SA
三种 Authentication 鉴权方式:
客户端想要访问 K8S 集群 apiserver,可选三种客户端身份鉴权认证:
- HTTPS 证书认证(kubeconfig):基于CA证书签名的数字证书认证
- HTTP Token 认证:通过一个 Token 来识别用户
- HTTP Base 认证:用户名+密码的方式认证(不常用)
Authorization 授权:
RBAC 授权逻辑通过将主体与角色绑定来决定是否可以执行某项操作。主体与角色关联,角色与资源权限关联。
Admission Control 准入控制:
Admission Control 实际上是一个准入控制插件列表,发送 API Server 的请求都需要经过这个列表的每个准入控制插件的检查,检查不通过,则拒绝请求。
2.RBAC 创建流程
(1)创建主体
选择一个主体类型,ServerAccount 是 K8S 较为常用的客户端主体类型。(上面有讲三种类型 user、group、ServerAccount)
(2)创建角色
角色两种 kind 类型:
- Role 授权特定命名空间的访问权限
- ClusterRole 授权所有命名空间的访问权限
Role 与 ClusterRole 最大区别在于,Role 有 namespace 区分,如果要应用在多个 namespace ,需要每个 namespace 下创建一个 Role。或者直接选择 ClusterRole 类型就不受 namespace 的限制。
为角色分配自定义资源权限:
- apiGroups: K8S API 组,核心组为 “”,API Group
- resources:K8S 资源对象,例如 Pod, Deployment, cronjob
- verbs:资源操作方法 get, list, create, update, patch, watch, delete
apiGroups: K8S API 组也可以称之为 Legacy Groups,作为 k8s 最核心的 API ,其特点是没有组的概念,例如 “v1”,在资源对象的定义中表示为 “apiVersion: v1”,属于核心组的资源主要有下面几种:
- Container
- Pod
- ReplicationController
- Endpoint
- Service
- ConfigMap
- Secret
- Volume
- PersistentVolumeClaim
- Event
- LimitRange
- PodTemplate
- Binding
- ComponentStatus
- Namespace
- Node
- jobs
- cronjobs
kubectl api-resources -o wide 命令可以查看到资源、apiGroup API组、verbs 资源操作方法之间的关系。
1 2 3 4 5 6
| > kubectl api-resources -o wide NAME SHORTNAMES APIVERSION NAMESPACED KIND VERBS bindings v1 true Binding [create] componentstatuses cs v1 false ComponentStatus [get list] nodes metrics.k8s.io/v1beta1 false NodeMetrics [get list] pods metrics.k8s.io/v1beta1 true PodMetrics [get list]
|
(3)角色绑定主体
角色绑定主体的 kind 类型也有两种:
RoleBinding 将角色绑定到主体,即 subjects
ClusterRoleBinding 将集群角色绑定到主体
subjects 就是鉴权的主体, kind 类型有三种:
User 用户
Group 用户组
ServerAccount K8S 资源对象 SA
3.案例
案例1:创建一个只有 default名称空间的只读用户的 token
思考创建流程:
主体(SA) -> 角色(Role) -> 角色绑定主体(RoleBinding)
创建主体
创建一个 SA 类型的 主体,注意主体是有名称空间的限制的。
1 2 3 4 5 6 7 8
| $ mkdir -p /opt/kubernetes/cfg/rbac-user $ vim serviceaccount-develop.yaml --- apiVersion: v1 kind: ServiceAccount metadata: name: develop namespace: default
|
此时,基础组件里的 token-controller 自动(根据 –service-account-private-key-file 的证书)为 ServiceAccount 生成 secrets,secrets 中包含的 token 信息,即可用作http token请求中的认证信息。获取 SA TOKEN:
1 2 3 4 5 6 7
| $ kubectl get serviceaccount develop -o jsonpath={.secrets[0].name} develop-token-7wc66
$ kubectl get secret develop-token-7wc66 -o jsonpath={.data.token} | base64 -d
|
获取 serviceaccount 详细信息,方便排查问题。
1 2 3
| kubectl describe serviceaccounts user-admin -n kube-system kubectl get clusterrolebindings.rbac.authorization.k8s.io user-admin kubectl describe clusterrolebindings.rbac.authorization.k8s.io develop-readonly
|
创建角色
创建角色 Role,分配常用资源只读权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| $ vim role-develop.yaml --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: develop namespace: default rules: - apiGroups: [""] resources: ["pods","pods/exec","pods/log","services"] verbs: ["get", "list", "watch", "create"] - apiGroups: ["apps"] resources: ["deployments","daemonsets","statefulsets"] verbs: ["get", "list", "watch"] - apiGroups: ["batch"] resources: ["jobs","cronjobs"] verbs: ["get", "list", "watch"]
|
角色绑定主体
创建角色绑定 RoleBinding:
- roleRef 绑定的角色规则
- subject 绑定的角色的主体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| $ vim rolebinding-develop.yaml --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: develop namespace: default roleRef: kind: Role name: develop apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: develop namespace: default
|
上述 RBAC 权限账号创建完成。由于 Role 和 Rolebinding 都在 default 下创建,所以只能访问 default 命名空间下的资源(仅限 Role 中配置的资源和 action)。
案例2:创建一个有所有名称空间的只读用户的 token
与案例1区别的是,使用的是 ClusterRole + ClusterRoleBinding,对所有 namespace 有权限,结合 Jumpserver 可以快速进入容器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| --- apiVersion: v1 kind: ServiceAccount metadata: name: develop namespace: default
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: develop rules: - apiGroups: [""] resources: ["pods","pods/exec","pods/log","services"] verbs: ["get", "list", "watch", "create"] - apiGroups: ["apps"] resources: ["deployments","daemonsets","statefulsets"] verbs: ["get", "list", "watch"] - apiGroups: ["batch"] resources: ["jobs","cronjobs"] verbs: ["get", "list", "watch"]
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: develop namespace: default roleRef: kind: ClusterRole name: develop apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: develop namespace: default
|
给程序员使用只读RBAC权限用户,结合Jumpserver可以快速进入容器排障。
案例3:创建超级管理员的 token
k8s创建管理员token
1 2 3 4 5 6 7 8
| $ kubectl create serviceaccount user-admin -n kube-system
$ kubectl create clusterrolebinding user-admin --clusterrole=cluster-admin --serviceaccount=kube-system:user-admin
$ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/user-admin/{print $1}')
|
案例4:创建一个只读SA用户:develop-readonly
kubernetes实战篇之创建一个只读权限的用户
创建用户
1
| kubectl create serviceaccount develop-readonly -n kube-system
|
或者
serviceaccount-develop-readonly.yaml
1 2 3 4 5 6
| --- apiVersion: v1 kind: ServiceAccount metadata: name: develop-readonly namespace: kube-system
|
创建策略
clusterrole-develop-readonly.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
| --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: develop-readonly rules: - apiGroups: - "" resources: - configmaps - endpoints - persistentvolumeclaims - pods - replicationcontrollers - replicationcontrollers/scale - serviceaccounts - services - nodes - persistentvolumeclaims - persistentvolumes verbs: - get - list - watch - apiGroups: - "" resources: - bindings - events - limitranges - namespaces/status - pods/log - pods/status - replicationcontrollers/status - resourcequotas - resourcequotas/status verbs: - get - list - watch - apiGroups: - "" resources: - namespaces verbs: - get - list - watch - apiGroups: - apps resources: - daemonsets - deployments - deployments/scale - replicasets - replicasets/scale - statefulsets verbs: - get - list - watch - apiGroups: - autoscaling resources: - horizontalpodautoscalers verbs: - get - list - watch - apiGroups: - batch resources: - cronjobs - jobs verbs: - get - list - watch - apiGroups: - extensions resources: - daemonsets - deployments - deployments/scale - ingresses - networkpolicies - replicasets - replicasets/scale - replicationcontrollers/scale verbs: - get - list - watch - apiGroups: - policy resources: - poddisruptionbudgets verbs: - get - list - watch - apiGroups: - networking.k8s.io resources: - networkpolicies - ingresses - ingressclasses verbs: - get - list - watch - apiGroups: - storage.k8s.io resources: - storageclasses - volumeattachments verbs: - get - list - watch - apiGroups: - rbac.authorization.k8s.io resources: - clusterrolebindings - clusterroles - roles - rolebindings verbs: - get - list - watch
|
用户和策略绑定
clusterrolebinding-develop-readonly.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13
| --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: develop-readonly subjects: - kind: ServiceAccount name: develop-readonly namespace: kube-system roleRef: kind: ClusterRole name: develop-readonly apiGroup: rbac.authorization.k8s.io
|
查看对应的权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| kubectl describe clusterrole develop-readonly Name: develop-readonly Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- bindings [] [] [get list watch create] events [] [] [get list watch create] limitranges [] [] [get list watch create] namespaces/status [] [] [get list watch create] pods/exec [] [] [get list watch create] pods/log [] [] [get list watch create] pods/status [] [] [get list watch create] replicationcontrollers/status [] [] [get list watch create] resourcequotas/status [] [] [get list watch create] resourcequotas [] [] [get list watch create] configmaps [] [] [get list watch] endpoints [] [] [get list watch] namespaces [] [] [get list watch] nodes [] [] [get list watch] persistentvolumeclaims [] [] [get list watch] persistentvolumes [] [] [get list watch] pods [] [] [get list watch] replicationcontrollers/scale [] [] [get list watch] replicationcontrollers [] [] [get list watch] serviceaccounts [] [] [get list watch] services [] [] [get list watch] daemonsets.apps [] [] [get list watch] deployments.apps/scale [] [] [get list watch] deployments.apps [] [] [get list watch] replicasets.apps/scale [] [] [get list watch] replicasets.apps [] [] [get list watch] statefulsets.apps [] [] [get list watch] horizontalpodautoscalers.autoscaling [] [] [get list watch] cronjobs.batch [] [] [get list watch] jobs.batch [] [] [get list watch] daemonsets.extensions [] [] [get list watch] deployments.extensions/scale [] [] [get list watch] deployments.extensions [] [] [get list watch] ingresses.extensions [] [] [get list watch] networkpolicies.extensions [] [] [get list watch] replicasets.extensions/scale [] [] [get list watch] replicasets.extensions [] [] [get list watch] replicationcontrollers.extensions/scale [] [] [get list watch] ingressclasses.networking.k8s.io [] [] [get list watch] ingresses.networking.k8s.io [] [] [get list watch] networkpolicies.networking.k8s.io [] [] [get list watch] poddisruptionbudgets.policy [] [] [get list watch] clusterrolebindings.rbac.authorization.k8s.io [] [] [get list watch] clusterroles.rbac.authorization.k8s.io [] [] [get list watch] rolebindings.rbac.authorization.k8s.io [] [] [get list watch] roles.rbac.authorization.k8s.io [] [] [get list watch] storageclasses.storage.k8s.io [] [] [get list watch] volumeattachments.storage.k8s.io [] [] [get list watch]
|
查看token
1
| kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/develop-readonly/{print $1}')
|
参考资料1
参考资料2