集群命名空间RBAC授权
应用现状
CCE的权限控制分为集群权限和命名空间权限两种权限范围,其中命名空间权限是基于Kubernetes RBAC能力的授权,可以对集群和命名空间内的资源进行授权。
当前,在CCE控制台,命名空间权限默认提供cluster-admin、admin、edit、view四种ClusterRole角色的权限,这四种权限是针对命名空间中所有资源进行配置,无法对命名空间中不同类别资源(如Pod、Deployment、Service等)的增删改查权限进行配置。
解决方案
Kubernetes提供一套RBAC授权机制,可以非常方便的实现命名空间内容资源的权限控制。
- Role:角色,其实是定义一组对Kubernetes资源(命名空间级别)的访问规则。
- RoleBinding:角色绑定,定义了用户和角色的关系。
- ClusterRole:集群角色,其实是定义一组对Kubernetes资源(集群级别,包含全部命名空间)的访问规则。
- ClusterRoleBinding:集群角色绑定,定义了用户和集群角色的关系。
Role和ClusterRole指定了可以对哪些资源做哪些动作,RoleBinding和ClusterRoleBinding将角色绑定到特定的用户、用户组或ServiceAccount上。如下图所示。
上图中的用户在CCE中可以是IAM用户或用户组,通过这样的绑定设置,就可以非常方便的实现命名空间内容资源的权限控制。
下面将通过给一个IAM用户user-example配置查看Pod的权限(该用户只有查看Pod的权限,没有其他权限),演示Kubernetes RBAC授权方法。
前提条件
本文所述方法仅在v1.11.7-r2及以上版本集群上生效,因为只有v1.11.7-r2及以上版本集群开启了RBAC功能。
创建IAM用户和用户组
使用账号登录IAM,在IAM中创建一个名为user-example的IAM用户和名为cce-role-group的用户组,如下所示。创建IAM用户和用户组的具体步骤请参见创建IAM用户和创建用户组。
创建后给cce-role-group用户组授予CCE FullAccess权限,如下所示。给用户组授权的方法具体请参见给用户组授权。
CCE FullAccess拥有集群操作相关权限(包括创建集群等),但是没有操作Kubernetes资源的权限(如查看Pod)。
创建集群
使用账号登录CCE,并创建一个集群。
注意不要使用IAM用户user-example创建集群,因为CCE会自动为创建集群的用户添加该集群所有命名空间cluster-admin权限,也就是说该用户允许对集群以及所有命名空间中的全部资源进行完全控制。
使用IAM用户user-example登录CCE控制台,在集群中下载kubectl配置文件并连接集群,执行命令获取Pod信息,可以看到没有相关权限,同样也无查看其它资源的权限。这说明user-example这个IAM用户没有操作Kubernetes资源的权限。
# kubectl get pod Error from server (Forbidden): pods is forbidden: User "0c97ac3cb280f4d91fa7c0096739e1f8" cannot list resource "pods" in API group "" in the namespace "default" # kubectl get deploy Error from server (Forbidden): deployments.apps is forbidden: User "0c97ac3cb280f4d91fa7c0096739e1f8" cannot list resource "deployments" in API group "apps" in the namespace "default"
创建Role和RoleBinding
使用账号登录CCE控制台,在上一步创建的集群中下载kubectl配置文件并连接集群,然后创建Role和RoleBinding。
此处使用账号是因为集群是使用账号创建,CCE在创建集群时会自动给该账号添加cluster-admin权限,也就是有权限创建Role和RoleBinding。您也可以使用其他拥有创建Role和RoleBinding权限的IAM用户来操作。
Role的定义非常简单,指定namespace,然后就是rules规则。如下面示例中的规则就是允许对default命名空间下的Pod进行GET、LIST操作。
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default # 命名空间 name: role-example rules: - apiGroups: [""] resources: ["pods"] # 可以访问pod verbs: ["get", "list"] # 可以执行GET、LIST操作
- apiGroups表示资源所在的API分组。
- resources表示可以操作哪些资源:pods表示可以操作pod,其他Kubernetes的资源如deployments、configmaps等都可以操作
- verbs表示可以执行的操作:get表示查询一个Pod,list表示查询所有Pod。您还可以使用create(创建), update(更新), delete(删除)等操作词。
详细的类型和操作请参见使用 RBAC 鉴权。
有了Role之后,就可以将Role与具体的用户绑定起来,实现这个的就是RoleBinding了。如下所示。
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: RoleBinding-example namespace: default annotations: CCE.com/IAM: 'true' roleRef: kind: Role name: role-example apiGroup: rbac.authorization.k8s.io subjects: - kind: User name: 0c97ac3cb280f4d91fa7c0096739e1f8 # IAM用户ID apiGroup: rbac.authorization.k8s.io
这里的subjects就是将Role与IAM用户绑定起来,从而使得IAM用户获取role-example这个Role里面定义的权限,如下图所示。
subjects下用户的类型还可以是用户组,这样配置可以对用户组下所有用户生效。
subjects:
- kind: Group
name: 0c96fad22880f32a3f84c009862af6f7 # 用户组ID
apiGroup: rbac.authorization.k8s.io
配置验证
使用IAM用户user-example连接集群,查看Pod,发现可以查看。
# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-658dff48ff-7rkph 1/1 Running 0 4d9h nginx-658dff48ff-njdhj 1/1 Running 0 4d9h # kubectl get pod nginx-658dff48ff-7rkph NAME READY STATUS RESTARTS AGE nginx-658dff48ff-7rkph 1/1 Running 0 4d9h
然后查看Deployment和Service,发现没有权限;再查询kube-system命名空间下的Pod,发现也没有权限。这就说明IAM用户user-example仅拥有defaul这个命名空间下GET和LIST Pod的权限,与前面定义的没有偏差。
# kubectl get deploy Error from server (Forbidden): deployments.apps is forbidden: User "0c97ac3cb280f4d91fa7c0096739e1f8" cannot list resource "deployments" in API group "apps" in the namespace "default" # kubectl get svc Error from server (Forbidden): services is forbidden: User "0c97ac3cb280f4d91fa7c0096739e1f8" cannot list resource "services" in API group "" in the namespace "default" # kubectl get pod --namespace=kube-system Error from server (Forbidden): pods is forbidden: User "0c97ac3cb280f4d91fa7c0096739e1f8" cannot list resource "pods" in API group "" in the namespace "kube-system"