Kubernetes 發展好快,在我寫這篇總結的同時, 1.9.0 1.8.4 1.6
版本已經在昨日(2017.12.16)正式釋出,而上次在正式環境中部署已經是半年前了,我花了點時間将叢集更新到了
版本,其中變化最明顯的就是權限了,已經可以用上 RBAC 了,而我也在發現報錯的時候才意識到需要将以前 k8s 的基礎應用也全部加上了權限(當然了,
其實就開始有了)。
目前,k8s 中一共有 4 種權限模式:
- Node: 一種特殊目的的授權模式,主要用來讓 kubelets 遵從 node 的編排規則,實際上是 RBAC 的一部分,相當于隻定義了 node 這個角色以及它的權限;
- ABAC: Attribute-based access control;
- RBAC: Role-based access control;
- Webhook: 以 HTTP Callback 的方式,利用外部授權接口來進行權限控制;
對于大部分人來說,RBAC 就能起到很好的權限控制效果了(k8s 的 RBAC 實作是一個非常優秀的樣例,詳細研究下它的設計将對你未來對于其它系統的權限設計會有很好的啟發作用,比如你們公司管理背景權限設計)。下面将詳細介紹下。
基礎
樣例
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: example
rules:
- apiGroups: [""] #"" 說明是 core API group
resources: ["pods"] # 可用來操作的對象
verbs: # 可以進行的操作
- get
- list
- create
- update
- patch
- watch
- proxy
- redirect
- delete
- deletecollection
Role & ClusterRole
兩種角色,很好區分,role 限定于單個 namespace,而 ClusterRole 則是沒有這個限制的,主要是用來給一些基礎服務用的。
RoleBinding & ClusterRoleBinding
這個就相當于具體的權限授權清單了,所有的 Role 會與具體的 ServiceAccount、User 以及 Group 等綁定,而他們的差別就是分别對應 Role & ClusterRole。
Aggregated ClusterRoles
這是 1.9 引入的新功能,簡而言之,你可以利用标簽來組合一些列的 ClusterRoles,具體樣例如下:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
# 所有帶有 rbac.example.com/aggregate-to-monitoring: "true" 這個标簽的都會被組合
# 然後自動生成 rules
rules: []
實踐:生成使用者賬戶
在官方文檔中,也沒有介紹應該如何生成具體的 User 賬戶(在
設計文檔中,提到過 userAccount,但目前還沒有實作),但其實生成賬戶很簡單,因為 User 賬戶是根據 SSL 證書生成的,你隻要根據 k8s 的 ca 證書來生成對應的賬戶即可。
比如目前我需要生成一個 xizhibei 的賬戶:
# 在目前目錄下添加目錄,用來存放證書
mkdir certs
# 設定一些變量
KUBE_URL=https://k8s-master01.zs:6443
CLUSTER=k8s.cluster
CRT_DAYS=365
USER_NAME=xizhibei
# CA 證書可以在 master node 上找到
# 一般就在 /etc/kubernetes/ssl 或者 /etc/kubernetes/pki 裡面
CA_CRT_PATH=/etc/kubernetes/ssl/ca.pem
CA_KEY_PATH=/etc/kubernetes/ssl/ca-key.pem
# 生成私有密鑰
openssl genrsa -out certs/$USER_NAME.key 2048
# 用私鑰生成證書,CN 表示使用者名,O 表示使用者組
openssl req -new -key certs/$USER_NAME.key -out certs/$USER_NAME.csr \
-subj "/CN=$USER_NAME/O=example"
# 然後用 CA 證書來給剛才生成的證書來簽名
# 在這個例子中,我們給 xizhibei 這個賬戶簽發了一張有效期為一年的證書
openssl x509 -req -in certs/$USER_NAME.csr -CA $CA_CRT_PATH -CAkey $CA_KEY_PATH \
-CAcreateserial -out certs/$USER_NAME.crt -days $CRT_DAYS
好了,這樣你就生成了一個賬戶,接下來,需要設定下 kubectl 的配置:
# 存放 kubectl config 的檔案
export KUBECONFIG=/root/k8s-$USER_NAME.conf
# 設定 cluster
kubectl config set-cluster $CLUSTER --server="$KUBE_URL" \
--certificate-authority="$CA_CRT_PATH" --embed-certs=true
# 設定私鑰以及已簽名證書
kubectl config set-credentials $USER_NAME --client-certificate=certs/$USER_NAME.crt \
--client-key=certs/$USER_NAME.key --embed-certs=true
# 設定 context
kubectl config set-context $USER_NAME-context --cluster=$CLUSTER --user=$USER_NAME
kubectl config use-context $USER_NAME-context
你可以使用
kubectl get pods -n example --kubeconfig /root/k8s-xizhibei.conf
來确認是否可以可用,不出所料的話,你會被告知沒有權限,因為現在隻是生成了一個賬戶,你還不可以操作具體的資源。
Error from server (Forbidden): pods is forbidden: User “xizhibei” cannot list pods in the namespace “example”
下面,就需要你配置具體的 Role 以及 RoleBinding 來授權你剛剛生成的賬戶,比如我想給剛剛生成的賬戶授權隻能對部署進行操作:
# new-user.yaml
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: example
name: deployment-manager
rules:
- apiGroups: ["","extensions","apps"]
resources: ["deployments", "replicasets", "pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: deployment-manager-binding
namespace: example
subjects:
- kind: User
name: [email protected]
apiGroup: ""
roleRef:
kind: ClusterRole
name: admin
apiGroup: ""
然後
kubectl create -f ./new-user.yaml
(注意,你得使用管理者賬戶,而不是剛剛生成的使用者賬戶)。
接下來,這個使用者就能進行操作了,使用
kubectl get pods -n example --kubeconfig /root/k8s-xizhibei.conf
,你就能看到 pods 的清單了。
P.S.
似乎又寫了一篇水文,通篇還是以介紹與總結為主,沒有具體的思考内容在裡面。但是回顧起來,你會發現這對于我們設計管理背景的權限還是挺有啟發的。比如目前管理背景中有訂單,使用者以及付費記錄三種資源,那麼對于管理者賬戶來說,我們就可以設計如下的 RBAC 模型:
Account:
- name, type: string
- roles, type: [string] # 這裡就相當于 rolebinding 了
Role:
- name
- rules
- name, type: string
- verbs, type: [string]
- resources, type: [string]
Resource: enum(order, user, payment)
Verb: enum(get, list, update, create, delete, deleteCollection)
對應的其中一條完整記錄:
Account:
- xizibei
- ['edit', 'view']
Role:
- 'view'
- ['get', 'list']
- ['order', 'user', 'payment']
本文轉自掘金-
kubernetes 中的權限管理