天天看點

Kubernetes叢集添加使用者

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指定

    --client-ca-file=xxx

    選項啟用,API Server通過此ca檔案來驗證API請求攜帶的用戶端證書的有效性,一旦驗證成功,API Server就會将用戶端證書Subject裡的CN屬性作為此次請求的使用者名。
  • 靜态token檔案 通過指定

    --token-auth-file=SOMEFILE

    選項來啟用bearer token驗證方式,引用的檔案是一個包含了token,使用者名,使用者ID 的csv檔案 請求時,帶

    上Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269

    頭資訊即可通過bearer token驗證
  • 靜态密碼檔案 通過指定

    --basic-auth-file=SOMEFILE

    選項啟用密碼驗證,類似的,引用的檔案時一個包含 密碼,使用者名,使用者ID 的csv檔案 請求時需要将Authorization頭設定為

    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: ...