結束完了 AutoScaling
主題後,隨即而來的是本系列的最後一個主題 Security
,這個議題可以說在 DevOps 中是特別耐人尋味的,有趣的點是他不一定是工作中的必備技能但卻極為重要,畢竟不是每個人公司都有數十人等級以上的團隊、或同時管理維護大大小小不同產品的工作環境,更多的是三到五人的小開發團隊以及一人維護的專案的情況,這時候權限管理相關的優先級自然被排到比較後面。
這時我們從另一個角度來看,人人想進的理想好公司通常除了好的文化跟環境之外,也有很大的概率是一間人數不小規模的企業甚至是跨國集團,如果我們在職業生涯追求的是這類型的公司,那又有什麼理由不去理解為自己加分的技能呢?而我想在資安就是一個不論是否為維運人員都很適合熟悉的一環。
當我們試著不管藉由指令或是其他方式與我們的 Kubernetes
集群互動時,一定都會經過該集群管理所有物件資源的的入口 kube-apiserver
,這時就可以體現 kube-apiserver
身份驗證的重要性,他能替我們檢查所有進入的請求,包括 Authentication(身份驗證)、Authorization(授權)和 Admission Control(准入控制)。
Kubernetes API 請求從發起到持久化到ETCD資料庫中的過程如下:
接下來我們使用 Kubernetes Context 實戰我們在工作中會面對到的用戶管理認證(Authentication) 問題。
在 Kubernetes
中,一個 Context 就像是一個方便好讀在客戶端紀錄著你與集群要如何溝通的 Alias
,假如我切換到某個群集後,那我在 kubectl 送出的每個指令都會指向該 Context
所設定的 cluster
、namespace
、user
執行操作。很重要的一點是 kube-apiserver
是看不懂所謂的 Context
的,而是在請求送出之前幫我們在客戶端把相關設定轉為參數送出,所以才呼應了前面提到的 Alias
概念。
先來看看 kubeconfig 中紀錄的 Context 到底長什麼樣吧:
kubectl config view
---------
apiVersion: v1ig view
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://kubernetes.docker.internal:6443
name: docker-desktop
contexts:
- context:
cluster: docker-desktop
user: docker-desktop
name: docker-desktop
current-context: docker-desktop
kind: Config
preferences: {}
users:
- name: docker-desktop
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
只查看當前的 context config 資訊:
kubectl config view --minify
基本上可以歸納出三個重點:
Clusters
:此列表中紀錄著每個集群如何與該集群的 kube-apiserver
溝通的 URL以及認證權限。Contexts
:此列表中紀錄著當你在該 Context
時,對 kube-apiserver
溝通時將會以內容中的 cluster
、user
、namespace
來執行(如 namespcae 為空則預設為 default
)。Users
:使用者選項定義著每個使用著唯一的名字以及相關的多種認證授權資訊,像是 client certificates
、bearer tokens
、authenticating proxy
等等。假設在我們的工作環境中有兩個集群,一個用於正式環境(production),另一個用於開發環境(develop),而兩個集群中我們又將前端(frontend)和後端(backend)用 namespace
區隔開來,接著我們將創造出前端開發者以及後端開發者兩種角色,並期望使用 Context
規範不管在正式環境或開發環境中,前端開發者與後端開發者只能在對應的 namespace
下控制集群。
此時粗略的 kubeconfig 大概如下:
apiVersion: v1
kind: Config
clusters:
- cluster:
name: development
- cluster:
name: production
users:
- name: backend-developer
- name: front-developer
contexts:
- context:
name: dev-backend
namespace: backend
cluster: development
user: backend-developer
- context:
name: prod-backend
namespace: backend
cluster: production
user: backend-developer
- context:
name: dev-frontend
namespace: frontend
cluster: development
user: frontend-developer
- context:
name: prod-frontend
namespace: frontend
cluster: production
user: frontend-developer
可以簡單的理解成,當切換到哪個 Context
時,即可以視為該 user
認證身份下的『操作權限』在該 cluster
中的kube-apiserver
發出對該 namespace
下的資源請求。
Context
:
# 建立/修改 Context 指令:
kubectl config set-context <CONTEXT_NAME> --namespace=<NAMESPACE_NAME>--cluster=<CLUSTER_NAME> --user=<USER_NAME>
# 陸續將所有 Context 建立出來:
kubectl config set-context prod-frontend --cluster=production --namespace=frontend --user=prod-frontend
--------
Context "prod-frontend" created.
kubectl config set-context prod-backend --cluster=production --namespace=backend --user=prod-backend
--------
Context "prod-backend" created.
kubectl config set-context dev-frontend --cluster=development --namespace=frontend --user=dev-frontend
--------
Context "dev-frontend" created.
kubectl config set-context dev-backend --cluster=development --namespace=backend --user=dev-backend
--------
Context "dev-backend" created.
再次查看 kubeconfig 可以發現上列 Context
以出現在列表之中:
kubectl config view
-------
contexts:
- context:
cluster: development
namespace: backend
user: dev-backend
name: dev-backend
- context:
cluster: development
namespace: frontend
user: dev-frontend
name: dev-frontend
- context:
cluster: docker-desktop
user: docker-desktop
name: docker-desktop
- context:
cluster: production
namespace: backend
user: prod-backend
name: prod-backend
- context:
cluster: production
namespace: frontend
user: prod-frontend
name: prod-frontend
Context
:# 顯示當前使用的 context
kubectl config current-context
# 切換到指定的 context
kubectl config use-context <CONTEXT_NAME>
此時我們已經可以隨心所欲的設定並切換 Context
,在團隊中只要讓對應的角色設定到正確的 Context
,即可實現讓該 user
在指定 cluster
中執行被賦予的權限。
# 刪除用戶
kubectl --kubeconfig=config-demo config unset users.<name>
# 刪除集群
kubectl --kubeconfig=config-demo config unset clusters.<name>
# 刪除 context
kubectl --kubeconfig=config-demo config unset contexts.<name>
看到這裡可能有些敏銳的同學注意到了,既然 Context
如前面所說的是一種 Alias
的概念,那實際執行的 cluster
授權以及 user
認證是如何來的呢?
由於我們在本地使用的 docker-desktop 只能提供我們一個 cluster
集群,加上在實際工作中使用的大多是雲端平台整合好的 Kubernetes
服務(Google GKE, AWS EKS….等),各家平台對於 kubeconfig
的 cluster
管理多半有與自家用戶權限整合,並以自家 cli 或 sdk 的方式進行操作,各家操作方式不一,所以本篇重點將放在 Context 管理上。
簡單使用 Google 的 gcloud auth
相關指令新增了對 Google GKE 集群的 kubeconfig,大概會如下所示:
kubectl config view
--------
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://35.xxx.xxx.xxx
name: gke_xxx-xxxx_asia-east1-c_xxx-dev
contexts:
- context:
cluster: gke_xxx-xxx_asia-east1-c_xxx-dev
namespace: rtmp-relay
user: gke_xxx-xxx_asia-east1-c_xxx-dev
name: gke_xxx-xxx_asia-east1-c_xxx-dev
current-context: docker-desktop
kind: Config
preferences: {}
users:
- name: gke_xxx-xxx_asia-east1-c_xxx-dev
user:
auth-provider:
config:
access-token:
cmd-args: config config-helper --format=json
cmd-path: /google-cloud-sdk/bin/gcloud
expiry: "2022-09-23T17:43:59Z"
expiry-key: '{.credential.token_expiry}'
token-key: '{.credential.access_token}'
name: gcp
關於使用 kubectl 獨自建立/修改 cluster
的指令:
kubectl config set-cluster \
<CLUSTER_NAME> \
--server=<SERVER_ADDRESS> \
--certificate-authority=<CLUSTER_CERTIFICATE>
而建立/修改 user
的指令也是非常相似的:
kubectl config set-credentials \
<USER_NAME> \
--client-certificate=<USER_CERTIFICATE> \
--client-key=<USER_KEY>
以上指令使用憑證的方式驗證身份,而 --client-certificate
被用來認證 user
,--certificate-authority
則用來認證該 cluster
。官方提供更多的驗證方式可以參考相關文件 Kubernetes authentication overview。
在以上的介紹中,我們大概可以了解 Context
這個在很多語言或者工具中,有著不同用途的抽象概念。有了 Context
我們在身為服務守護者的團隊協作中,可以確保每個人該有的最大權限,在個人開發中,也可以防止自己的人為疏忽而造成不可逆轉的損失,接下來我們將更進一步的深入介紹 ,基於RBAC
下 Kubernetes
如何對一個角色進行授權吧。
千呼萬喚始出來!鐵人賽系列「從異世界歸來發現只剩自己不會 Kubernetes」同名改編作品出版了!
感謝所有交流指教的各路英雄,也感謝願意點閱文章的各位,如果能幫助到任何人都將會是我的榮幸。
本書內容改編自第 14 屆 iThome 鐵人賽 DevOps 組的優選系列文章《從異世界歸來發現只剩自己不會 Kubernetes》。此書是一本綜合性的指南,針對想要探索認識 Kubernetes 的技術人員而生。無論是初涉此領域的新手,還是已有深厚經驗的資深工程師,本書都能提供你所需的知識和技能。
「這本書不僅提供了豐富的範例程式碼和操作指南,讓身為工程師的我們能實際操作來加深認知;更重要的是,它教會我如何從後端工程師的角度去思考和應用 Kubernetes。從容器的生命週期、資源管理到部署管理,每一章都與我們的日常開發工作息息相關。」
──── 雷N │ 後端工程師 / iThome 鐵人賽戰友
天瓏連結: 從異世界歸來發現只剩自己不會 Kubernetes:初心者進入雲端世界的實戰攻略!
相關程式碼同時收錄在:
https://github.com/MikeHsu0618/2022-ithelp/tree/master/Day28
Reference
[Day17] k8s管理篇(三):User Management、RBAC、Node Maintenance