返回文章列表

Kubernetes 准入控制與授權機制

本文探討 Kubernetes 准入控制與授權機制的最佳實踐和常見挑戰,涵蓋 ValidatingWebhookConfiguration 和 MutatingWebhookConfiguration 的組態細節、failurePolicy 設定、效能最佳化、NamespaceSelector

Kubernetes DevOps

Kubernetes 准入控制與授權機制是確保叢集安全和穩定的根本。本文詳細說明如何組態准入 Webhook,包括 ValidatingWebhookConfigurationMutatingWebhookConfiguration,並探討 failurePolicy 的設定與影響。同時,文章也涵蓋了准入 Webhook 的效能最佳化技巧,例如快速回應和 NamespaceSelector 的使用,以及如何保護 kube-system 名稱空間安全。此外,文章也闡述了 RBAC 的安全組態,並解析了 ABAC、RBAC 和 Webhook 等授權機制,最後結合 GitOps 佈署實踐,提供更全面的 Kubernetes 安全管理方案。

組態准入 Webhook

如前所述,准入 Webhook 的主要優勢之一是它們可以動態組態。瞭解如何有效地組態准入 Webhook 非常重要,因為在一致性和故障模式方面存在著影響和權衡。 以下程式碼片段是一個 ValidatingWebhookConfiguration 資源清單,用於定義一個驗證准入 Webhook。每個欄位的詳細描述如下:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: ## 資源名稱
webhooks:
- name: ## 准入 Webhook 的名稱,當任何准入審查被拒絕時將顯示給使用者
  clientConfig:
    service:
      namespace: ## 准入 Webhook Pod 所在的名稱空間
      name: ## 用於連線到准入 Webhook 的服務名稱
      path: ## Webhook URL
    caBundle: ## 用於驗證 Webhook 伺服器憑證的 PEM 編碼 CA 組合
  rules: ## 描述 API 伺服器必須將哪些操作傳送到此 Webhook
  - operations:
    - ## 觸發 API 伺服器將請求傳送到此 Webhook 的特定操作(例如,建立、更新、刪除、連線)
    apiGroups:
    - ""
    apiVersions:
    - "*"
    resources:
    - ## 按名稱指定的特定資源(例如,佈署、服務、Ingress)
  failurePolicy: ## 定義如何處理存取問題或無法識別的錯誤,必須為 Ignore 或 Fail
  admissionReviewVersions: ["v1"] ## 指定接受的 AdmissionReview 物件版本
  sideEffects: ## 指示 Webhook 是否可能需要處理帶外變更
  timeoutSeconds: 5 ## API 伺服器在將請求視為失敗之前等待回應的時間

內容解密:

ValidatingWebhookConfiguration 資源清單定義了一個驗證准入 Webhook,用於檢查 API 請求是否符合特定規則。其中,webhooks 欄位定義了 Webhook 的名稱、客戶端組態、規則等。clientConfig 欄位指定了用於連線到 Webhook 的服務名稱和名稱空間。rules 欄位定義了觸發 Webhook 的操作和資源。failurePolicy 欄位定義瞭如何處理存取問題或無法識別的錯誤。

MutatingWebhookConfiguration

為了完整起見,讓我們來看看 MutatingWebhookConfiguration 資源清單。此清單定義了一個變異准入 Webhook。每個欄位的詳細描述如下:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: ## 資源名稱
webhooks:
- name: ## 准入 Webhook 的名稱,當任何准入審查被拒絕時將顯示給使用者
  clientConfig:
    service:
      namespace: ## 准入 Webhook Pod 所在的名稱空間
      name: ## 用於連線到准入 Webhook 的服務名稱
      path: ## Webhook URL
    caBundle: ## 用於驗證 Webhook 伺服器憑證的 PEM 編碼 CA 組合
  rules: ## 描述 API 伺服器必須將哪些操作傳送到此 Webhook
  - operations:
    - ## 觸發 API 伺服器將請求傳送到此 Webhook 的特定操作(例如,建立、更新、刪除、連線)
    apiGroups:
    - ""
    apiVersions:
    - "*"
    resources:
    - ## 按名稱指定的特定資源(例如,佈署、服務、Ingress)
  failurePolicy: ## 定義如何處理存取問題或無法識別的錯誤,必須為 Ignore 或 Fail
  admissionReviewVersions: ["v1"] ## 指定接受的 AdmissionReview 物件版本
  sideEffects: ## 指示 Webhook 是否可能需要處理帶外變更
  reinvocationPolicy: ## 控制是否在對物件進行其他變異時重新呼叫變異 Webhook
  timeoutSeconds: 5 ## API 伺服器在將請求視為失敗之前等待回應的時間

內容解密:

MutatingWebhookConfiguration 資源清單定義了一個變異准入 Webhook,用於修改 API 請求。其中,webhooks 欄位定義了 Webhook 的名稱、客戶端組態、規則等。與 ValidatingWebhookConfiguration 不同的是,MutatingWebhookConfiguration 多了一個 reinvocationPolicy 欄位,用於控制是否在對物件進行其他變異時重新呼叫變異 Webhook。

圖表翻譯:

此圖表展示了 API 請求透過准入 Webhook 的流程。首先,請求會經過變異准入控制器,然後是驗證准入控制器。最後,請求會被提交給准入審查。如果審查透過,請求就會成功;否則,請求就會失敗。

准入控制最佳實踐

既然我們已經介紹了准入控制器的強大功能,以下是一些最佳實踐,以幫助您充分利用它們。

不需要關注准入外掛的順序

在早期的 Kubernetes 版本中,准入外掛的順序對於處理順序非常重要。在目前支援的 Kubernetes 版本中,透過 --enable-admission-plugins 指定為 API 伺服器旗標的准入外掛順序不再重要。然而,在准入 Webhook 的情況下,順序仍然扮演著小角色,因此瞭解請求流程非常重要。請求的准入或拒絕作為邏輯與執行,如果任何准入 Webhook 拒絕請求,則整個請求被拒絕,並向使用者傳回錯誤。

值得注意的是,變異准入控制器總是在驗證准入控制器之前執行。如果您仔細想想,這是有道理的:您可能不希望驗證將要修改的物件。圖表展示了透過准入 Webhook 的請求流程;您會看到變異准入控制器在驗證准入控制器之前執行。

Kubernetes 准入控制與授權機制深度解析

Kubernetes 的准入控制(Admission Control)與授權(Authorization)是確保叢集安全性和穩定性的關鍵機制。本文將探討這兩個領域的最佳實踐和常見挑戰,並提供具體的技術指導。

准入控制的最佳實踐

避免多重變異准入 Webhook 修改相同欄位

在組態多個變異准入 Webhook 時,必須小心避免它們修改相同的資源欄位,因為這可能導致不一致的行為。建議使用驗證准入 Webhook 來確認最終的資源清單是否符合預期。

確保變異准入 Webhook 的冪等性

變異准入 Webhook 必須是冪等的,這意味著它們必須能夠處理已經被處理過的物件,並且可能已經被修改過。

失敗處理策略

failurePolicy 欄位定義了當准入 Webhook 發生存取問題或無法辨識的錯誤時,API 伺服器應該如何處理請求。可以設定為 IgnoreFail

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: example-webhook
webhooks:
- name: example-webhook.example.com
  failurePolicy: Fail
  clientConfig:
    # 組態 clientConfig

內容解密:

此範例展示瞭如何組態 MutatingWebhookConfigurationfailurePolicy。當設定為 Fail 時,如果 Webhook 無法正常運作,請求將被拒絕。這種設定需要謹慎使用,以避免影響正常的叢集操作。

准入 Webhook 的效能最佳化

快速回應

准入 Webhook 必須快速回應,因為所有準入 Webhook 的呼叫都組態了 30 秒的逾時時間。複雜的邏輯或依賴外部系統可能會嚴重影響使用者經驗。

範圍選擇與安全性

使用 NamespaceSelector 範圍選擇

建議使用 NamespaceSelector 欄位來明確指定準入 Webhook 操作的名稱空間範圍,避免不必要的資源處理。

保護 kube-system 名稱空間

絕對不要在 kube-system 名稱空間上執行准入 Webhook 操作,因為這可能幹擾系統級服務的正常運作。

RBAC 與安全組態

鎖定準入 Webhook 組態

使用 RBAC 鎖定 MutatingWebhookConfigurationValidatingWebhookConfiguration 的建立許可權,防止未授權的存取和潛在的安全風險。

授權機制解析

Kubernetes 的授權機制發生在身份驗證之後、准入控制之前。主要的授權模組包括:

  1. Attribute-Based Access Control (ABAC):透過本地檔案組態授權策略。
  2. Role-Based Access Control (RBAC):透過 Kubernetes API 組態授權策略。
  3. Webhook:透過遠端 REST 端點處理授權請求。
  4. Node:專門為 kubelet 請求提供授權。

圖表說明:API 請求流程

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Kubernetes 准入控制與授權機制

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

圖表翻譯: 此圖展示了 Kubernetes 中 API 請求的處理流程。首先,請求經過身份驗證,接著進行授權檢查,然後進入准入控制階段,最終完成資源操作。這個流程確保了叢集的安全性和策略的一致性。

Kubernetes授權機制與GitOps佈署實踐

Kubernetes授權機制詳解

Kubernetes的授權機制是確保叢集安全性的關鍵組成部分。叢集管理員透過在API伺服器上設定--authorization-mode引數來組態授權模組。多個模組可以同時組態,並按順序檢查。與准入控制器不同,只要有一個授權模組允許請求,該請求就可以繼續進行。只有當所有模組都拒絕請求時,才會向使用者傳回錯誤。

ABAC授權模組

ABAC(屬性基礎存取控制)是一種根據屬性的授權機制。以下是一個策略定義範例,授予使用者Mary對kube-system名稱空間中的pod的唯讀存取許可權:

apiVersion: abac.authorization.kubernetes.io/v1beta1
kind: Policy
spec:
  user: mary
  resource: pods
  readonly: true
  namespace: kube-system

若Mary嘗試存取demo-app名稱空間中的pod,將被拒絕,因為她沒有存取該名稱空間中pod的許可權:

apiVersion: authorization.k8s.io/v1
kind: SubjectAccessReview
spec:
  resourceAttributes:
    verb: get
    resource: pods
    namespace: demo-app

Kubernetes提供了一組API(authorization.k8s.io)來暴露API伺服器的授權機制給外部服務,這些API非常適合用於除錯:

  • SelfSubjectAccessReview:檢查當前使用者的存取許可權
  • SubjectAccessReview:檢查任意使用者的存取許可權
  • LocalSubjectAccessReview:檢查特定名稱空間中使用者的存取許可權
  • SelfSubjectRulesReview:傳回使用者在指定名稱空間中可以執行的操作列表

使用kubectl進行授權檢查

Kubernetes內建了kubectl auth can-i命令,透過查詢相同的API來檢查使用者的存取許可權:

$ kubectl auth can-i get pods --namespace demo-app
yes

使用管理員憑證,也可以檢查其他使用者的存取許可權:

$ kubectl auth can-i get pods --namespace demo-app --as mary
yes

RBAC與Webhook授權模組

  • RBAC(角色基礎存取控制):Kubernetes的RBAC機制在第4章中有深入介紹。
  • Webhook:Webhook授權模組允許叢集管理員組態一個外部REST端點來委託授權流程。API伺服器會將SubjectAccessReview物件作為請求體的一部分傳送給Webhook應用,後者處理並傳回帶有狀態列位的物件。

授權最佳實踐

在更改叢集上的授權模組之前,請考慮以下最佳實踐:

  • 避免在多控制平面叢集中使用ABAC:由於ABAC策略需要放置在每個控制平面主機的檔案系統上並保持同步,因此不建議在多控制平面叢集中使用ABAC。同樣,Webhook模組的組態也是根據檔案和對應的旗標。
  • 避免使用Webhook模組:雖然Webhook模組功能強大,但也可能非常危險。由於每個請求都受授權流程的約束,Webhook服務的故障將對叢集造成嚴重影響。因此,除非您完全審查並熟悉Webhook服務不可用時的叢集故障模式,否則不建議使用外部授權模組。

GitOps與佈署實踐

GitOps是一種利用Git作為Kubernetes資源單一真實來源的應用佈署方式。透過將Git置於佈署流程的核心,開發人員和維運人員可以透過提交Pull Request來加速和簡化Kubernetes中的應用佈署和維運任務。

GitOps工作流程

  1. 設定GitOps代理:使用Flux等工具設定GitOps代理。
  2. 連線Git儲存函式庫:將Flux代理連線到Git儲存函式庫。
  3. 同步資源到Kubernetes叢集:將資源同步到Kubernetes叢集。
  4. 佈署應用到叢集:將應用佈署到叢集。

GitOps工具與最佳實踐

本章涵蓋了以下主題:

  • 什麼是GitOps?
  • 為什麼使用GitOps?
  • GitOps與其他佈署方法的比較
  • 模式與最佳實踐
  • GitOps工具

透過採用GitOps,開發人員可以利用與管理應用程式碼相同的工具和實踐來管理Kubernetes資源,從而簡化應用佈署和維運任務。

GitOps 深度解析:原理、優勢與實務應用

GitOps 的起源與核心概念

GitOps 是由 Weaveworks 團隊所推廣的概念,其基礎源自於在生產環境中執行 Kubernetes 的豐富經驗。GitOps 將軟體開發生命週期的理念應用於維運管理,使 Git 儲存函式庫成為真理的唯一來源,而叢集狀態則與 Git 儲存函式庫保持同步。例如,當更新 Kubernetes Deployment 清單時,這些組態變更會自動反映在 Git 中的叢集狀態。

這種方法簡化了多叢集的管理,確保一致性並避免組態漂移。GitOps 允許以宣告式的方式描述多個環境的叢集,並驅動叢集維持在所期望的狀態。GitOps 的實踐可以同時應用於應用程式交付和維運,為開發者提供了一套共通的工具鏈。

GitOps 的核心原則

根據 OpenGitOps Project 定義的四項核心原則,建構 GitOps 工作流程時應考慮以下要素:

  1. 宣告式組態
    所有組態以宣告式的 YAML 檔案儲存在 Git 中,確保叢集組態的唯一真實來源。

  2. 版本化組態
    所有組態儲存在 Git 中,所有變更均被追蹤和版本化,便於稽核變更記錄並進行回復操作。

  3. 不可變組態
    組態一旦變更便不可修改,確保叢集狀態的一致性。

  4. 持續狀態協調
    叢集狀態持續與 Git 中定義的狀態進行協調,確保叢集始終處於一致狀態。

為何選擇 GitOps?

GitOps 是管理 Kubernetes 叢集的極佳方式,不僅可用於佈署應用程式,還能管理叢集和應用程式組態。在討論其眾多優勢之前,先來看看傳統的應用程式佈署和組態方式。

傳統佈署流程的問題

傳統佈署流程涉及多個手動步驟,如更新應用程式碼、建置新的容器映像、推播至容器登入檔、更新 Kubernetes 清單並將變更套用到叢集。這一過程不僅耗時,而且容易出錯。此外,當使用者直接對 Kubernetes 資源進行變更時,可能會導致組態漂移。隨著應用程式和叢集數量的增加,這種複雜性進一步加劇。

GitOps 帶來的解決方案

GitOps 提供以下關鍵優勢來解決上述問題:

  1. 宣告式組態
    組態以 YAML 檔案形式儲存在 Git 中,提供單一真實來源,便於稽核變更並熟悉開發者的工作流程。

  2. 版本控制
    Git 儲存函式庫支援不可變性和版本歷史,使得變更追蹤變得簡單,並能輕鬆比較歷史變更。

  3. 持續協調
    叢集狀態與 Git 中定義的狀態持續協調,支援自動同步和簡單的回復機制,確保叢集的一致性。

  4. 安全性增強
    使用 Git 管理 Kubernetes 應用程式佈署,可獲得完整的變更稽核日誌,所有變更均透過 Git 儲存函式庫進行,並由 GitOps 代理自動協調直接對 Kubernetes 資源的變更,提供完整的操作稽核軌跡並增強環境安全性。

GitOps 儲存函式庫結構規劃

在實施 GitOps 時,如何組織 Git 儲存函式庫結構是一個常見問題。常見的四種儲存函式庫結構策略包括:

  1. 單一 Monorepo
    將所有 Kubernetes 清單和應用程式碼儲存在單一儲存函式庫中。這種方法簡單直接,但在公司規模擴大時會變得難以管理,且無法實作關注點分離。