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
組態重點解析
- Webhook 端點設定:Webhook 的 URL 路徑包含了 jsPolicy 策略的特定路徑,這使得不同的策略可以透過不同的路徑被呼叫。
- 資源選擇規則:
rules部分定義了該 Webhook 只會攔截 Pod 資源的 CREATE 操作。 - 失敗策略:
failurePolicy設定為 Fail,確保當服務無法回應時,操作會被拒絕。 - 匹配策略:
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-
清理重點說明
- 刪除 jsPolicy 相關資源:指令碼首先解除安裝 Helm Chart,接著刪除相關的 Namespace 與 Webhook 組態。
- CRD 清理:由於 Helm 可能不會自動刪除自定義資源定義(CRD),因此指令碼中特別加入了刪除相關 CRD 的指令。
- 標籤清理:最後,指令碼會移除 kube-system Namespace 中的相關標籤。
jsPolicy 策略管理
jsPolicy 使用 JavaScript 作為其策略語言,這使得它能夠充分利用 JavaScript 生態系統來建立和測試策略。策略可以透過兩種方式加入 Kubernetes 叢集:
- 內嵌式策略(Inline Policies):直接在 JsPolicy 資源的 spec.javascript 欄位中嵌入 JavaScript 程式碼。
- 套件式策略(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
策略重點解析
- 操作與資源篩選:該策略只會攔截 Pod 資源的 CREATE 操作。
- Namespace 篩選:透過
namespaceSelector,策略只會在帶有policy=enabled標籤的 Namespace 中生效。 - 物件篩選:
objectSelector確保策略只會對帶有env=dev標籤的 Pod 生效。
#### 策略實作最佳實踐
- 明確定義策略範圍:透過精確的
namespaceSelector和objectSelector設定,避免不必要的效能開銷。 - 使用適當的失敗策略:根據實際需求選擇 Fail 或 Ignore,以平衡安全性和系統可用性。
- 定期審查和更新策略:隨著業務需求變化,定期檢查和調整策略組態。
#### 策略未來發展方向
- 更精細的策略控制:未來可能會支援更複雜的策略邏輯,例如多層級的資源篩選條件。
- 整合更多測試工具:預計將有更多工具被整合到 jsPolicy 的開發流程中,以提升策略測試的效率和準確性。