iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
DevOps

30 天挑戰 CKAD 認證!菜鳥的 Kubernetes 學習日記系列 第 20

【Day20】掌握 KubeConfig:Clusters、Users 與 Contexts 的三角關係

  • 分享至 

  • xImage
  •  

gh

前情提要

昨天我們深入實戰了 RBAC (Role-Based Access Control),看到了 Kubernetes 權限管理的核心概念。我們先從系統內建的 kube-proxy Role/RoleBinding 開始,了解如何查看物件資源的權限;接著建立了新的使用者 sean,這個帳號在一開始什麼都做不了,直到透過 Role 與 RoleBinding 賦予權限,才得以在 Namespace sean 內查看 Pods。最後,我們建立了 ClusterRole 與 ClusterRoleBinding,讓 sean 能跨越 Namespace,查看整個叢集的 Nodes。

然而,僅僅有了角色與權限,還不代表使用者可以順利進入 Clusters。實際上,我們還需要一份 KubeConfig 來定義使用者該如何連線到 API Server、使用哪一組憑證,以及當前該用哪個 Context。簡單來說,KubeConfig 是讓 API Serverkubectl 知道 「我是誰、我要去哪裡、我要用什麼身份」 的關鍵設定檔。今天我們來看看 Kube Config 如果管理 Clusters、Users、Contexts!

為何需要 Kube Config

如果沒有 KubeConfig,每次要查詢 Kubernetes 資源時,都得把憑證與金鑰通通帶上,指令會變得很冗長,例如:

kubectl get pods
  --server=https://172.18.0.3:6443 \
  --client-certificate=/etc/kubernetes/pki/admin.crt \
  --client-key=/etc/kubernetes/pki/admin.key \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \

KubeConfig 正是為了解決這種麻煩,它是一個 YAML 設定檔,描述了如何連線到 Kubernetes 叢集:包含 API Server 的位址、使用者憑證,以及多個環境的切換方式。

預設路徑是 ~/.kube/configkubectl 會自動讀取這個檔案,因此下指令時不需要再額外輸入憑證參數。

Kube Config 載入順序

kubectl 載入設定檔時,會依照以下優先序決定使用哪一份:

  1. --kubeconfig 參數:顯式指定的檔案,優先級最高。
  2. $KUBECONFIG 環境變數:如果有設定,會讀取該變數指向的檔案。
  3. 預設檔案 ~/.kube/config:當以上兩者皆未指定時,才會使用。

Kube Config 組成元素

gh

一份 kubeconfig 檔案主要包含三個核心部分,如上圖:

  • clusters:定義叢集(API Server 的 URL、CA 憑證),通常會有多個 Cluster,例如 Dev 與 Prod。
  • users:定義用戶(使用憑證、token 或基本認證來證明身份),以 Local 來看就如同 root 使用者以外,還會有其他 User。在實務上會最常見的是分成 Admin 和 Develop 的角色,但詳細還是會根據專案背景與需求調整。
  • contexts:將「Cluster + User + Namespace」綁定在一起,形成一個操作環境。

KubeConfig 並不會「創建新用戶」或「賦予新權限」,它只是 告訴 kubectl 要用哪個身份去連線哪個叢集。真正的授權還是透過 RBAC 管控。

以下面我自己的 Kube Config 為例:

kubectl config view

可以看到這個 yaml 檔除了基本的 apiVersion 和 kind 之外,剩下的三個部分就是前面提及的 ClusterContextsUsers。可以看到我是一個 Cluster 和兩個 Users,然後 Contexts 會將 Cluster 和 Users 綁在一起。current-context 就代表 kubectl 在不指定任何額外參數時,會用哪個 cluster、哪個 user、哪個 namespace 都在這邊設定好了。

Namespace 的部分是切換到指定 Contexts 後,預設不指定的話就會在指定的 Namespace 進行操作。

apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://127.0.0.1:36345
  name: kind-kind
contexts:
- context:
    cluster: kind-kind
    namespace: default
    user: kind-kind
  name: kind-kind
- context:
    cluster: kind-kind
    namespace: sean
    user: sean
  name: sean-context
current-context: kind-kind
preferences: {}
users:
- name: kind-kind
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED
- name: sean
  user:
    client-certificate: /root/sean/sean.crt
    client-key: /root/sean/sean.key

切換 Context 只需要:

kubectl config use-context sean-context

可以看到 Kube Config 會跟著更新,切換後 kubectl 就會以 sean 這個使用者、連線到 kind-kind Cluster、並在 sean namespace 下操作:

gh

Kube Config 相關操作:Clusters、Users、Contexts

這裡整理常見操作,並透過圖片和指令實際驗證。

使用 Kube Config

在開始實戰 Kube Config 之前,要先知道 Kubernetes 把設定檔放在哪。

進入 Master Node:

docker exec -it kind-control-plane bash

可以看到有 admin.conf,這就是叢集初始化時產生的預設 KubeConfig,裡面就是 Super User 的憑證與設定。

gh

解碼檔案中的憑證可以看到內容確實是 base64 編碼的:

echo "your-certificate" | base64 -d

我們之前實戰操作都是使用 root 使用者進行操作,例如切換成 Local 使用者 sean_chen::

# 切換 User
su - sean_chen

# 使用 User sean_chen 查看 Node
kubectl get nodes

gh

此時會因為缺少 ~/.kube/config 而無法操作。解法是複製一份設定檔給該使用者並修改擁有權限:

mkdir - /home/sean_chen/.kube ; docker cp kind-control-plane:/etc/kubernetes/admin.conf /home/sean_chen/.kube/config; chown -R sean_chen:sean_chen /home/sean_chen/.kube/config

接下來到對應資料夾看看檔案權限,確定 User 有權限可以使用:

ls -atlhr

gh

確認擁有者之後,再次查看 Node:

kubectl get nodes

就能看到 Cluster Nodes,證明不同使用者也能正確存取。

gh

建立 Cluster:

首先因為我是 Kind,我需要先把 ca.crt 從 Master Node 拿出來:

docker cp kind-control-plane:/etc/kubernetes/pki/ca.crt ./kind-config

再來我們連線的 Server 要變成 Master Node 的 Docker Container IP,因此要先查看:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' kind-control-plane

該拿的資訊都拿到之後,就建立一個 Cluster:

kubectl config set-cluster myk8s --server=https://172.18.0.3:6443 --certificate-authority=ca.crt --embed-certs --kubeconfig=newconfig

gh

建立完成後,可以比較有無指定 --kubeconfig 的差別,也呼應了前面提到的載入順序。

gh

刪除 Cluster:

kubectl config delete-cluster myk8s --kubeconfig=newconfig

建立 Users:

三種方式:

  1.  憑證 (SSL Client Certificate):這也是昨天 RBAC 建立 User 的方式
kubectl config set-credentials sean --client-certificate=/root/sean/sean.crt --client-key=/root/sean/sean.key --kubeconfig=newconfig
  1. Bearer Token (常見於 ServiceAccount)
kubectl config set-credentials sa-sean --token=$TOKEN --kubeconfig=newconfig
  1. Basic Auth (已不建議):HTTP 基本認證,由 username 與 password 組成而成的身份認證
kubectl config set-credentials http-sean --username=admin --password=uXFGweU9l35qcif --kubeconfig=newconfig

查詢 Users:

# 查詢第一個 Users:
kubectl config view -o jsonpath='{.users[].name}'

# 查詢所有 Users:
kubectl config view -o jsonpath='{.users[*].name}'

gh

習慣 jq 的也可以直接用 jq 取得想要的資訊。

移除 Users:

kubectl unset users.sean

建立 Contexts:

指定 Cluster、User、Namespace

# 可以不要指定 Kube Config 就會套用預設的 Config
kubectl config set-context sean-context --cluster=kind-kind --namespace=sean --user=sean --kubeconfig=newconfig

切換 Contexts:

# 可以不要指定 Kube Config 就會套用預設的 Config
# 查詢所有 Contexts
kubectl config get-contexts --kubeconfig=newconfig

重新命名:

# 查詢當前 Contexts
kubectl config current-context --kubeconfig=newconfig

設定 Contexts

# 可以不要指定 Kube Config 就會套用預設的 Config
# 切換 Contexts
kubectl config use-context sean-context --kubeconfig=newconfig

# 重新命名 Contexts
kubectl config rename-context sean-context context-sean --kubeconfig=newconfig

刪除 Contexts

# 可以不要指定 Kube Config 就會套用預設的 Config
# 刪除 Contexts
kubectl config delete-context sean-context --kubeconfig=newconfig

kubectl config 提供了完整的 CRUD 操作,但實務上若已熟悉結構,直接編輯 YAML 會更快。

實戰 🔥

接下來用 Service Account 實戰一個完整流程。

我們先拿前面練習的 Cluster 來用:

kubectl config set-cluster myk8s --server=https://172.18.0.3:6443 --certificate-authority=ca.crt --embed-certs --kubeconfig=newconfig

建立一個 Namespace:

kubectl create ns sa-ithome

建立 Service Account:

kubectl -n sa-ithome create serviceaccount sa-ithome

gh

建立與該 SA 對應的 Secret:

apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: sa-ithome-secret
  namespace: sa-ithome
  annotations:
    kubernetes.io/service-account.name: "sa-ithome"

gh

設定環境變數 TOKENNAME:

TOKENNAME=sa-ithome-secret

將 Secrets 內容解碼之後存放到 TOKEN 環境變數 (Secrets 儲存只會使用 base64 編碼)

TOKEN=`kubectl -n sa-ithome get secret $TOKENNAME -o jsonpath='{.data.token}'| base64 --decode`

把這個 Token 加入 Service Account,目的是要讓 kubectl 在執行時就能帶著這個 Token 去跟 API Server 做 Authentication 身分驗證,讓 API Server 知道「這是 sa-ithome 這個 ServiceAccount」。

kubectl config set-credentials sa-ithome --token=$TOKEN --kubeconfig=newconfig

gh

查看我們剛剛建立的 SA Users:

kubectl config get-users --kubeconfig newconfig

gh

Clusters 和 Users 都建立好了,現在建立 Contexts 將他們組合起來:

# 建立 Contexts
kubectl config set-context sa-ithome@myk8s --cluster=myk8s --user=sa-ithome --namespace=sa-ithome --kubeconfig=newconfig

# 查詢 Contexts
kubectl config get-contexts --kubeconfig=newconfig

gh

但可以看到我們建立的 Service Account 還不是預設的 Contexts,因此我們將其指定為預設的 Contexts:

kubectl config use-context sa-ithome@myk8s --kubeconfig=newconfig

這樣就成功將預設 Context 設定過來了,看到 * 在 Current Context:

gh

驗證權限:

kubectl auth can-i list pod --kubeconfig=newconfig

kubectl get pods --kubeconfig=newconfig

結果顯示無法操作,因為 SA 尚未綁定任何 Role。這呼應了昨天 RBAC 的重點:身份認證 (Authentication) 只證明「你是誰」,真正能不能做事,還是得靠 RBAC 授權 (Authorization)。

gh

總結

今天我們把重點放在 KubeConfig,理解了它的三大組成元素:Clusters、Users 與 Contexts,並透過實戰驗證它在 Authentication 中的角色。

需要特別注意的是,KubeConfig 本身 不會創建用戶或賦權,它只是存放身份與連線資訊的設定檔。當 API Server 收到請求,會先依據 KubeConfig 驗證憑證 (Authentication),確認你是誰;接著才會進入 RBAC (Authorization),判斷這個身份是否有足夠的權限執行操作。

透過實戰,我們學會了如何新增 Cluster、User、Context,並且利用 Service Account 的 Token 測試 Context 切換與權限驗證,實際感受到「身份」與「權限」是分開處理的。

而這個流程還沒結束。在 Authentication → Authorization 之後,還會再經過 Admission Controllers。它們負責在物件進入叢集前進行最後的檢查與處理,例如補上必要的欄位、套用預設策略,或是直接拒絕不符合規範的資源。換句話說,Admission Controllers 是 Kubernetes 確保環境一致性與安全性的最後一環。明天要來更深入探討 Admission Controllers 的角色,以及如何透過 Validating / Mutating Webhook 來實現自訂規則。

下一篇文章:Kubernetes 安全鏈條的最後拼圖:Admission Controllers


上一篇
【Day19】扮演 Kubernetes 的權限總管:RBAC 授權機制
下一篇
【Day21】Kubernetes 安全鏈條的最後拼圖:Admission Controllers
系列文
30 天挑戰 CKAD 認證!菜鳥的 Kubernetes 學習日記21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言