Kubernetes認證入門指南

RancherLabs發表於2021-06-03

Kubernetes用來執行安全訪問和許可權的步驟有3個——認證(Authentication)、授權(Authorization)和准入(Admission)。在本文中,我們先開始瞭解認證(Authentication)。

在認證中第一個需要考慮的是身份認證(Identity)。

身份認證簡介

Kubernetes假設“user”是在Kubernetes之外管理的。在生產環境中,可以採用LDAP(輕量級目錄訪問協議)、SSO(單點登入)、Kerberos或SAML(安全斷言置標語言)進行身份認證管理。在開發或測試環境中,其他的認證策略也有可能會被使用到。

在Kubernetes中沒有表達普通使用者的物件,因此不能通過API將普通使用者新增到叢集中。

認證策略概覽

Kubernetes通過認證外掛使用認證代理、bearer token、客戶端證書或HTTP基本授權來認證API請求。當向API server發出HTTP請求時,外掛會嘗試將以下屬性與請求關聯起來:

  • Username:識別終端使用者的字串
  • UID:識別終端使用者的字串,並試圖比username格式更為一致,同時每個UID都是獨特的。
  • Groups:一組字串,將使用者與一組常見的分組使用者關聯起來
  • Extra fields:字串的對映,儲存著授權者認為可能有用的額外資訊。

所有這些值對認證系統來說都是不透明的,只有在authorizer對其進行解釋時才有意義。Kubernetes管理員通常會啟用多種認證方法。所需的兩種最基本的方法是——服務賬戶的service account token再加上至少一種其他的使用者認證方法。

X509客戶端證書

  • 從Kubernetes 1.4開始,客戶端證書可以使用證書組織欄位來表明使用者的組成員資格。
  • 要讓一個使用者擁有多個組成員資格,需要在證書中包含多個組織欄位。
  • 通過向API server傳遞 --client-ca-file=選項來啟用客戶端證書認證。
  • 引用的檔案必須包含一個或多個證書頒發機構,用於驗證提交給API server的客戶證書。
  • 如果出示客戶端證書並進行驗證,則使用主體的通用名作為請求的使用者名稱。

例如,使用openssl命令列工具來生成證書籤名請求:

openssl req -new -key <pem_file>.pem -out <out-csr-file>.pem -subj "/CN=admin/O=prod/O=dev/O=uat"

這將為使用者名稱admin建立一個CSR(證書籤名請求),該使用者名稱屬於以下3個組:prod、dev和uat。

靜態Token檔案

當在命令列中給出--token-auth-file=選項時,API Server會從檔案中讀取bearer token。如今,token無限期存在,如果不重啟API Server,就無法更改token列表。Token檔案是一個csv檔案,至少有3列:token、使用者名稱、user uid,後面可能還會有組名(這是可選的)。

token, user, uid,"prod,dev,uat"

請注意:如果你有超過1個組,該列必須使用雙引號。

在請求中放入一個bearer token

當使用來自HTTP客戶端的bearer token認證時,API server期望授權請求頭的值為Bearer 。bearer token必須是一個字元序列,可以只需使用HTTP的編碼和引用功能就可以將其放在HTTP請求頭的值中。例如,如果Bearer Token是ad644f3f-bfch-295b-75bk-h9g8ngf36hb6,那麼它將出現在HTTP請求頭中,如下所示:

Authorization: Bearer ad644f3f-bfch-295b-75bk-h9g8ngf36hb6

靜態密碼檔案

通過向API server傳遞--basic-auth-file=選項來啟用基本認證。現在,基本的認證憑證將無限期地持續下去,而且如果不重新啟動 API server,就無法更改密碼。

基本的 auth 檔案是一個 csv 檔案,至少有 3 列:密碼、使用者名稱、使用者 ID。在Kubernetes 1.6及以後的版本中,你可以指定一個可選的第4列,包含逗號分隔的組名。如果你有多個組,你必須用雙引號(")括住第4列的值。

password,user,uid,"group1,group2,group3"

當使用來自HTTP客戶端的基本認證時,API server期望Authorizationheader的值為:

Basic BASE64ENCODED(USER:PASSWORD)

服務賬戶Token

服務賬戶是一個自動啟用的身份認證器,它使用簽名的bearer token來驗證請求。該外掛需要2個可選的標誌:

--service-account-key-file

一個包含PEM編碼金鑰的檔案,用於簽署bearer token。如果沒有指定,將使用API server的TLS金鑰。

--service-account-lookip

如果啟用了,從API sever上刪除的token將被撤銷。

服務賬戶通常由API server自動建立,並通過ServiceAccount 准入控制器與叢集中執行的Pod相關聯。

Bearer Token會被掛載到眾所周知的位置的Pod中,並允許叢集內程式與API Server對話。賬戶可以使用PodSpec的serviceAccountName欄位與Pod顯式關聯。

注意,serviceAccountName通常會被省略,因為這是自動完成的。

練習實踐:使用ServiceAccount Token

使用以下命令可以建立ServiceAccount:

kubectl create serviceaccount testuser

建立的金鑰包含API server的公共CA和簽名的JSON web Token(JWT)。以下命令可以顯示出揭示相關金鑰的yaml:

kubectl get serviceaccount testuser -o yaml

以下命令可以顯示可用Token:

kubectl get secrets

要獲得編碼的token資料,請輸入:

kubectl get secret testuser-token-mgtnp -o yaml

你可以將編碼後的token資料複製並貼上到https://jwt.io/ 以檢視有效載荷。使用你選擇的編輯器輸入以下yaml檔案(test-pod.yaml),以執行一個pod:

apiVersion: v1 
kind: pod 
metadata:  
  name: test-pod 
spec:  
  serviceAccountName: testuser  
  container:  
  - name: alpine:3.7    
    command:    
    - "sh"    
    - "-c"    
    - "sleep 100"

然後使用以下命令啟動pod:

kubectl apply -f test-pod.yaml

使用describe可以檢視更詳細的內容:

kubectl describe test-pod

現在,我們有一個正在執行的pod,名為test-pod,讓我們進入互動模式並執行一個shell:

kubectl exec -it test-pod -- sh

如果你想在docker容器內執行shell,所使用的命令與docker命令類似。這時,我們將會收到一個提示,然後進入Alpine Linux系統,該系統是在pod中的一個容器內執行的。為了開啟被複制到容器中的token,你需要執行以下命令:

cat /var/run/sercrets/kubernetes.io/serviceaccount/token

複製輸出並將該token貼上在https://jwt.io/上Encoded部分。在另一邊你會得到token的型別、名稱空間、ServiceAccount名稱、金鑰名稱等。

這幾乎以一種十分直觀的方式向你說明了Kubernetes如何在token中進行身份驗證有效載荷。

作者:
Sudip Sengupta
連結:
https://dzone.com/articles/kubernetes-authentication

相關文章