前面我們在kubernetes dashboard 升級之路一文中成功的將Dashboard
升級到最新版本了,增加了身份認證功能,之前為了方便增加了一個admin
用戶,然后授予了cluster-admin
的角色綁定,而該角色綁定是系統內置的一個超級管理員權限,也就是用該用戶的token
登錄Dashboard
后會很強勢,什么權限都有,想干嘛干嘛,這樣的操作顯然是非常危險的。接下來我們來為一個新的用戶添加訪問權限控制。
Role
Role
表示是一組規則權限,只能累加,Role
可以定義在一個namespace
中,只能用於授予對單個命名空間中的資源訪問的權限。比如我們新建一個對默認命名空間中Pods
具有訪問權限的角色:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"]
ClusterRole
ClusterRole
具有與Role
相同的權限角色控制能力,不同的是ClusterRole
是集群級別的,可以用於:
- 集群級別的資源控制(例如 node 訪問權限)
- 非資源型 endpoints(例如 /healthz 訪問)
- 所有命名空間資源控制(例如 pods)
比如我們要創建一個授權某個特定命名空間或全部命名空間(取決於綁定方式)訪問secrets的集群角色:
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: # "namespace" omitted since ClusterRoles are not namespaced name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"]
RoleBinding和ClusterRoleBinding
RoloBinding
可以將角色中定義的權限授予用戶或用戶組,RoleBinding
包含一組權限列表(subjects
),權限列表中包含有不同形式的待授予權限資源類型(users、groups、service accounts),RoleBinding
適用於某個命名空間內授權,而 ClusterRoleBinding
適用於集群范圍內的授權。
比如我們將默認命名空間的pod-reader
角色授予用戶jane,這樣以后該用戶在默認命名空間中將具有pod-reader
的權限:
# This role binding allows "jane" to read pods in the "default" namespace. kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: read-pods namespace: default subjects: - kind: User name: jane apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
RoleBinding
同樣可以引用ClusterRole
來對當前 namespace 內用戶、用戶組或 ServiceAccount 進行授權,這種操作允許集群管理員在整個集群內定義一些通用的 ClusterRole,然后在不同的 namespace 中使用 RoleBinding 來引用
例如,以下 RoleBinding 引用了一個 ClusterRole,這個 ClusterRole 具有整個集群內對 secrets 的訪問權限;但是其授權用戶 dave 只能訪問 development 空間中的 secrets(因為 RoleBinding 定義在 development 命名空間)
# This role binding allows "dave" to read secrets in the "development" namespace. kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: read-secrets namespace: development # This only grants permissions within the "development" namespace. subjects: - kind: User name: dave apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: secret-reader apiGroup: rbac.authorization.k8s.io
最后,使用 ClusterRoleBinding 可以對整個集群中的所有命名空間資源權限進行授權;以下 ClusterRoleBinding 樣例展示了授權 manager 組內所有用戶在全部命名空間中對 secrets 進行訪問
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace. kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: read-secrets-global subjects: - kind: Group name: manager apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: secret-reader apiGroup: rbac.authorization.k8s.io
限制dashboard 用戶權限
有了上面的理論基礎,我們就可以來新建一個用戶,為該用戶指定特定的訪問權限了,比如我們的需求是:
- 新增一個新的用戶
cnych
- 該用戶只能對命名空間
kube-system
下面的pods
和deployments
進行管理
第一步新建一個ServiceAccount
:
$ kubectl create sa cnych -n kube-system
然后我們新建一個角色role-cnych:(role.yaml)
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: kube-system name: role-cnych rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] - apiGroups: ["extensions", "apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
注意上面的rules
規則:管理pods
和deployments
的權限。
然后我們創建一個角色綁定,將上面的角色role-cnych
綁定到cnych的ServiceAccount
上:(role-bind.yaml)
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: role-bind-cnych namespace: kube-system subjects: - kind: ServiceAccount name: cnych namespace: kube-system roleRef: kind: Role name: role-cnych apiGroup: rbac.authorization.k8s.io
分別執行上面兩個yaml
文件:
$ kubect create -f role.yaml $ kubect create -f role-bind.yaml
接下來該怎么做?和前面一樣的,我們只需要拿到cnych
這個ServiceAccount
的token
就可以登錄Dashboard
了:
$ kubectl get secret -n kube-system |grep cnych cnych-token-nxgqx kubernetes.io/service-account-token 3 47m $ kubectl get secret cnych-token-nxgqx -o jsonpath={.data.token} -n kube-system |base64 -d # 會生成一串很長的base64后的字符串
然后在dashboard
登錄頁面上直接使用上面得到的token
字符串即可登錄,登錄過后能看到下面的頁面。
這是因為當前的這個token
對應的用戶沒有被授予訪問默認命名空間的權限,所以會出現這種提示,然后我們訪問kube-system
這個命名空間試下看看(https:///#!/pod?namespace=kube-system):
我們可以看到可以訪問pod
列表了,但是也會有一些其他額外的提示:events is forbidden: User “system:serviceaccount:kube-system:cnych” cannot list events in the namespace “kube-system”,這是因為當前登錄用只被授權了訪問pod
和deployment
的權限,同樣的,訪問下deployment
看看可以了嗎?
同樣的,你可以根據自己的需求來對訪問用戶的權限進行限制,可以自己通過Role
定義更加細粒度的權限,也可以使用系統內置的一些權限……