Kubernetes認證入門指南
- 2021 年 6 月 3 日
- 筆記
- Kubernetes
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=
token, user, uid,"prod,dev,uat"
請注意:如果你有超過1個組,該列必須使用雙引號。
在請求中放入一個bearer token
當使用來自HTTP客戶端的bearer token認證時,API server期望授權請求頭的值為Bearer
Authorization: Bearer ad644f3f-bfch-295b-75bk-h9g8ngf36hb6
靜態密碼文件
通過向API server傳遞–basic-auth-file=
基本的 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數據複製並粘貼到//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粘貼在//jwt.io/上Encoded部分。在另一邊你會得到token的類型、命名空間、ServiceAccount名稱、密鑰名稱等。
這幾乎以一種十分直觀的方式向你說明了Kubernetes如何在token中進行身份驗證有效載荷。
作者:
Sudip Sengupta
鏈接:
//dzone.com/articles/kubernetes-authentication