在 Kubernetes 環境中佈署策略即程式碼工具已成為確保叢集安全和穩定性的重要手段。MagTape 作為一款根據 OPA 的開源工具,提供了一個便捷的策略管理方案。然而,由於專案版本較舊,直接佈署於新版 Kubernetes 叢集時,可能會遇到相容性問題。本文將逐步解析 MagTape 的安裝流程,並提供解決方案,確保在現代 Kubernetes 叢集中順利佈署和使用 MagTape。首先,需要下載官方提供的安裝 YAML 檔案,並針對當前 Kubernetes 版本進行調整,例如更新 PodDisruptionBudget 的 API 版本、OPA 和 kube-mgmt 容器映像等。此外,還需特別注意 ValidatingWebhookConfiguration 的設定,確保其能正確攔截和驗證 Kubernetes 資源的變更請求。透過設定 Namespace 標籤,可以精確控制 MagTape 策略的生效範圍,實作更細粒度的策略管理。最後,透過檢查 MagTape Pod 狀態和日誌,可以驗證安裝是否成功,並進一步瞭解其內部運作機制。

在 Kubernetes 環境中安裝與解除安裝 MagTape

MagTape 可以透過以下安裝 YAML 檔案輕鬆安裝和解除安裝:

下載安裝 YAML 檔案

$ curl -O \
https://raw.githubusercontent.com/tmobile/magtape/v2.4.0/deploy/install.yaml

雖然在專案的 README.md 中可以找到安裝和解除安裝 MagTape 的說明,但筆者選擇下載安裝 manifest 並根據需求進行修改。

評估 MagTape 的適用性

MagTape 是一個較舊的專案,最近一次更新是在兩年多前。根據第1章中提到的 PaC(Policy as Code)解決方案選擇標準,這應該是讀者立即警惕的紅旗,筆者也同意這種看法。事實上,在從 Docker Hub 提取最新的 MagTape 容器後,筆者執行了 docker scout quickview 命令來瞭解這個過時容器映像中的 CVE(Common Vulnerabilities and Exposures)情況。結果如下:

# Docker scout quickview of MagTape container image
$ docker scout quickview tmobile/magtape:v2.4.0
✓ Image stored for indexing
✓ Indexed 93 packages
Target │ tmobile/magtape:v2.4.0 │ 1C 33H 20M 1L
digest │ e545b933cb3c │
Base image │ python:3-alpine │ 1C 9H 4M 0L
Refreshed base image │ python:3-alpine │ 0C 1H 1M 0L
│ │ -1 -8 -3
Updated base image │ python:3.9-alpine3.18 │ 0C 2H 2M 0L
│ │ -1 -7 -2

內容解密:

上述輸出顯示了多個 CVE,包括一些具有高嚴重性和關鍵嚴重性的漏洞。筆者對此並不感到意外,因為這是一個過時的專案。

安裝過程中的問題與解決方案

在安裝過程中,筆者遇到了幾個問題,這些問題很可能是由於專案的年代久遠所致。首先遇到的錯誤是由於 PodDisruptionBudget (PDB) 資源的 API 版本過時;筆者當時執行的是 Kubernetes 1.29.1 叢集:

# Outdated API version error
error: resource mapping not found for name: "magtape-pdb" namespace:
"magtape-system" from "install.yaml": no matches for kind "PodDisruptionBudget"
in version "policy/v1beta1" ensure CRDs are installed first

為瞭解決這個問題,筆者編輯了下載的安裝 YAML 檔案,將 PDB 的版本更新為 v1。然後,更新了 OPA 和 kube-mgmt 容器映像,分別使用 openpolicyagent/opa:0.62.1-staticopenpolicyagent/kube-mgmt:8.5.5。此外,還在 kube-mgmt 容器上設定了 --namespaces=magtape-system,以便 kube-mgmt 能夠找到並擷取策略 ConfigMap 資源。最後,將 ValidatingWebhookConfiguration 規則中的 apiVersions 值設為 v1,如下所示:

# ValidatingWebhookConfiguration rules
rules:
- apiGroups:
  - '*'
  apiVersions:
  - v1
  operations:
  - CREATE
  - UPDATE
  resources:
  - deployments
  - statefulsets
  - daemonsets
  - pods
  - poddisruptionbudgets

內容解密:

apiVersions 必須設定為 v1 以支援明確定義多個資源。在設定 ValidatingWebhookConfiguration 規則時,需要注意當明確定義多個資源時如何指定 apiVersions

設定 ValidatingWebhookConfiguration 的最佳實踐

在設定 ValidatingWebhookConfiguration 時,需要注意以下幾點:

  • 明確定義多個資源時,不可以使用 apiVersion 的萬用字元(*)。
  • 如果只定義一個資源(如 pods),則可以使用 apiVersion 的萬用字元。
  • 當所有值都使用萬用字元時(apiGroupsapiVersionsresources),規則將適用於所有資源。
# Explicitly defined multiple resources do not work with an apiVersion wildcard value
rules:
- operations: ["CREATE", "UPDATE"]
  apiGroups: ["*"]
  apiVersions: ["*"]
  resources: ["pods","deployments","services"]

# Pods alone work with an apiVersion wildcard value
rules:
- operations: ["CREATE", "UPDATE"]
  apiGroups: ["*"]
  apiVersions: ["*"]
  resources: ["pods"]

# All wildcard values (apiGroups, apiVersions, resources) work
rules:
- operations: ["CREATE", "UPDATE"]
  apiGroups: ["*"]
  apiVersions: ["*"]
  resources: ["*"]

# Explicitly defined multiple resources work with an apiVersion v1 value
rules:
- operations: ["CREATE", "UPDATE"]
  apiGroups: ["*"]
  apiVersions: ["v1"]
  resources: ["pods","deployments","services"]

疑難排解 ValidatingWebhookConfiguration 的技巧:

在對 ValidatingWebhookConfiguration 進行疑難排解時,尤其是當 webhook 未按預期觸發時,首先要檢查的三個問題是: • 不正確的選擇加入或離開 Namespace 標籤。 • 資源未包含在規則中。 • apiVersions 與明確定義的多個資源不一致。

成功安裝 MagTape

經過上述修改後,MagTape 成功安裝:

# Use downloaded and edited install.yaml to install MagTape
$ make up
./up.sh 2>&1
namespace/magtape-system created
clusterrole.rbac.authorization.k8s.io/magtape-write created
clusterrole.rbac.authorization.k8s.io/magtape-read created
clusterrolebinding.rbac.authorization.k8s.io/magtape-write-crb created
clusterrolebinding.rbac.authorization.k8s.io/magtape-read-crb created
role.rbac.authorization.k8s.io/magtape-ops created
rolebinding.rbac.authorization.k8s.io/magtape-ops-rb created
serviceaccount/magtape-sa created
configmap/magtape-env created
configmap/magtape-vwc-template created
configmap/magtape-opa-default-main created
configmap/magtape-opa-entrypoint created
service/magtape-svc created
poddisruptionbudget.policy/magtape-pdb created
deployment.apps/magtape created
horizontalpodautoscaler.autoscaling/magtape created
configmap/policy-emptydir-check created
configmap/policy-host-path-check created
configmap/policy-host-port-check created

MagTape 安裝流程圖示

  graph LR;
    A[下載 install.yaml] --> B[編輯 install.yaml];
    B --> C[更新 PDB 版本];
    C --> D[更新 OPA 和 kube-mgmt];
    D --> E[設定 ValidatingWebhookConfiguration];
    E --> F[執行 make up 安裝 MagTape];

圖表翻譯: 此圖示呈現了 MagTape 的安裝流程,包括下載和編輯安裝檔案、更新相關組態以及執行安裝命令等步驟。

本章重點回顧:
  • MagTape 的安裝與解除安裝方法。
  • 在現代 Kubernetes 環境中安裝 MagTape 可能遇到的問題及解決方案。
  • 設定 ValidatingWebhookConfiguration 的最佳實踐。
  • 對 MagTape 的思考。

本章詳細介紹瞭如何在 Kubernetes 環境中安裝和組態 MagTape,並針對安裝過程中可能遇到的問題提供瞭解決方案。透過這些內容,讀者可以更好地理解 MagTape 的工作原理和應用場景,為實際使用提供參考。

MagTape 安裝與驗證流程詳解

在完成 MagTape 的安裝後,進行了一系列檢查以確保其正常運作。首先,將 MagTape 安裝到 minikube 叢集中,並設定 replica count 為 1,以方便測試和除錯。

編輯 MagTape Deployment 資源

透過直接編輯 MagTape Deployment 資源,將 spec.replicas 設定為 1,以控制執行中的 Pod 數量。

$ kubectl -n magtape-system edit deployment magtape

這種方式可以即時調整執行中的副本數量,便於觀察日誌和進行測試。

檢查 MagTape Pod 狀態

確認 MagTape Pod 是否正常執行:

$ kubectl -n magtape-system get pods
NAME                     READY   STATUS    RESTARTS   AGE
magtape-5b45bc79df-vfmc2   1/1     Running   0          4m47s

此步驟確保 MagTape 已正確佈署並處於執行狀態。

ValidatingWebhookConfiguration 設定解析

MagTape 安裝過程中建立了一個 ValidatingWebhookConfiguration,其設定如下:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  labels:
    app: magtape
  name: magtape-webhook
webhooks:
- admissionReviewVersions:
  - v1
  clientConfig:
    caBundle: LS0...
    service:
      name: magtape-svc
      namespace: magtape-system
      path: /
      port: 443
  failurePolicy: Fail
  matchPolicy: Equivalent
  name: magtape.webhook.k8s.t-mobile.com
  namespaceSelector:
    matchLabels:
      k8s.t-mobile.com/magtape: enabled
  rules:
  - apiGroups:
    - '*'
    apiVersions:
    - 'v1'
    operations:
    - CREATE
    - UPDATE
    resources:
    - deployments
    - statefulsets
    - daemonsets
    - pods
    - poddisruptionbudgets
    scope: '*'
  sideEffects: None
  timeoutSeconds: 10

內容解密:

此設定定義了一個 webhook,用於攔截特定資源的操作請求(如 CREATE 和 UPDATE),並將其送至 MagTape 服務進行驗證。主要監控的資源包括:

  • deployments
  • statefulsets
  • daemonsets
  • pods
  • poddisruptionbudgets

這些資源的變更會被 webhook 攔截,並根據設定的策略進行檢查。

設定 Namespace 以啟用 MagTape 驗證

建立一個新的 Namespace policy-test,並為其加上標籤,使其納入 MagTape 的驗證範圍:

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
  name: policy-test
EOF

$ kubectl label ns policy-test k8s.t-mobile.com/magtape=enabled

檢查已標記的 Namespace:

$ kubectl get namespaces -l k8s.t-mobile.com/magtape=enabled
NAME         STATUS   AGE
policy-test   Active   2d5h

MagTape 使用「選擇加入」(opt-in)模式,即只有帶有特定標籤的 Namespace 才會受到策略控制。

MagTape Pod 組成元件解析

MagTape Pod 中包含四個容器:

  1. MagTape init(init-container):負責處理 TLS 設定,確保 Kubernetes API server 能夠與 webhook 服務進行 HTTPS 通訊。
  2. MagTape:主要的應用容器。
  3. OPA(Open Policy Agent):用於執行策略評估。
  4. kube-mgmt:負責將 ConfigMap 中的策略載入 OPA。

MagTape init 日誌分析:

$ kubectl -n magtape-system logs -l app=magtape -c magtape-init
[2024-03-09 06:33:25,549] INFO: Waiting for certificate approval
[2024-03-09 06:33:25,550] INFO: Found approved certificate
[2024-03-09 06:33:25,551] INFO: Creating secret "magtape-tls" in namespace "magtape-system"

內容解密:

MagTape init 容器負責生成和管理 TLS 證書,建立必要的 secret 以支援 webhook 的 HTTPS 通訊。

OPA 策略載入與驗證

透過 kube-mgmt 容器,將定義在 ConfigMap 中的策略載入 OPA。例如:

kind: ConfigMap
metadata:
  annotations:
    openpolicyagent.org/policy-status: '{"status":"ok"}'
  labels:
    app: opa
    openpolicyagent.org/policy: rego
  name: magtape-opa-entrypoint
  namespace: magtape-system
data:
  magtape.rego: |-
    package magtape
    
    decisions[{"policy": p, "reasons": reasons}] {
      data.kubernetes.admission[p].matches
      reasons := data.kubernetes.admission[p].deny
    }

內容解密:

此 ConfigMap 定義了 OPA 的策略入口點,用於彙總各項策略的檢查結果。decisions 陣列包含了所有匹配的策略及其對應的稽核結果。

使用 Debugger Pod 查詢 OPA 狀態

執行一個 debugger Pod 以查詢 OPA 的狀態:

$ kubectl -n magtape-system run -it debugger \
--image jimmyraywv/debugger:v0.1.0 --restart=Never

/ # curl -k https://10.244.0.10:8443/v1/data/magtape
{"result":{"decisions":[]}}

內容解密:

此命令查詢 OPA 中的 magtape 策略狀態,結果顯示目前沒有待決策的策略。

  1. 多叢集支援:研究 MagTape 在多叢集環境下的佈署與管理。
  2. 策略最佳化:根據實際需求調整和最佳化 OPA 策略,提高稽核效率。
  3. 整合其他工具:探討將 MagTape 與其他 Kubernetes 生態工具(如 Gatekeeper)的整合方案。

透過這些改進,可以進一步提升 MagTape 在 Kubernetes 環境中的應用價值。