Kubernetes中的使用者
K8S中有兩種使用者(User)——服務賬号(ServiceAccount)和普通意義上的使用者(User) ServiceAccount是由K8S管理的,而User通常是在外部管理,K8S不存儲使用者清單——也就是說,添加/編輯/删除使用者都是在外部進行,無需與K8S API互動,雖然K8S并不管理使用者,但是在K8S接收API請求時,是可以認知到送出請求的使用者的,實際上,所有對K8S的API請求都需要綁定身份資訊(User或者ServiceAccount),這意味着,可以為User配置K8S叢集中的請求權限。
ServiceAccount是K8S内部資源,而User是獨立于K8S之外的。從它們的本質可以看出:
- User通常是人來使用,而ServiceAccount是某個服務/資源/程式使用的。
- User獨立在K8S之外,也就是說User是可以作用于全局的,在任何命名空間都可被認知,并且需要在全局唯一。
- ServiceAccount作為K8S内部的某種資源,是存在于某個命名空間之中的,在不同命名空間中的同名ServiceAccount被認為是不同的資源。
- K8S不會管理User,是以User的建立/編輯/登出等,需要依賴外部的管理機制。
- 這裡說的添加使用者指的是普通意義上的使用者,即存在于叢集外的使用者,為k8s的使用者。
- 實際上叫做添加使用者也不準确,使用者早已存在,這裡所做的隻是使K8S能夠認知此使用者,并且控制此使用者在叢集内的權限。
使用者驗證
盡管K8S認知使用者靠的隻是使用者的名字,但是隻需要一個名字就能請求K8S的API顯然是不合理的,是以依然需要驗證此使用者的身份,在K8S中,有以下幾種驗證方式:
- X509用戶端證書 用戶端證書驗證通過為API Server指定
選項啟用,API Server通過此ca檔案來驗證API請求攜帶的用戶端證書的有效性,一旦驗證成功,API Server就會将用戶端證書Subject裡的CN屬性作為此次請求的使用者名。--client-ca-file=xxx
- 靜态token檔案 通過指定
選項來啟用bearer token驗證方式,引用的檔案是一個包含了token,使用者名,使用者ID 的csv檔案 請求時,帶--token-auth-file=SOMEFILE
頭資訊即可通過bearer token驗證上Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269
- 靜态密碼檔案 通過指定
選項啟用密碼驗證,類似的,引用的檔案時一個包含 密碼,使用者名,使用者ID 的csv檔案 請求時需要将Authorization頭設定為--basic-auth-file=SOMEFILE
。Basic BASE64ENCODED(USER:PASSWORD)
這裡隻介紹用戶端驗證。
為使用者生成證書
首先需要為此使用者建立一個私鑰:
openssl genrsa -out tom.key 2048
接着用此私鑰建立一個csr(證書簽名請求)檔案,其中我們需要在subject裡帶上使用者資訊(CN為使用者名,O為使用者組),其中/O參數可以出現多次,即可以有多個使用者組:
openssl req -new -key tom.key -out tom.csr -subj "/CN=tom/O=MGM"
找到K8S叢集(API Server)的CA憑證檔案,其位置取決于安裝叢集的方式,通常會在/etc/kubernetes/pki/路徑下,會有兩個檔案,一個是CA憑證(ca.crt),一個是CA私鑰(ca.key)。通過叢集的CA憑證和之前建立的csr檔案,來為使用者頒發證書:
openssl x509 -req -in tom.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out tom.crt -days 365
-CA和-CAkey參數需要指定叢集CA憑證所在位置,-days參數指定此證書的過期時間,這裡為365天。
最後将證書(tom.crt)和私鑰(tom.key)儲存起來,這兩個檔案将被用來驗證API請求。
為使用者添加基于角色的通路控制(RBAC)
首先創造一個角色,該角色在acp命名空間下擁有所有權限:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: acp
name: acp-admin
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
将角色和使用者tom綁定:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: acp-admin-binding
namespace: acp
subjects:
- kind: User
name: tom
apiGroup: ""
roleRef:
kind: Role
name: acp-admin
apiGroup: ""
如yaml中所示,RoleBinding資源建立了一個 Role-User 之間的關系,roleRef節點指定此RoleBinding所引用的角色,subjects節點指定了此RoleBinding的受體,可以是User,也可以是前面說過的ServiceAccount,在這裡隻包含了名為 tom 的使用者。參考:
https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding為kubectl配置使用者
現在我們想要通過kubectl以tom的身份來操作叢集,需要将tom的認證資訊添加進kubectl的配置,即~/.kube/config中,通過以下指令将使用者tom的驗證資訊添加進kubectl的配置:
kubectl config set-credentials tom --client-certificate=tom.crt --client-key=tom.key
添加完成後在~/.kube/config可以看到新增了:
users:
- name: tom
user:
client-certificate: /root/k8s/tom.crt
client-key: /root/k8s/tom.key
用下面指令添加一個context配置:
kubectl config set-context tom --cluster=kubernetes --namespace=acp --user=tom
contexts:
- context:
cluster: kubernetes
namespace: acp
user: tom
name: tom
通過
kubectl config get-contexts
指令也可以查到目前kubectl所配置的context資訊:
[root@master1 k8s]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
tom kubernetes tom acp
使用剛剛新建立的context:
#方式一:切換context
kubectl config use-context tom
#方式二:使用該context
kubectl --context=tom <指令>
在叢集外部使用
将tom.crt/tom.key的内容用BASE64編碼:
cat tom.crt | base64 --wrap=0
cat tom.key | base64 --wrap=0
将擷取的編碼後的文本複制進~/.kube/config檔案中:
contexts:
- context:
cluster: kubernetes
namespace: acp
user: tom
name: tom
users:
- name: tom
user:
client-certificate-data: ...
client-key-data: ...