kubernetes RBAC實戰
環境準備
先用 kubeadm 安裝好 kubernetes 集群,包地址(https://market.aliyun.com/products/56014009/cmxz022571.html#sku=yuncode1657100000) 好用又方便,服務周到,童叟無欺。
本文目的:讓名為 devuser 的用戶只能有許可權訪問特定 namespace 下的pod。
命令行 kubectl 訪問
安裝 cfssl
此工具生成證書非常方便, pem 證書與 crt 證書,編碼一致可直接使用
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64nchmod +x cfssl_linux-amd64nmv cfssl_linux-amd64 /bin/cfsslnnwget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64nchmod +x cfssljson_linux-amd64nmv cfssljson_linux-amd64 /bin/cfssljsonnnwget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64nchmod +x cfssl-certinfo_linux-amd64nmv cfssl-certinfo_linux-amd64 /bin/cfssl-certinfo n
簽發客戶端證書
根據查證書與秘鑰簽發用戶證書
根證書已經在 /etc/kubernetes/pki 目錄下了
[root@master1 ~]# ls /etc/kubernetes/pki/napiserver.crt ca-config.json devuser-csr.json front-proxy-ca.key sa.pubnapiserver.key ca.crt devuser-key.pem front-proxy-client.crtnapiserver-kubelet-client.crt ca.key devuser.pem front-proxy-client.keynapiserver-kubelet-client.key devuser.csr front-proxy-ca.crt sa.keyn
注意以下幾個文件: ca.crt ca.key ca-config.json devuser-csr.json
創建 ca-config.json 文件
cat > ca-config.json <<EOFn{n "signing": {n "default": {n "expiry": "87600h"n },n "profiles": {n "kubernetes": {n "usages": [n "signing",n "key encipherment",n "server auth",n "client auth"n ],n "expiry": "87600h"n }n }n }n}nEOF n
創建 devuser-csr.json 文件:
k8s 的用戶名就是從 CN 上獲取的。 組是從 O 上獲取的。這個用戶或者組用於後面的角色綁定使用
cat > devuser-csr.json <<EOFn{n "CN": "devuser",n "hosts": [],n "key": {n "algo": "rsa",n "size": 2048n },n "names": [n {n "C": "CN",n "ST": "BeiJing",n "L": "BeiJing",n "O": "k8s",n "OU": "System"n }n ]n}nEOF n
生成 user 的證書:
$ cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetnes devuser-csr.json | cfssljson -bare devuser n
就會生成下面的文件:
devuser.csr devuser-key.pem devuser.pem n
校驗證書
# cfssl-certinfo -cert kubernetes.pem n
生成 config 文件
kubeadm 已經生成了 admin.conf,我們可以直接利用這個文件,省的自己再去配置集群參數
$ cp /etc/kubernetes/admin.conf devuser.kubeconfig
設置客戶端認證參數:
kubectl config set-credentials devuser n--client-certificate=/etc/kubernetes/ssl/devuser.pem n--client-key=/etc/kubernetes/ssl/devuser-key.pem n--embed-certs=true n--kubeconfig=devuser.kubeconfig n
設置上下文參數:
kubectl config set-context kubernetes n--cluster=kubernetes n--user=devuser n--namespace=kube-system n--kubeconfig=devuser.kubeconfig n
設置莫認上下文:
kubectl config use-context kubernetes --kubeconfig=devuser.kubeconfign
以上執行一個步驟就可以看一下 devuser.kubeconfig 的變化。裡面最主要的三個東西
- cluster: 集群信息,包含集群地址與公鑰
- user: 用戶信息,客戶端證書與私鑰,正真的信息是從證書里讀取出來的,人能看到的只是給人看的。
- context: 維護一個三元組, namespace cluster 與 user
創建角色
創建一個叫 pod-reader 的角色
[root@master1 ~]# cat pod-reader.yamlnkind: RolenapiVersion: rbac.authorization.k8s.io/v1nmetadata:n namespace: kube-systemn name: pod-readernrules:n- apiGroups: [""] # "" indicates the core API groupn resources: ["pods"]n verbs: ["get", "watch", "list"]nkubectl create -f pod-reader.yaml n
綁定用戶
創建一個角色綁定,把 pod-reader 角色綁定到 devuser 上
[root@master1 ~]# cat devuser-role-bind.yamlnkind: RoleBindingnapiVersion: rbac.authorization.k8s.io/v1nmetadata:n name: read-podsn namespace: kube-systemnsubjects:n- kind: Usern name: devuser # 目標用戶n apiGroup: rbac.authorization.k8s.ionroleRef:n kind: Rolen name: pod-reader # 角色信息n apiGroup: rbac.authorization.k8s.ion
kubectl create -f devuser-role-bind.yaml n
使用新的 config 文件
$ rm .kube/config && cp devuser.kubeconfig .kube/config n
最終的效果就是:已經沒有別的 namespace 的許可權了,也不能訪問 node 信息了
t@master1 ~]# kubectl get nodenError from server (Forbidden): nodes is forbidden: User "devuser" cannot list nodesn at the cluster scopen
[root@master1 ~]# kubectl get pod -n kube-systemnNAME READY STATUS RESTARTS AGEncalico-kube-controllers-55449f8d88-74x8f 1/1 Running 0 8dncalico-node-clpqr 2/2 Running 0 8dnkube-apiserver-master1 1/1 Running 2 8dnkube-controller-manager-master1 1/1 Running 1 8dnkube-dns-545bc4bfd4-p6trj 3/3 Running 0 8dnkube-proxy-tln54 1/1 Running 0 8dnkube-scheduler-master1 1/1 Running 1 8dnn[root@master1 ~]# kubectl get pod -n defaultnError from server (Forbidden): pods is forbidden: User "devuser" cannot list pods in the namespace "default": role.rbac.authorization.k8s.io "pod-reader" not found n
dashboard 訪問
service account 原理
k8s 裡面有兩種用戶,一種是 User,一種就是 service account,User 給人用的,service account 給進程用的,讓進程有相關的許可權。
如 dasboard 就是一個進程,我們就可以創建一個 service account 給它,讓它去訪問 k8s。
我們看一下是如何把 admin 許可權賦給 dashboard 的:
╰─? cat dashboard-admin.yamlnapiVersion: rbac.authorization.k8s.io/v1beta1nkind: ClusterRoleBindingnmetadata:n name: kubernetes-dashboardn labels:n k8s-app: kubernetes-dashboardnroleRef:n apiGroup: rbac.authorization.k8s.ion kind: ClusterRolen name: cluster-adminnsubjects:n- kind: ServiceAccountn name: kubernetes-dashboardn namespace: kube-system n
把 kubernetes-dashboard 這個 ServiceAccount 綁定到 cluster-admin 這個 ClusterRole 上,這個 cluster role 非常牛逼,啥許可權都有
[root@master1 ~]# kubectl describe clusterrole cluster-admin -n kube-systemnName: cluster-adminnLabels: kubernetes.io/bootstrapping=rbac-defaultsnAnnotations: rbac.authorization.kubernetes.io/autoupdate=truenPolicyRule:n Resources Non-Resource URLs Resource Names Verbsn --------- ----------------- -------------- -----n [*] [] [*]n *.* [] [] [*] n
而創建 dashboard 時創建了這個 service account:
apiVersion: v1nkind: ServiceAccountnmetadata:n labels:n k8s-app: kubernetes-dashboardn name: kubernetes-dashboardn namespace: kube-system n
然後 deployment 里指定 service account
volumes:n - name: kubernetes-dashboard-certsn secret:n secretName: kubernetes-dashboard-certsn - name: tmp-volumen emptyDir: {}n serviceAccountName: kubernetes-dashboard n
更安全的做法
[root@master1 ~]# cat admin-token.yamlnkind: ClusterRoleBindingnapiVersion: rbac.authorization.k8s.io/v1beta1nmetadata:n name: adminn annotations:n rbac.authorization.kubernetes.io/autoupdate: "true"nroleRef:n kind: ClusterRolen name: cluster-adminn apiGroup: rbac.authorization.k8s.ionsubjects:n- kind: ServiceAccountn name: adminn namespace: kube-systemn---napiVersion: v1nkind: ServiceAccountnmetadata:n name: adminn namespace: kube-systemn labels:n kubernetes.io/cluster-service: "true"n addonmanager.kubernetes.io/mode: Reconcilen[root@master1 ~]# kubectl get secret -n kube-system|grep adminnadmin-token-7rdhf kubernetes.io/service-account-token 3 14mn[root@master1 ~]# kubectl describe secret admin-token-7rdhf -n kube-systemnName: admin-token-7rdhfnNamespace: kube-systemnLabels: <none>nAnnotations: kubernetes.io/service-account.name=adminn kubernetes.io/service-account.uid=affe82d4-d10b-11e7-ad03-00163e01d684nnType: kubernetes.io/service-account-tokennnDatan====nca.crt: 1025 bytesnnamespace: 11 bytesntoken: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi03cmRoZiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImFmZmU4MmQ0LWQxMGItMTFlNy1hZDAzLTAwMTYzZTAxZDY4NCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.jSfQhFsY7V0ZmfqxM8lM_UUOoUhI86axDSeyVVtldSUY-BeP2Nw4q-ooKGJTBBsrOWvMiQePcQxJTKR1K4EIfnA2FOnVm4IjMa40pr7-oRVY37YnR_1LMalG9vrWmqFiqIsKe9hjkoFDuCaP7UIuv16RsV7hRlL4IToqmJMyJ1xj2qb1oW4P1pdaRr4Pw02XBz9yBpD1fs-lbwheu1UKcEnbHS_0S3zlmAgCrpwDFl2UYOmgUKQVpJhX4wBRRQbwo1Sn4rEFVI1NIa9l_lM7Mf6YEquLHRu3BCZTdu9YfY9pevQz4OfHE0NOvDIqmGRL8Z9kPADAXbljWzcD1m1xCQn用此 token 在界面上登錄即可n
作者:fanux
原文鏈接:https://segmentfault.com/a/1190000012151075
小月兒
推薦閱讀:
※一周IT博文精選TOP10(第十期)
※梁勝:Kubernetes 已成為新的基礎設施標準
※容器編排之Kubernetes安裝與配置
※Azure Managed Kubernetes (AKS) 簡介
※k8s學習筆記之持久化存儲
TAG:Kubernetes |