jsPolicy 是一款根據 JavaScript 的 Kubernetes 策略引擎,允許開發者使用 JavaScript 編寫自定義策略,並透過 Webhook 將其整合到 Kubernetes 叢集中。本文將詳細介紹 jsPolicy 的安裝流程,包含 Helm 佈署、驗證步驟以及相關的 Webhook 組態解析。同時,也將探討如何使用 kubectl 檢視 jsPolicy 的執行狀態,以及如何透過 Helm 和自定義指令碼進行解除安裝和清理工作。此外,本文還會介紹 jsPolicy 的策略管理機制,包含內嵌式和套件式策略的建立、應用和最佳實踐,並展望 jsPolicy 未來的發展方向,例如更精細的策略控制和更完善的測試工具整合。

jsPolicy 安裝與驗證

在撰寫本文時,jsPolicy 尚未支援 Linux/ARM64 架構。由於主要使用的是 ARM64 M2 MacBook Pro 和 minikube,因此不得不切換到較舊的根據 Intel 的機器來執行 jsPolicy。

安裝 jsPolicy

執行前述的安裝指令碼後,輸出結果如下:

# 安裝 jsPolicy 的 make 命令
$ make up
./up.sh
NAME: jspolicy
LAST DEPLOYED: Sat Mar 9 18:25:22 2024
NAMESPACE: jspolicy
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thank you for installing jspolicy.
Your release is named jspolicy.
To learn more about the release, try:
$ helm status jspolicy -n jspolicy
$ helm get all jspolicy -n jspolicy
Learn more about using jsPolicy here: https://github.com/loft-sh/jspolicy
namespace/jspolicy labeled
jspolicy-ignore: ignore
namespace/kube-system labeled
jspolicy-ignore: ignore

安裝驗證

安裝後,使用以下 kubectl 命令來檢查 jsPolicy 是否正確執行:

# 檢查 jsPolicy 的 Deployments 和 Pods
$ kubectl -n jspolicy get all
NAME                          READY   STATUS    RESTARTS   AGE
pod/jspolicy-6c695f6bbf-2bpw4 1/1     Running   0          24s
...
NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/jspolicy     1/1     1            1           24s
...

檢視 jsPolicy Controller 日誌

# 檢視 jsPolicy controller 日誌
$ kubectl logs jspolicy-6c695f6bbf-zqnzs
I0607 02:47:18.097502       1 deleg.go:121] controller-runtime: metrics: Metrics server is starting to listen addr :8080
I0607 02:47:18.113062       1 logr.go:249] controller-runtime: webhook: path /policy/: Registering webhook
I0607 02:47:18.113281       1 logr.go:249] controller-runtime: webhook: path /crds: Registering webhook
I0607 02:47:18.113399       1 deleg.go:121] setup: starting manager
I0607 02:47:18.113478       1 logr.go:249] controller-runtime: webhook: webhooks: Starting webhook server

安裝的 CRDs

在安裝過程中,jsPolicy 安裝了五個 Kubernetes CRDs:

# 由 jsPolicy 安裝的 CRDs
$ kubectl get crd
NAME                                      CREATED AT
clusterpolicyreports.wgpolicyk8s.io       2023-06-05T18:00:06Z
jspolicies.policy.jspolicy.com            2023-06-05T18:00:06Z
jspolicybundles.policy.jspolicy.com       2023-06-05T18:00:06Z
jspolicyviolations.policy.jspolicy.com    2023-06-05T18:00:06Z
policyreports.wgpolicyk8s.io              2023-06-05T18:00:06Z

Webhook 組態

在初始安裝期間,jsPolicy 安裝了一個 Kubernetes webhook 組態,該組態將呼叫傳送到 jsPolicy 控制器的 /crds 端點。此 webhook 組態為僅對由 jsPolicy CRDs 建立的 policy.jspolicy.com Kubernetes API 群組中的資源進行 CREATE 和 UPDATE 操作時生效:

# 用於接收策略的 CRD webhook 組態
service:
  name: jspolicy
  namespace: jspolicy
  path: /crds
  port: 443
failurePolicy: Fail
matchPolicy: Equivalent
name: jspolicy.jspolicy.com
namespaceSelector: {}
objectSelector: {}
rules:
  - apiGroups:
      - policy.jspolicy.com
    apiVersions:
      - v1beta1
    operations:
      - CREATE
      - UPDATE
    resources:
      - '*'
    scope: '*'

這個 webhook 組態的目的是處理 jsPolicy 策略,並準備(編譯、捆綁、編碼和壓縮)它們以在 Kubernetes 群集中使用。

策略 Webhook 組態

與之前的 Kubernetes PaC 解決方案不同,jsPolicy 為每個成功匯入的策略資源註冊 webhook。圖 9-1 說明瞭這個概念:

圖表翻譯:

此圖示展示了多個根據策略的 webhook 組態。每個策略都有獨立的 webhook 組態,但都指向相同的策略服務基本 URL /policy,並在服務路徑組態元素的最後一個路徑段中包含策略名稱。

  graph LR;
    A[多個策略] -->|註冊 webhook|> B[jsPolicy Webhook 管理器];
    B --> C[不同的 webhook 組態];
    C --> D[相同的服務 URL /policy];

已匯入的策略

以下輸出列出了五個由 jsPolicy 匯入的策略:

# 五個已匯入的策略
$ kubectl get jspolicies -oname
jspolicy.policy.jspolicy.com/copy-namespace-annotations.example.com
jspolicy.policy.jspolicy.com/copy-namespace-annotations2.example.com
jspolicy.policy.jspolicy.com/copy-namespace-labels.jimmyray.io
jspolicy.policy.jspolicy.com/dont-create-me.jimmyray.io
jspolicy.policy.jspolicy.com/npol.ns.jimmyray.io

這些策略的型別包括:

  • Mutating(變異型):三個
  • Validating(驗證型):一個
  • Controller(控制器型):一個

在這五個已匯入的策略中,只有四個實際使用了 webhook 組態。控制器型策略根據叢集事件,不參與 Kubernetes API 伺服器請求流程,因此不使用 webhook 組態。

相關的 Webhook 組態

以下列出了變異型和驗證型 webhook 組態,顯示了參與 Kubernetes API 伺服器請求流程的策略與其各自的 webhook 組態之間的一對一對應關係:

# 相關的 webhook 組態列表(省略具體內容)

隨著 Kubernetes 環境的日益複雜,對策略管理的需求也將不斷增長。jsPolicy 的這種靈活架構使其能夠適應不斷變化的需求,為未來的發展提供了堅實的基礎。開發者可以根據具體需求,編寫多個 webhook 組態,以實作對不同資源和操作的精細控制。

Kubernetes 中的 jsPolicy 安裝與策略管理詳解

jsPolicy 安裝與驗證

jsPolicy 提供簡便的安裝與管理方式,主要透過 Helm 進行佈署。首先,我們需要了解安裝後的驗證步驟,以確保 jsPolicy 正確執行於 Kubernetes 叢集。

驗證 Webhook 組態

安裝完成後,可以使用以下指令檢查 mutating 和 validating webhook 組態:

# 取得 mutating webhook 組態列表
$ kubectl get mutatingwebhookconfigurations
NAME                                  WEBHOOKS   AGE
copy-namespace-annotations.example.com-ifdea   1          20m
copy-namespace-annotations2.example.com-gjnmi  1          20m
copy-namespace-labels.jimmyray.io-utkfd        1          20m

# 取得 validating webhook 組態列表
$ kubectl get validatingwebhookconfigurations
NAME                                  WEBHOOKS   AGE
dont-create-me.jimmyray.io-xexyy       1          22m
jspolicy                               1          25m

這些輸出結果顯示了目前叢集中生效的 webhook 組態數量與存活時間。透過這些資訊,可以確認 jsPolicy 是否正確建立所需的 webhook 組態。

詳細組態解析

以下是一個具體的 ValidatingWebhookConfiguration 範例,展示了 jsPolicy 如何將策略應用於 Kubernetes 資源:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: deny-specific-container-image.example.com-faqlb
  ownerReferences:
  - apiVersion: policy.jspolicy.com/v1beta1
    controller: true
    kind: JsPolicy
    name: deny-specific-container-image.example.com
    uid: 2ee42f1e-488b-4a99-bdfe-3c5714780e30
  resourceVersion: "6303"
  uid: 75008e80-7b8d-4a45-97b3-e30766c7b843
webhooks:
- admissionReviewVersions:
  - v1
  clientConfig:
    caBundle: LS0tLS1...
    service:
      name: jspolicy
      namespace: jspolicy
      path: /policy/deny-specific-container-image.example.com
      port: 443
  failurePolicy: Fail
  matchPolicy: Equivalent
  name: deny-specific-container-image.example.com
  namespaceSelector: {}
  objectSelector: {}
  rules:
  - apiGroups:
    - '*'
    apiVersions:
    - '*'
    operations:
    - CREATE
    resources:
    - pods
    scope: '*'
  sideEffects: None
  timeoutSeconds: 10

組態重點解析

  1. Webhook 端點設定:Webhook 的 URL 路徑包含了 jsPolicy 策略的特定路徑,這使得不同的策略可以透過不同的路徑被呼叫。
  2. 資源選擇規則rules 部分定義了該 Webhook 只會攔截 Pod 資源的 CREATE 操作。
  3. 失敗策略failurePolicy 設定為 Fail,確保當服務無法回應時,操作會被拒絕。
  4. 匹配策略matchPolicy 設定為 Equivalent,表示 Webhook 將匹配等效的 API 請求版本。

jsPolicy 的解除安裝流程

解除安裝 jsPolicy 可以透過以下 Helm 指令完成,並使用自定義的指令碼進行額外的清理工作:

# 自定義解除安裝指令碼
#!/usr/bin/env bash
set -e
trap 'catch $? $LINENO' ERR

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

KUBECTL="kubectl"
NS=${1:-jspolicy}

helm -n $NS uninstall jspolicy
${KUBECTL} delete ns $NS
${KUBECTL} delete validatingwebhookconfiguration jspolicy
${KUBECTL} delete mutatingwebhookconfiguration jspolicy
${KUBECTL} api-resources --api-group='policy.jspolicy.com' -o name | xargs ${KUBECTL} delete crd
${KUBECTL} api-resources --api-group='wgpolicyk8s.io' -o name | xargs ${KUBECTL} delete crd
${KUBECTL} label ns kube-system jspolicy-ignore-

清理重點說明

  1. 刪除 jsPolicy 相關資源:指令碼首先解除安裝 Helm Chart,接著刪除相關的 Namespace 與 Webhook 組態。
  2. CRD 清理:由於 Helm 可能不會自動刪除自定義資源定義(CRD),因此指令碼中特別加入了刪除相關 CRD 的指令。
  3. 標籤清理:最後,指令碼會移除 kube-system Namespace 中的相關標籤。

jsPolicy 策略管理

jsPolicy 使用 JavaScript 作為其策略語言,這使得它能夠充分利用 JavaScript 生態系統來建立和測試策略。策略可以透過兩種方式加入 Kubernetes 叢集:

  1. 內嵌式策略(Inline Policies):直接在 JsPolicy 資源的 spec.javascript 欄位中嵌入 JavaScript 程式碼。
  2. 套件式策略(Bundled Policies):將 JavaScript 程式碼編碼和壓縮後儲存在 JsPolicyBundle 資源的 spec.bundle 欄位中。

範例:內嵌式驗證策略

以下是一個驗證性內嵌策略的範例,用於阻止在特定 Namespace 中建立帶有特定標籤的 Pod:

apiVersion: policy.jspolicy.com/v1beta1
kind: JsPolicy
metadata:
  name: "dont-create-me.jimmyray.io"
spec:
  operations: ["CREATE"]
  resources: ["pods"]
  namespaceSelector:
    matchExpressions:
    - key: policy
      operator: In
      values: ["enabled"]
  objectSelector:
    matchLabels:
      env: dev

策略重點解析

  1. 操作與資源篩選:該策略只會攔截 Pod 資源的 CREATE 操作。
  2. Namespace 篩選:透過 namespaceSelector,策略只會在帶有 policy=enabled 標籤的 Namespace 中生效。
  3. 物件篩選objectSelector 確保策略只會對帶有 env=dev 標籤的 Pod 生效。

#### 策略實作最佳實踐

  1. 明確定義策略範圍:透過精確的 namespaceSelectorobjectSelector 設定,避免不必要的效能開銷。
  2. 使用適當的失敗策略:根據實際需求選擇 Fail 或 Ignore,以平衡安全性和系統可用性。
  3. 定期審查和更新策略:隨著業務需求變化,定期檢查和調整策略組態。

#### 策略未來發展方向

  1. 更精細的策略控制:未來可能會支援更複雜的策略邏輯,例如多層級的資源篩選條件。
  2. 整合更多測試工具:預計將有更多工具被整合到 jsPolicy 的開發流程中,以提升策略測試的效率和準確性。