iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0
Kubernetes

從零開始的雲端實戰:30 天 Kubernetes 核心觀念與部署指南系列 第 26

【Day 26】集群安全守門員:RBAC 角色權限控管與 ServiceAccount

  • 分享至 

  • xImage
  •  

今日目標

  • 理解企業多使用者與多應用環境下,實施「最小權限原則(Principle of Least Privilege)」的必要性。
  • 搞懂 Kubernetes RBAC 的核心四要素:User / ServiceAccountRole / ClusterRoleRoleBinding / ClusterRoleBinding
  • 掌握人類使用者身分(User)與程式 Pod 身分(ServiceAccount)的差異。
  • 實戰操作:建立一個「唯讀權限」的 ServiceAccount,並實測其被允許與被拒絕的 API 操作。

痛點場景:人人都是 Admin 的災難

在前面的所有實作中,我們使用的都是預設的 minikube 系統最高權限(cluster-admin)。

但在真實企業團隊中:

  • 開發工程師 / 實習生:通常只需要在 development 空間內查看日誌與重啟 Pod,不該有權限修改生產環境(production)或刪除命名空間。
  • CI/CD 自動化工具(如 GitHub Actions、GitLab CI):只需要有更新 Deployment 映像檔的權限,不該擁有讀取全部 Secret 密碼的權限。
  • 跑在 Pod 內部的程式:如果需要呼叫 K8s API,絕對不能給予無限制的存取權限,否則一旦容器被黑客攻破,整個集群就會直接淪陷。

為了解決權限劃分問題,Kubernetes 內建了強大的 RBAC(Role-Based Access Control,基於角色的存取控制)


RBAC 的核心四要素解密

RBAC 的運作邏輯非常直觀,主要回答三個問題:「誰(Who)」「哪裡(Where)」「什麼資源(What)」 執行 「什麼動作(How)」

RBAC 元件 作用範圍(Scope) 角色定位說明
ServiceAccount Namespace 級別 給「Pod 內部的應用程式」或「CI/CD 程式」使用的專屬身分帳號。
Role Namespace 級別 定義在「單一命名空間」內的權限規則清單(例如:只能讀取 dev 空間的 Pods)。
ClusterRole Cluster 全集群級別 定義在「全集群範圍」的權限規則清單(例如:讀取所有 Nodes 或所有 Namespaces 的資源)。
RoleBinding Namespace 級別 「綁定關係」:將某個 Role 的權限授予特定的 User 或 ServiceAccount。
ClusterRoleBinding Cluster 全集群級別 「集群綁定關係」:將 ClusterRole 的全集群權限授予特定的帳號。

Role 的權限規則如何撰寫?

一份 Role 定義檔核心包含三個欄位:

rules:
  - apiGroups: [""]            # 核心 API 群組(例如 Pod, Service, ConfigMap 屬於 "")
    resources: ["pods", "pods/log"] # 允許存取的資源名稱
    verbs: ["get", "list", "watch"] # 允許執行的動作(動詞)

常見的 verbs(動作動詞)包含:

  • get:查看單一物件
  • list:列出物件清單
  • watch:持續監聽變更
  • create:建立新物件
  • update / patch:修改物件
  • delete:刪除物件

實戰演練:建立一個受限的「Pod 唯讀帳號」

我們要在 default 命名空間中,建立一個只能「查看與讀取 Pod 日誌」、但「嚴禁建立或刪除任何 Pod」的受限 ServiceAccount。

步驟 1:建立 ServiceAccount、Role 與 RoleBinding

建立 rbac-demo.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-reader-sa
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader-role
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-binding
  namespace: default
subjects:
  - kind: ServiceAccount
    name: pod-reader-sa
    namespace: default
roleRef:
  kind: Role
  name: pod-reader-role
  apiGroup: rbac.authorization.k8s.io

套用配置:

kubectl apply -f rbac-demo.yaml

步驟 2:使用 kubectl auth can-i 快速檢驗權限

Kubernetes 提供了一個非常強大的指令 kubectl auth can-i,可以讓我們在不切換帳號的情況下,直接模擬該身分測試權限!

測試「是否可以列出 Pods」:

kubectl auth can-i list pods --as=system:serviceaccount:default:pod-reader-sa

預期輸出:

yes

測試「是否可以讀取 Pod 日誌」:

kubectl auth can-i get pods/log --as=system:serviceaccount:default:pod-reader-sa

預期輸出:

yes

測試「是否可以刪除 Pod」:

kubectl auth can-i delete pods --as=system:serviceaccount:default:pod-reader-sa

預期輸出:

no

測試「是否可以查看 Secrets(機密資料庫)」:

kubectl auth can-i get secrets --as=system:serviceaccount:default:pod-reader-sa

預期輸出:

no

步驟 3:在 Pod 中指派該 ServiceAccount

當應用程式需要以特定身分運行時,只需在 Pod 的 spec.serviceAccountName 指定帳號名稱:

apiVersion: v1
kind: Pod
metadata:
  name: app-with-sa
spec:
  serviceAccountName: pod-reader-sa # 指定使用剛剛建立的身分
  containers:
    - name: app
      image: nginx:1.25

當 Pod 啟動後,Kubernetes 會自動在容器內部掛載一個專屬的 JWT Token(位於 /var/run/secrets/kubernetes.io/serviceaccount/token),容器內的程式碼便能拿著這個 Token 向 API Server 發送合法且受限的查詢請求。


本日小結

今天我們搞懂了 Kubernetes 企業資安的基石 RBAC

  • 實踐「最小權限原則」,告別危險的人人 Admin 模式。
  • 搞懂了 Role(單一空間)ClusterRole(全集群) 的邊界。
  • 掌握了 ServiceAccount 作為 Pod 身分憑據的機制。
  • 學會了使用 kubectl auth can-i 快速進行權限除錯與合規驗證。

當有了安全的權限隔離後,開發團隊該如何將寫好的程式碼,自動化打包並部署到 Kubernetes 集群中?

明天 Day 27,我們將進入現代持續部署的核心:「現代自動化部署:CI/CD 整合與 GitOps (ArgoCD) 核心概念」


上一篇
【Day 25】集中式日誌管理:使用 Grafana Loki + Promtail 收集 Pod 日誌
下一篇
【Day 27】現代自動化部署:CI/CD 整合與 GitOps (ArgoCD) 核心概念
系列文
從零開始的雲端實戰:30 天 Kubernetes 核心觀念與部署指南30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言