Cloud Custodian 是一款開源工具,能有效管理和監控雲端資源,近年來也支援 Kubernetes。本文將會介紹如何利用 Cloud Custodian 定義策略,篩選和操作 Kubernetes 資源,例如刪除或標註 Pod。文章會以實際案例說明如何撰寫 YAML 策略檔,並解析執行結果與日誌資訊。此外,還會探討 Cloud Custodian 的控制器模式,說明如何整合 Kubernetes 的動態准入控制器和變異 Webhook,實作更自動化的資源管理。最後,文章將提供安裝指令碼範例,以及策略驗證和測試方法,協助讀者快速上手並應用於實際環境。
Cloud Custodian 在 Kubernetes 中的應用與實踐
前言
Cloud Custodian(簡稱 c7n)是一個強大的開源工具,用於管理和監控雲端資源的合規性與成本最佳化。隨著 Kubernetes 的廣泛採用,c7n 也擴充套件了對 Kubernetes 資源的管理能力。本文將探討如何使用 c7n 來管理和監控 Kubernetes 中的資源。
使用 c7n 管理 Kubernetes 資源
c7n 透過定義策略(policies)來對 Kubernetes 資源進行篩選和操作。這些策略可以根據資源的屬性、標籤等進行篩選,並執行相應的操作,如刪除、標註等。
執行策略刪除 Pod
以下是一個實際的例子,展示瞭如何使用 c7n 策略刪除特定的 Pod:
policies:
- name: delete-pods
resource: k8s.pod
filters:
- type: value
key: metadata.labels.test
value: c7n
actions:
- type: delete
內容解密:
policies: 定義了一組策略。name: 策略的名稱為delete-pods。resource: 指定了要操作的 Kubernetes 資源型別為k8s.pod。filters: 篩選條件,這裡根據 Pod 的標籤test=c7n進行篩選。actions: 操作型別,這裡定義了刪除(delete)操作。
執行上述策略後,c7n 會篩選出符合條件的 Pod 並將其刪除。日誌輸出如下:
2023-07-03 00:02:03,442 - custodian.policy - DEBUG - Running policy:delete-pods resource:k8s.pod region:default c7n:0.9.28
2023-07-03 00:02:03,495 - custodian.resources.pod - DEBUG - Filtered from 8 to 1 pod
2023-07-03 00:02:03,526 - custodian.policy - INFO - policy:delete-pods action:delete resource resources:1 execution_time:0.03
內容解密:
Running policy: 表示正在執行delete-pods策略。Filtered from 8 to 1 pod: 表示從 8 個 Pod 中篩選出 1 個 Pod。action:delete: 表示執行了刪除操作,成功刪除了 1 個 Pod。
探索 c7n 對資源的表示方式
c7n 可以用來發現和了解其內部對不同 Kubernetes 資源的表示方式。例如,透過編寫一個粗粒度的 Pod 策略,可以收集叢集中所有 Pod 的資料。
粗粒度 Pod 策略範例
policies:
- name: get-all-pods
description: Collects all pods.
resource: k8s.pod
內容解密:
name: 策略名稱為get-all-pods。resource: 操作的資源型別為k8s.pod。description: 策略的描述,說明該策略用於收集所有 Pod 的資料。
透過執行上述策略,c7n 將收集叢集中所有 Pod 的資源資料,並可以進一步分析這些資料以瞭解 c7n 對 Pod 資源的內部表示方式。
使用 c7n 篩選缺少 securityContext 的 Pod
在實際應用中,可以編寫策略來檢測 Pod 或容器是否缺少 securityContext 組態。以下是一個範例策略:
policies:
- name: security-context-pods
resource: k8s.pod
filters:
- type: value
key: metadata.labels.test
value: c7n
- type: value
key: spec.security_context
value: empty
- type: list-item
key: spec.containers[]
attrs:
- type: value
key: security_context
value: empty
內容解密:
filters: 定義了多個篩選條件,包括檢查 Pod 標籤、spec.security_context是否為空,以及容器級別的security_context是否為空。type: list-item: 用於檢查列表中的元素(這裡指容器)是否符合特定條件。
該策略能夠篩選出那些在 Pod 級別或容器級別缺少 securityContext 組態的 Pod。
對符合條件的 Pod 進行標註和註解
進一步,可以在策略中新增 patch 操作,對符合條件的 Pod 新增標籤和註解:
policies:
- name: security-context-pods
resource: k8s.pod
filters:
- type: value
key: metadata.labels.test
value: c7n
- type: list-item
key: spec.containers[]
attrs:
- type: value
key: security_context
value: empty
actions:
- type: patch
options:
metadata:
labels:
'compliance-issue': 'sec-con-missing'
annotations:
'compliance-issue': 'One or more containers are missing the securityContext element.'
內容解密:
actions: 定義了對篩選出的 Pod 執行的操作,這裡是patch操作,用於修改 Pod 的後設資料。metadata.labels和metadata.annotations: 分別用於新增標籤和註解,以標記這些 Pod 存在安全組態問題。
隨著 Kubernetes 生態系統的不斷發展,c7n 將繼續演進,以更好地支援 Kubernetes 資源的管理和監控。未來的發展方向可能包括:
- 更豐富的資源支援:擴充套件對更多 Kubernetes 資源的支援,如 Custom Resources 等。
- 更強大的策略引擎:增強策略引擎的能力,以支援更複雜的篩選和操作邏輯。
- 更好的整合與相容性:改進與其他 Kubernetes 生態工具的整合,如 Argo CD、Flux 等。
透過不斷的改進和創新,c7n 將成為 Kubernetes 使用者管理和監控叢集資源的得力助手。
控制器模式詳解與實務操作
在前面的章節中,我們已經建立了 c7n_kube 策略並透過 c7n CLI 進行套用。同時,我們檢視了 c7n 策略執行所產生的檔案,以深入瞭解 c7n_kube 的結構與物件模型,從而編寫出更完善的策略。在本章節中,我們將探討如何在傳統的 Kubernetes 動態准入控制器(dynamic admission controller)中,以控制器模式執行 c7n 策略。
控制器模式簡介
c7n Kubernetes 提供者(c7n-kube)的控制器模式與過往的解決方案有一定差異。儘管 c7n-kube 使用了 Kubernetes 的動態准入控制器,但它僅採用了變異 Webhook 組態(mutating webhook configuration),而未安裝驗證 Webhook 組態(validating webhook configuration)。
安裝與設定
初始安裝問題與解決方案
在初次使用控制器模式時,遇到了 c7n 檔案過時的問題。由於使用了 Helm 進行安裝,發現檔案中的範例 values 檔案與目前的 JSON 結構不符。因此,直接使用了 GitHub 儲存函式庫中的 values 檔案並進行了自定義修改。
# c7n-kube 控制器模式 Helm 安裝引數
certManager:
enabled: yes
issuer:
create: yes
certificate:
create: yes
name: "{{ .Release.Name }}-issuer"
controller:
annotations: {}
create: true
image: cloudcustodian/c7n:0.9.35.0
name: "{{ .Release.Name }}"
onException: warn
port: 8443
replicas: 1
pod:
annotations: {}
labels:
app: c7n_kube
name: "{{ .Release.Name }}"
policies:
configMap:
name: "{{ .Release.Name }}-policies"
policies:
- name: 'warn-all-pods'
resource: 'k8s.pod'
mode:
type: k8s-admission
on-match: warn
operations:
- CREATE
- UPDATE
- name: missing-required-labels-pods
mode:
type: k8s-admission
on-match: deny
operations:
- CREATE
- UPDATE
description: |
所有 Pod 都需要包含以下標籤:
app
billing
env
owner
resource: k7s.pod
filters:
- or:
- metadata.labels.app: absent
- metadata.labels.billing: absent
- metadata.labels.env: absent
- metadata.labels.owner: absent
source: configMap
service:
create: true
name: "{{ .Release.Name }}"
port: 8443
webhook:
create: true
failurePolicy: Ignore
namespaceSelector:
matchExpressions:
- key: policy
operator: In
values: ["enabled"]
rules:
- apiGroups:
- '*'
apiVersions:
- 'v1'
operations:
- CREATE
resources:
- pods
主要組態解說
- 憑證管理:使用 cert-manager 自動建立 TLS 憑證,以確保 Kubernetes API 伺服器與 Webhook 服務之間的通訊安全。
- 控制器映像檔:指定 c7n Kubernetes 控制器的 Docker 映像檔版本。
- 策略定義:在安裝控制器時一併載入所需的策略。
- Webhook 組態:
- 設定失敗策略為「忽略」(Ignore),以避免因 Webhook 呼叫失敗而阻擋資源變更。
- 使用名稱空間選擇器(Namespace selector)來實作「選擇性加入」(opt-in)的管理模式。
- 設定 Webhook 只監控 Pod 資源的相關操作。
安裝指令碼自動化
為了簡化安裝與解除安裝流程,特別編寫了 up.sh 和 down.sh 指令碼:
# up.sh 指令碼內容片段
#!/usr/bin/env bash
# 設定錯誤處理機制
set -e
trap 'catch $? $LINENO' ERR
# 安裝 cert-manager
read -p "是否安裝 cert-manager?" yn
case $yn in
[Yy]* ) kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
sleep 120 # 等待 cert-manager 初始化完成
esac
# 安裝 c7n-kube
helm install c7n-kube c7n/c7n-kube -n $NS --create-namespace --values values.yaml
# down.sh 指令碼內容片段,用於解除安裝 c7n-kube 與 cert-manager
helm -n $NS uninstall c7n-kube
# 可選:刪除 cert-manager
read -p "是否解除安裝 cert-manager?" yn
case $yn in
[Yy]* ) kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml --ignore-not-found
esac
策略驗證與測試
安裝完成後,使用特定的名稱空間(Namespace)與 Pod 清單來驗證策略執行結果:
apiVersion: v1
kind: Namespace
metadata:
name: policy-test
labels:
app: test
billing: lob-cc
env: dev
owner: jimmy
policy: enabled
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod-1
namespace: policy-test
labels:
test: c7n # 缺少必要的標籤,如 app, billing 等
spec:
containers:
- name: c1 # 略...
策略測試結果分析
- 由於
test-pod-1缺少必要的標籤(app、billing、env、owner),根據設定的策略,將會被拒絕建立。 - 相關日誌與事件資訊可用於進一步的稽核與除錯。
- 持續最佳化安裝流程:研究更完善的自動化指令碼,以減少人工干預並提升佈署效率。
- 擴充套件策略範疇:開發更多符合實際需求的策略,以強化叢集的安全性和規範性。
- 提升系統穩定性:持續監控系統運作狀態,最佳化資源組態,確保高用性。
透過上述措施,能夠進一步鞏固 c7n-kube 在 Kubernetes 環境下的應用基礎,為企業帶來更高的安全性與維運效率。
詳細程式碼解析:
在上述 up.sh 與 down.sh 指令碼中,我們使用了多項技術來實作自動化佈署與管理:
#!/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:-c7n-kube}
read -p "Do you wish to install certmanager?" yn
yn=${yn:-n}
case $yn in
[Yy]* ) ${KUBECTL} apply -f \ https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
sleep 120
esac
read -p "Do you wish to install/update the namespace?" yn
yn=${yn:-n}
case $yn in
[Yy]* ) ${KUBECTL} apply -f k8s/0-ns.yaml
esac
helm install c7n-kube c7n/c7n-kube -n $NS \ --create-namespace --values values.yaml
#### 程式碼解析:
此指令碼主要用於自動化安裝 `cert-manager` 與 `c7n-kube`。透過使用 `read` 命令進行互動式輸入,允許使用者選擇是否安裝或更新特定元件。同時,利用 `helm` 命令進行 `c7n-kube` 的佈署,並指定對應的 `values.yaml` 組態檔案。
1. **錯誤處理機制**:
```bash
set -e
trap 'catch $? $LINENO' ERR
這段程式碼啟用了嚴格的錯誤處理,一旦執行過程中出現錯誤,便會觸發 catch 函式輸出錯誤資訊。
-
互動式安裝選項:
read -p "Do you wish to install certmanager?" yn case $yn in [Yy]* ) ${KUBECTL} apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml esac使用者可以選擇是否安裝
cert-manager。如果是,則會從指定的 URL 下載並應用相關資源組態。 -
Helm 安裝指令:
helm install c7n-kube c7n/c7n-kube -n $NS --create-namespace --values values.yaml此命令用於透過 Helm 安裝
c7n-kube,並指定名稱空間及自定義的values.yaml組態檔案。 -
名稱空間管理:
read -p "Do you wish to install/update the namespace?" yn case $yn in [Yy]* ) ${KUBECTL} apply -f k8s/0-ns.yaml esac提供選項讓使用者決定是否建立或更新指定的名稱空間。
綜上所述,這些指令碼大幅簡化了 c7n-kube 與相關元件的佈署流程,並提供了靈活的互動選項供使用者自定義安裝步驟。