Gatekeeper 作為 Kubernetes 原生的策略引擎,有效提升叢集安全性。本文從 Helm 安裝步驟開始,詳細說明版本選擇、引數設定與 Namespace 組態。接著,透過建立測試策略與 Namespace,驗證 Gatekeeper 的運作,並解析 Webhook 的 fail open/close 策略與 Namespace 豁免設定。文章也提供自動化安裝指令碼,簡化佈署流程,並探討 Gatekeeper 的未來發展趨勢,例如多叢集管理、更豐富的策略函式庫以及與其他安全工具的整合,以滿足日益增長的 Kubernetes 安全需求。

Gatekeeper 安裝與組態詳解

Gatekeeper 是一款與 Kubernetes 叢集緊密整合的策略執行工具,用於確保叢集資源符合組織的安全與合規要求。本文將詳細介紹 Gatekeeper 的安裝流程、驗證方法以及 Namespaces 忽略機制的組態。

Gatekeeper 安裝

Gatekeeper 的安裝過程相對簡單。首先,假設目前使用的 Kubernetes 版本在支援範圍內,根據 Kubernetes Supported Versions 政策,Gatekeeper v3.15.0 被安裝在 Kubernetes 1.28.3 叢集中。安裝完成後,系統會在 gatekeeper-system Namespace 中建立兩個 Deployment 資源:

# 檢查 Deployment 資源
$ kubectl -n gatekeeper-system get deployment
NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
gatekeeper-audit                1/1     1            1           24h
gatekeeper-controller-manager   1/1     1            1           24h

# 檢查 Pod 資源
$ kubectl -n gatekeeper-system get po
NAME                                             READY   STATUS    RESTARTS   AGE
gatekeeper-audit-7c7494fc77-l4mr2                1/1     Running   0          24h
gatekeeper-controller-manager-78b4bdc4bf-46fc7   1/1     Running   0          24h

安裝後檢查

安裝完成後,需要進行一系列檢查以確保 Gatekeeper 正確執行。這些檢查包括:

  1. 日誌審查:檢查 Gatekeeper 各元件的日誌輸出,確保無異常錯誤。
  2. CRD 檢查:確認 Gatekeeper 安裝的自定義資源定義(CRDs)正確建立。
  3. 系統資源檢查:檢查 gatekeeper-system Namespace 下的資源狀態。

策略測試

為了驗證 Gatekeeper 的功能,需要安裝一個拒絕所有 Pod 建立的策略,並進行測試:

# 安裝拒絕所有 Pod 的 Constraint Template
$ kubectl apply -f ./examples/validating/deny/constraint-templates/0-denyall.yaml
constrainttemplate.templates.gatekeeper.sh/k8sdenyall created

# 安裝拒絕所有 Pod 的 Constraint
$ kubectl apply -f ./examples/validating/deny/constraints/0-denyall-pods.yaml
k8sdenyall.constraints.gatekeeper.sh/deny-all-pods created

# 建立測試 Namespace
$ kubectl apply -f ./examples/validating/deny/0-ns.yaml
namespace/policy-test created

# 試圖在測試 Namespace 中建立 Pod
$ kubectl -n policy-test apply -f ./examples/validating/deny/1-test-pod.yaml
Error from server (Forbidden): error when creating "1-test-pod.yaml":
admission webhook "validation.gatekeeper.sh" denied the request:
[deny-all-pods] INPUT: {"parameters": {}, "review": {"dryRun": false, "kind":
{"group": "", "kind": "Pod", "version": "v1"}, "name": "test-pod",
"namespace": "policy-test", ...

程式碼解析

上述命令展示瞭如何使用 Gatekeeper 的 Constraint 和 Constraint Template 來強制執行策略。以下是關鍵步驟的解析:

  1. Constraint Template 建立:定義了一個通用範本 k8sdenyall,用於描述策略邏輯。
  2. Constraint 建立:根據範本建立具體的約束條件 deny-all-pods
  3. 測試驗證:在特定 Namespace 中嘗試建立 Pod 時,Gatekeeper 的驗證 Webhook 攔截了該請求並傳回錯誤。

Webhook 組態詳解

Gatekeeper 安裝過程中會建立三個 Webhook 組態,其中兩個是驗證 Webhook,一個是變更 Webhook。具體組態如下:

# 列出驗證 Webhook 組態
$ kubectl get validatingwebhookconfigurations gatekeeper-validating-webhook-configuration
NAME                                    WEBHOOKS   AGE
gatekeeper-validating-webhook-configuration   2       3h10m

# 列出變更 Webhook 組態
$ kubectl get mutatingwebhookconfiguration gatekeeper-mutating-webhook-configuration
NAME                                   WEBHOOKS   AGE
gatekeeper-mutating-webhook-configuration   1       3h11m

Webhook 的失敗策略

其中兩個 Webhook 設定為「忽略失敗」(fail open),即當 Webhook 服務無法回應時,仍允許資源建立。僅有檢查 Namespace 是否可被忽略的 Webhook 設定為「失敗關閉」(fail closed)。


#### 此圖示顯示 Webhook 組態邏輯
```mermaid
graph LR
    A[資源請求] --> B{Webhook 驗證}
    B -->|驗證透過| C[資源建立]
    B -->|驗證失敗| D[請求拒絕]
    B -->|Webhook 失敗| E[失敗策略處理]
    E -->|Fail Open| C
    E -->|Fail Closed| D

圖表翻譯: 此圖展示了資源請求經過 Webhook 驗證的流程。當資源請求到達時,首先經過 Webhook 的驗證。如果驗證透過,資源將被建立;如果驗證失敗,請求將被拒絕。若 Webhook 本身發生故障,則根據設定的失敗策略進行處理。若設定為「Fail Open」,則允許資源建立;若設定為「Fail Closed」,則拒絕請求。

Namespaces 忽略機制

在實際應用中,通常需要將某些系統級別的 Namespaces(如 kube-system)排除在 Gatekeeper 的策略檢查之外。Gatekeeper 提供了一套機制來實作這一點。

設定豁免 Namespaces

在安裝 Gatekeeper 時,可以透過 Helm 的組態引數指定豁免的 Namespaces:

# Helm 安裝引數設定豁免 Namespaces
--set "controllerManager.exemptNamespaces={kube-system}"

對應的 Gatekeeper controller manager 引數設定如下:

containers:
- args:
  ...
  - --exempt-namespace=gatekeeper-system
  ...
  - --exempt-namespace=kube-system

程式碼解析

上述組態展示瞭如何透過 Helm 和 Gatekeeper 的引數來設定豁免 Namespaces。以下是詳細解析:

  1. Helm 組態:在安裝 Gatekeeper 時,使用 --set 引數指定需要豁免的 Namespaces。
  2. Controller Manager 引數:Gatekeeper 的 controller manager 將根據這些引陣列態豁免清單。

操作範例

當某個 Namespace 被設定為豁免後,可以為其新增特定的標籤,使其被 Gatekeeper 忽略:

# 為豁免 Namespace 新增標籤
$ kubectl label ns kube-system admission.gatekeeper.sh/ignore=true
namespace/kube-system labeled

自動化安裝指令碼

為了簡化 Gatekeeper 的佈署流程,可以將安裝命令包裝在 shell 指令碼和 Makefile 中,實作一鍵安裝與組態:

#!/usr/bin/env bash
# 安裝 Gatekeeper 的 shell 指令碼
set -e
trap 'catch $? $LINENO' ERR

catch() {
    if [ "$1" != "0" ]; then
        echo "Error $1 occurred on $2"
    fi
}

KUBECTL="kubectl"

# Helm 安裝 Gatekeeper
helm install gatekeeper ...

# 組態豁免 Namespace
$KUBECTL label ns kube-system admission.gatekeeper.sh/ignore=true

指令碼解析

上述指令碼展示瞭如何自動化 Gatekeeper 的安裝與初始組態。主要步驟包括:

  1. 錯誤處理機制:透過 set -etrap 確保指令碼在遇到錯誤時終止並輸出相關資訊。
  2. Helm 安裝:呼叫 Helm 命令安裝 Gatekeeper。
  3. 後續組態:為指定的豁免 Namespace 新增忽略標籤。

探討

隨著 Kubernetes 生態的不斷發展,Gatekeeper 未來可能朝著以下幾個方向演進:

  1. 多叢集管理支援:增強對多個 Kubernetes 叢集的集中管理能力。
  2. 更豐富的策略函式庫:提供更多預設的安全與合規策略,降低使用門檻。
  3. 與其他安全工具整合:加強與現有安全工具鏈的整合,如影像掃描、漏洞偵測等。

這些發展將進一步鞏固 Gatekeeper 在 Kubernetes 安全領域的重要地位。

Gatekeeper 安裝與設定

Gatekeeper 是一個強大的 Kubernetes 安全工具,用於執行和管理叢集中的安全策略。在本章中,我們將探討如何安裝、組態和使用 Gatekeeper。

使用 Helm 安裝 Gatekeeper

Helm 簡化了 Gatekeeper 的安裝過程。以下命令展示瞭如何使用 Helm 安裝 Gatekeeper:

helm install gatekeeper gatekeeper/gatekeeper \
--namespace gatekeeper-system --create-namespace \
--set logDenies=true --set replicas=1 --set version=v3.15.0 \
--set "controllerManager.exemptNamespaces={kube-system}"

內容解密:

  • helm install gatekeeper gatekeeper/gatekeeper:使用 Helm 安裝 Gatekeeper。
  • --namespace gatekeeper-system --create-namespace:在 gatekeeper-system 名稱空間中安裝 Gatekeeper,如果該名稱空間不存在,則建立它。
  • --set logDenies=true:啟用記錄拒絕請求的日誌功能。
  • --set replicas=1:設定 Gatekeeper 的副本數量為 1。
  • --set version=v3.15.0:指定要安裝的 Gatekeeper 版本為 v3.15.0
  • --set "controllerManager.exemptNamespaces={kube-system}":設定豁免的名稱空間為 kube-system

組態 kube-system 名稱空間

為了確保 kube-system 名稱空間被 Gatekeeper 忽略,需要為其新增特定的標籤:

LABEL=$(${KUBECTL} get ns kube-system -oyaml | { grep admission.gatekeeper.sh/ignore || true; })
if [[ "$LABEL" == "" ]]
then
  ${KUBECTL} label ns kube-system admission.gatekeeper.sh/ignore=jimmy
  ${KUBECTL} get ns kube-system -oyaml | grep admission.gatekeeper.sh/ignore
fi

內容解密:

  • ${KUBECTL} get ns kube-system -oyaml:取得 kube-system 名稱空間的 YAML 組態。
  • grep admission.gatekeeper.sh/ignore:檢查是否存在 admission.gatekeeper.sh/ignore 標籤。
  • 如果標籤不存在,則使用 ${KUBECTL} label ns kube-system admission.gatekeeper.sh/ignore=jimmy 新增標籤。

Gatekeeper 組態功能

Gatekeeper 提供了一個組態功能(目前仍在 alpha 階段),允許使用者排除某些名稱空間、同步 Kubernetes 資料以及組態除錯跟蹤。以下是一個示例組態資源:

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: "gatekeeper-system"
spec:
  match:
  - excludedNamespaces: ["policy-test"]
    processes: ["*"]

內容解密:

  • apiVersion: config.gatekeeper.sh/v1alpha1:指定組態資源的 API 版本。
  • kind: Config:定義資源型別為組態。
  • metadata.namemetadata.namespace:指定組態資源的名稱和名稱空間。
  • spec.match.excludedNamespaces:指定要排除的名稱空間列表。
  • spec.match.processes:指定要排除的處理過程,* 表示所有過程。

解除安裝 Gatekeeper

解除安裝 Gatekeeper 需要使用 Helm 和一些額外的步驟來刪除相關的 CRD 和名稱空間。以下是一個示例指令碼:

#!/usr/bin/env bash
# error handling
set -e
trap 'catch $? $LINENO' ERR
catch() {
  if [ "$1" != "0" ]; then
    echo "Error $1 occurred on $2"
  fi
}
KUBECTL="kubectl"
helm uninstall gatekeeper
${KUBECTL} delete crd -l gatekeeper.sh/system=yes
${KUBECTL} delete ns gatekeeper-system
${KUBECTL} label ns kube-system admission.gatekeeper.sh/ignore-

內容解密:

  • helm uninstall gatekeeper:解除安裝 Gatekeeper Helm 發布版本。
  • ${KUBECTL} delete crd -l gatekeeper.sh/system=yes:刪除由 Gatekeeper 安裝的 CRD。
  • ${KUBECTL} delete ns gatekeeper-system:刪除 gatekeeper-system 名稱空間。
  • ${KUBECTL} label ns kube-system admission.gatekeeper.sh/ignore-:移除 kube-system 名稱空間上的 admission.gatekeeper.sh/ignore 標籤。

OPA 約束框架

Gatekeeper 在內部執行 OPA,但不直接暴露 OPA。要與 OPA 介面,需要建立至少兩個資源:ConstraintTemplateConstraint。這些資源的構建根據 OPA 約束框架(OPA CF)。

ConstraintTemplate 和 Constraint

  • ConstraintTemplate 用於宣告新的約束型別,並包含策略 Rego。
  • Constraint 是對系統必須滿足的要求的宣告。

策略與執行點

Gatekeeper 使用 OPA CF 定義了多個元件,包括:

  • 約束範本(ConstraintTemplate)
  • 約束(Constraint)
  • 執行點(Enforcement points)
  • 目標(Targets)

這些元件共同工作,以確保 Kubernetes 資源符合定義的策略。