返回文章列表

Kubernetes叢集模擬功能組態

本文探討如何在 Kubernetes 叢集中組態模擬(Impersonation)功能,允許服務帳戶代表其他使用者操作,並示範如何使用 OpenUnison 和其他反向代理實作模擬,同時討論 RBAC 策略組態、稽核以及安全考量。

Kubernetes DevOps

在 Kubernetes 叢集中,模擬功能允許服務帳戶代表其他使用者執行操作,這對於在叢集內外執行反向代理尤其實用。本文將介紹如何使用 OpenUnison 組態及啟用模擬功能,並探討不使用 OpenUnison 的情況下,如何透過其他反向代理及 RBAC 策略設定來達成模擬,同時也涵蓋安全性考量和 RBAC 策略的稽核機制。透過正確的組態,可以增強叢集的安全性及靈活性,並確保服務帳戶的許可權控管。

組態叢集以使用模擬(Impersonation)功能

在前面的章節中,我們瞭解了服務帳戶(Service Account)的特殊許可權:它可以用來模擬任何人(取決於您的RBAC定義)。如果您在叢集內部執行反向代理(reverse proxy),使用服務帳戶是可行的,尤其是結合TokenRequest API以保持令牌(token)短暫有效。

安全性考量

  • 當在叢集外部執行代理時,如果代理被入侵,攻擊者可以使用該服務帳戶以任何人的身份存取API服務。因此,務必經常輪換(rotate)該服務帳戶。
  • 如果在叢集外部執行代理,最好使用較短有效期的憑證(certificate)代替服務帳戶。

在叢集上執行代理時,您需要確保它被妥善鎖定。至少應在自己的名稱空間(namespace)中執行。避免使用kube-system名稱空間,因為您希望最小化存取許可權。使用多因素身份驗證(multi-factor authentication)來存取該名稱空間是一個好主意,同時也應實施網路策略(network policies)來控制哪些Pod可以存取反向代理。

組態叢集以使用模擬功能

步驟1:刪除現有的Helm佈署

首先,刪除現有的orchestra Helm佈署(這不會刪除操作員;我們希望保留OpenUnison操作員)。

$ helm delete orchestra --namespace openunison
release "orchestra" uninstalled

此時,openunison名稱空間中只剩下操作員Pod。由操作員在佈署orchestra Helm chart時建立的所有Secret、Ingress、Deployment、Service等物件都已被刪除。

步驟2:重新佈署OpenUnison並啟用模擬功能

編輯values.yaml檔案,新增以下兩行組態:

network:
  openunison_host: "k8sou.apps.192-168-2-131.nip.io"
  dashboard_host: "k8sdb.apps.192-168-2-131.nip.io"
  api_server_host: "k8sapi.apps.192-168-2-131.nip.io"
  session_inactivity_timeout_seconds: 900
k8s_url: https://192.168.2.131:32776
cert_template:
  ou: "Kubernetes"
  o: "MyOrg"
  l: "My Cluster"
  st: "State of Cluster"
  c: "MyCountry"
image: "docker.io/tremolosecurity/openunison-k8s-login-saml2:latest"
myvd_config_path: "WEB-INF/myvd.conf"
k8s_cluster_name: kubernetes
enable_impersonation: true
dashboard:
  namespace: "kubernetes-dashboard"
  cert_name: "kubernetes-dashboard-certs"
  label: "k8s-app=kubernetes-dashboard"
  service_name: kubernetes-dashboard
certs:
  use_k8s_cm: false
  trusted_certs: []
monitoring:
  prometheus_service_account: system:serviceaccount:monitoring:prometheus-k8s
saml:
  idp_url: https://portal.apps.tremolo.io/idp-test/metadata/dfbe4040-cd32-470e-a9b6-809c8f857c40
  metadata_xml_b64: ""

步驟3:使用更新的values.yaml檔案重新安裝Helm chart

helm install orchestra tremolo/openunison-k8s-login-saml2 --namespace openunison -f ./values.yaml

步驟4:完成與測試身份提供者的整合

  1. 取得後設資料(metadata):
$ curl --insecure https://k8sou.apps.192-168-2-131.nip.io/auth/forms/saml2_rp_metadata.jsp
  1. 登入到https://portal.apps.tremolo.io/,選擇測試身份提供者,並將取得的後設資料貼上到測試身份提供者的Meta Data欄位中。
  2. 點選Update Relying Party。

測試模擬功能

  1. 在瀏覽器中輸入OpenUnison佈署的URL。
  2. 登入到OpenUnison,然後點選儀錶板(dashboard)。您不應該看到任何錯誤訊息。
  3. 點選右上角的小圓形圖示,檢視您登入的使用者身份。
  4. 傳回OpenUnison儀錶板,點選Kubernetes Tokens徽章。注意,傳遞給kubectl--server標誌不再是IP地址,而是values.yaml檔案中network.api_server_host的主機名。
  5. kubectl命令複製並貼上到shell中:
export TMP_CERT=$(mktemp) && echo -e "
---
--BEGIN CERTIFICATE
---
--\n...\n
---
--END CERTIFICATE
---
--" > $TMP_CERT
kubectl config set-cluster kubernetes --server=https://k8sapi.apps.192-168-2-131.nip.io --certificate-authority=$TMP_CERT --embed-certs=true
kubectl config set-context kubernetes --cluster=kubernetes --user=mlbiamext
kubectl config use-context kubernetes

內容解密:

此步驟演示瞭如何組態OpenUnison以使用模擬功能,並測試其與Kubernetes叢集的整合。透過啟用模擬功能,OpenUnison可以作為API伺服器的反向代理,讓使用者能夠透過OpenUnison存取Kubernetes資源而無需直接與API伺服器互動。這增強了叢集的安全性和靈活性。

圖表翻譯:

此處沒有Plantuml圖表,請根據實際內容新增相關圖表及翻譯。

組態模擬(Impersonation)而不使用 OpenUnison

在前面的章節中,我們已經瞭解如何使用 OpenUnison 來組態模擬(Impersonation)。現在,我們將探討如何在不使用 OpenUnison 的情況下實作模擬。

瞭解模擬的需求

模擬是一種機制,允許一個程式或服務帳戶代表另一個使用者或帳戶執行操作。在 Kubernetes 中,這意味著一個反向代理(reverse proxy)可以代表使用者向 API 伺服器傳送請求。

使用其他反向代理實作模擬

雖然 OpenUnison 提供了自動化的解決方案,但也可以使用其他反向代理來實作模擬。例如,JetStack 的 OIDC Proxy 就是一個專門為 Kubernetes 設計的解決方案。

關鍵要素

要成功實作模擬,需要了解兩個關鍵要素:

  1. 模擬的 RBAC 策略:需要正確組態 RBAC 策略,以允許服務帳戶進行模擬。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: impersonator
rules:
- apiGroups:
  - ""
  resources:
  - users
  - groups
  verbs:
  - impersonate

內容解密:

此 YAML 檔案定義了一個名為 impersonator 的 ClusterRole,該角色具有模擬使用者和群組的許可權。其中:

  • apiVersionkind 指定了 Kubernetes 資源的版本和型別。
  • metadata 部分定義了資源的名稱。
  • rules 部分定義了角色的許可權。在此例中,該角色可以對 usersgroups 資源執行 impersonate 操作。
  1. 預設群組:Kubernetes 在模擬使用者時不會自動新增 system:authenticated 群組。因此,需要手動組態反向代理以新增此群組,否則可能會導致某些操作失敗。

RBAC 策略與稽核

身份驗證只是管理叢集存取的第一步。一旦授予叢集存取許可權,就需要根據帳戶型別(自動化系統或使用者)限制其操作。本章將探討 Kubernetes 的根據角色的存取控制(RBAC)模型。

RBAC 簡介

RBAC 是 Kubernetes 用於授權存取資源的機制。本章的第一部分將探討如何組態 RBAC、有哪些選項可用,並將理論對映到實際示例中。

將企業身份對映到 Kubernetes 以授權資源存取

本章將探討如何將企業身份對映到 Kubernetes,以授權存取資源。這包括瞭解如何使用 RBAC 策略來控制對資源的存取。

名稱空間多租戶

本章還將探討名稱空間多租戶的概念,以及如何使用 RBAC 來管理不同名稱空間中的資源存取。

Kubernetes 稽核

Kubernetes 稽核是一種記錄叢集中發生的事件的機制。本章將探討如何使用稽核來監控和除錯叢集。

使用 audit2rbac 除錯策略

audit2rbac 是一個用於除錯 RBAC 策略的工具。本章將探討如何使用該工具來簡化除錯過程。

RBAC 策略與稽核

技術需求

本章節有以下技術需求:

  • 一個使用第7章組態的 KinD 叢集:將身份驗證整合到叢集中
  • 可以存取第6章的SAML2實驗室:服務、負載平衡和外部DNS

RBAC 簡介

在探討RBAC之前,讓我們快速回顧一下Kubernetes和存取控制的歷史。 在Kubernetes 1.6之前,存取控制是根據屬性基礎的存取控制(ABAC)。顧名思義,ABAC透過將規則與屬性進行比較來提供存取權,而不是角色。所分配的屬性可以被賦予任何型別的資料,包括使用者屬性、物件、環境、位置等。

過去,要為ABAC組態Kubernetes叢集,您必須在API伺服器上設定兩個值:

  • --authorization-policy-file
  • --authorization-mode=ABAC

authorization-policy-file 是API伺服器上的本地檔案。由於它是每個API伺服器上的本地檔案,因此對檔案的任何更改都需要對主機的特權存取權,並且需要重新啟動API伺服器。可以想像,更新ABAC策略的過程變得困難,並且任何即時更改都需要API伺服器重新啟動時的短暫中斷。

從Kubernetes 1.6開始,RBAC成為授權存取資源的首選方法。與ABAC不同,RBAC使用Kubernetes原生物件,並且更新會在無需重新啟動API伺服器的情況下反映出來。RBAC也與不同的身份驗證方法相容。從現在開始,我們將重點關注如何開發RBAC策略並將其應用到您的叢集中。

什麼是角色?

在Kubernetes中,角色是一種將許可權繫結到一個可以被描述和組態的物件的方法。角色具有規則,這些規則是資源和動詞的集合。從後往前看,我們有以下內容:

  • 動詞:可以在API上執行的操作,例如讀取(get)、寫入(createupdatepatchdelete)或列出和監控。
  • 資源:要套用動詞的API名稱,例如 servicesendpoints 等。也可以列出特定的子資源。可以命名特定的資源以提供對物件的非常具體的許可權。

角色並不指定誰可以對資源執行動詞——這由角色繫結(RoleBindings)和叢集角色繫結(ClusterRoleBindings)處理。我們將在角色繫結和叢集角色繫結一節中瞭解更多相關資訊。

重點提示

術語「角色」可以有多種含義,並且RBAC經常在其他上下文中使用。在企業界,術語「角色」通常與業務角色相關聯,用於傳達對該角色的授權,而不是特定人員。例如,一家企業可能會為所有應付帳款人員分配發出支票的能力,而不是為應付帳款部門的每位成員建立特定的授權,以便發出支票。當有人在角色之間轉換時,他們會失去舊角色的許可權並獲得新角色的許可權。在從應付帳款轉換到應收帳款的情況下,使用者將失去付款能力並獲得接受付款的能力。透過將許可權繫結到角色,而不是個人,當角色變更時,許可權變更會自動發生,而無需手動切換每個使用者的許可權。這是術語RBAC更「經典」的用法。

每個規則中的資源都由以下內容識別:

  • apiGroups:資源所屬群組的列表
  • resources:資源的物件型別名稱(以及可能的子資源)
  • resourceNames:可選的、要套用此規則的特定物件列表

每個規則必須具有apiGroupsresources列表。 resourceNames是可選的。

重點提示

如果您發現自己正在授權對名稱空間內特定物件的存取權,那麼是時候重新思考您的授權策略了。Kubernetes的租戶邊界是名稱空間。除非有非常具體的原因,否則在RBAC角色中命名特定的Kubernetes物件是一種反模式,應避免使用。當RBAC角色正在命名特定物件時,請考慮將它們所在的名稱空間分解,以建立單獨的名稱空間。

一旦資源在規則中被識別,就可以指定動詞。動詞是一種可以在資源上執行的操作,提供對Kubernetes中物件的存取權。

如果對物件所需的存取權應為 all,則無需新增每個動詞;相反,可以使用萬用字元來識別所有動詞、資源或apiGroups

識別角色

Kubernetes授權頁面(https://kubernetes.io/docs/reference/access-authn-authz/rbac/)使用以下角色作為範例,允許某人取得Pod及其日誌的詳細資訊:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]

內容解密:

此YAML定義了一個名為pod-and-pod-logs-reader的角色,位於default名稱空間中。該角色允許對podspods/log資源執行getlist操作。

  • apiVersionkind 定義了該物件的型別和版本。
  • metadata 包含了該角色的後設資料,包括名稱和名稱空間。
  • rules 定義了該角色的規則。在這個例子中,有一條規則允許對 podspods/log 資源執行 getlist 操作。
    • apiGroups: [""] 表示該資源屬於核心API群組(即未指定任何群組)。
    • resources: ["pods", "pods/log"] 指定了受此規則影響的資源:Pods及其日誌。
    • verbs: ["get", "list"] 指定了允許的操作:取得和列出。

從後往前推斷這個角色是如何定義的,我們將從資源開始,因為它是最容易找到的部分。Kubernetes中的所有物件都由URL表示。如果您想提取預設名稱空間中所有Pod的資訊,您將呼叫 /api/v1/namespaces/default/pods URL;如果您想要特定Pod的日誌,您將呼叫 /api/v1/namespaces/default/pods/mypod/log URL。

Kubernetes 中的角色(Role)定義與應用

在 Kubernetes 的 RBAC(Role-Based Access Control)授權機制中,角色(Role)是用於定義使用者或服務帳戶對叢集資源的存取許可權。本文將探討 Role 的定義、應用及其相關的最佳實踐。

Role 的組成要素

一個 Role 主要由三個部分組成:apiGroupsresourcesverbs。這些元素共同決定了 Role 所能執行的操作範圍。

  • apiGroups:指定了資源所屬的 API 群組。例如,Pod 資源屬於核心群組,其 apiGroups 為空字串 ("")。
  • resources:列出了受權控管的資源型別,如 Pod 或 Pod 的日誌。
  • verbs:定義了允許對資源執行的操作,如 getlist 等。值得注意的是,這裡的 verbs 並非 HTTP 動詞,而是根據 Kubernetes API 伺服器的物件結構定義的。

Role 與 ClusterRole 的區別

Role 可以在名稱空間(namespace)層級或叢集(cluster)層級定義許可權。當定義為 ClusterRole 時,可以跨名稱空間或針對非名稱空間資源(如 PersistentVolume 和 StorageClass)設定許可權。

示例:ClusterRole 定義

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-pod-and-pod-logs-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]

內容解密:

  1. apiVersionkind:指定了 Kubernetes 資源的 API 版本和型別,這裡定義了一個 ClusterRole。
  2. metadata.name:為這個 ClusterRole 定義了名稱。
  3. rules:列出了具體的授權規則。
    • apiGroups: [""]:表示核心 API 群組。
    • resources: ["pods", "pods/log"]:允許存取 Pod 和 Pod 日誌資源。
    • verbs: ["get", "list"]:允許對這些資源執行 getlist 操作。

負向角色(Negative Roles)的限制

在 RBAC 中,不支援直接定義「允許所有操作除了特定操作」這樣的負向角色。主要原因包括:

  • 安全性與簡潔性:複雜的規則引擎難以測試和驗證,容易引入安全漏洞。
  • 未預期的後果:允許大部分操作的許可權可能在叢集擴充套件或新增功能時引入未預期的風險。

替代方案與最佳實踐

雖然 RBAC 不直接支援負向角色,但可以透過自定義授權 Webhook 或動態生成 RBAC Role 物件來實作類別似功能。然而,這些方法被視為安全性的反模式,應謹慎使用。

Kubernetes RBAC 結構圖示

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title Kubernetes RBAC 結構圖示

rectangle "繫結" as node1
rectangle "定義" as node2
rectangle "包含" as node3
rectangle "指定" as node4
rectangle "列出" as node5

node1 --> node2
node2 --> node3
node3 --> node4
node4 --> node5

@enduml

圖表翻譯: 此圖示呈現了 Kubernetes RBAC 的基本結構。使用者或服務帳戶透過繫結 Role 或 ClusterRole 獲得許可權。Role/ClusterRole 中定義了具體的許可權規則,包括 apiGroups、resources 和 verbs,分別指定了 API 群組、資源型別和允許的操作,從而實作了細粒度的許可權控制。