Gatekeeper 作為 Kubernetes 的一個關鍵安全工具,仰賴 Open Policy Agent (OPA) 提供強大的策略控制能力。本文不僅探討 Gatekeeper 的驗證、強制和變異策略機制,更輔以實際案例與程式碼片段,解析如何在 Kubernetes 環境中有效應用。從容器安全形度出發,我們會示範如何使用 SeccompProfile 限制系統呼叫,提升 Pod 安全性。此外,針對多租戶環境,文章詳細介紹如何結合 Node Taints、Tolerations 和 Affinity 等 Kubernetes 原生機制,搭配 Gatekeeper 的 Assign 和 Validation 策略,實作資源隔離和安全管控,確保不同租戶間的工作負載互不幹擾。
Gatekeeper 政策與 Kubernetes 的整合應用
Gatekeeper 是 Kubernetes 的一個重要安全工具,它透過 Open Policy Agent (OPA) 實作對叢集資源的策略控制。在本章中,我們將探討 Gatekeeper 的政策機制,包括驗證政策、強制執行動作和變異政策,並透過具體範例來說明其應用。
驗證政策與違規處理
Gatekeeper 的驗證政策用於檢查 Kubernetes 資源是否符合特定的安全要求。當資源不符合政策要求時,Gatekeeper 會記錄違規資訊。以下是一個典型的違規日誌範例:
{
"resource_group": "apps",
"resource_api_version": "v1",
"resource_kind": "Deployment",
"resource_namespace": "policy-test",
"resource_name": "test",
"request_username": "minikube-user"
}
內容解密:
此 JSON 物件記錄了一次違規事件的詳細資訊。其中:
resource_group
和resource_api_version
指定了資源的 API 群組和版本。resource_kind
表示資源型別為 Deployment。resource_namespace
和resource_name
指定了違規資源所在的名稱空間和名稱。request_username
表示發起請求的使用者名稱。
在 Gatekeeper 的 Constraint 狀態列位中,也可以看到違規的詳細資訊:
totalViolations: 1
violations:
- enforcementAction: dryrun
group: apps
kind: Deployment
message: 'INVALID_DEPLOYMENT_REGISTRY: BAD_REGISTRY/read-only-container:v0.0.1 image is not sourced from an authorized registry. Resource ID (ns/name/kind): policy-test/test/Deployment'
name: test
namespace: policy-test
version: v1
內容解密:
此段 YAML 描述了一個違規事件:
totalViolations
表示總共有 1 個違規事件。violations
列出了違規的詳細資訊,包括執行動作、資源群組、種類別、錯誤訊息等。message
欄位明確指出映像檔BAD_REGISTRY/read-only-container:v0.0.1
不是來自授權的登入檔。
變異政策的應用
Gatekeeper 的變異政策允許在資源建立或更新時自動修改其設定。為了啟用變異功能,我們需要在安裝 Gatekeeper Helm chart 時設定特定的引數:
--set logMutations=true --set mutationAnnotations=true
這些引數會啟用變異日誌記錄和資源註解,有助於除錯和稽核。
Gatekeeper Controller Manager 的變異引數
- args:
- --log-mutations=true
- --mutation-annotations=true
- --operation=mutation-webhook
內容解密:
這些引陣列態了 Gatekeeper Controller Manager 的行為:
--log-mutations=true
啟用了變異日誌記錄。--mutation-annotations=true
為被變異的資源新增註解。--operation=mutation-webhook
指定了變異操作的型別。
變異日誌範例
當變異政策被應用時,Gatekeeper Controller Manager 會記錄相關的日誌:
{
"level": "info",
"ts": 1672262677.1373708,
"logger": "mutation",
"msg": "Mutation applied",
"process": "mutation",
"Mutation Id": "2e223bf5-73bb-4e55-8e75-d778d5b32cbc",
"event_type": "mutation_applied",
"resource_group": "",
"resource_kind": "Pod",
"resource_api_version": "v1",
"resource_namespace": "policy-test",
"resource_name": "test-pod",
"iteration_0": "AssignMetadata//label-billing:1, AssignMetadata//label-env:1, AssignMetadata//label-owner:1"
}
內容解密:
此 JSON 物件描述了一次成功的變異操作:
msg
表示變異已應用。Mutation Id
是此次變異的唯一識別碼。resource_kind
和resource_name
指定了被變異的資源型別和名稱。iteration_0
列出了應用的變異操作,包括新增特定的標籤。
Gatekeeper 的四種變異 CRDs
Gatekeeper 提供了四種變異 CRDs(Custom Resource Definitions)來實作不同的變異需求:
- assign.mutations.gatekeeper.sh:用於修改資源的中繼資料(metadata)以外的部分。
- assignmetadata.mutations.gatekeeper.sh:專門用於修改資源的中繼資料。
- modifyset.mutations.gatekeeper.sh:用於修改資源中的列表專案。
- assignimage.mutations.gatekeeper.sh:用於修改容器映像檔字串。
使用 AssignMetadata 變異器新增標籤
以下是一個使用 AssignMetadata 變異器的範例政策,用於為特定的 Pod 新增標籤:
apiVersion: mutations.gatekeeper.sh/v1
kind: AssignMetadata
metadata:
name: label-owner
spec:
match:
scope: Namespaced
kinds:
- apiGroups: ["*"]
kinds: ["Pod"]
namespaces: ["policy*"]
location: "metadata.labels.owner"
parameters:
assign:
value: "jimmy"
圖表翻譯:
graph LR A[開始] --> B[匹配 Namespaced 範圍內的 Pod 資源] B --> C[檢查名稱空間是否符合 policy*] C --> D[在 metadata.labels.owner 處指定 jimmy] D --> E[完成變異]
此圖示展示了 AssignMetadata 變異器的運作流程,從匹配資源到最終指定的過程。
內容解密:
此 AssignMetadata 政策的詳細說明:
match
部分指定了政策的匹配條件,包括範圍、資源型別和名稱空間。location
指定了要修改的欄位,即metadata.labels.owner
。parameters.assign.value
設定了要賦予標籤的值為"jimmy"
。
測試變異政策
我們可以建立一個測試 Pod 來驗證上述政策的效果:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: policy-test
labels:
app: test
spec:
containers:
- name: test
image: gcr.io/google-containers/pause:3.2
imagePullPolicy: Always
securityContext:
allowPrivilegeEscalation: false
runAsUser: 1000
readOnlyRootFilesystem: true
runAsNonRoot: true
capabilities:
drop: ["ALL"]
seccompProfile:
type: "RuntimeDefault"
套用此 Pod 設定後,我們可以檢查其標籤和註解:
$ kubectl -n policy-test get pods test-pod -o=jsonpath='{.metadata.labels}'
{"app":"test","billing":"lob-cc","env":"dev","owner":"jimmy"}
$ kubectl -n policy-test get pods test-pod -o=jsonpath='{.metadata.annotations}'
{"gatekeeper.sh/mutation-id":"2e223bf5-73bb-4e55-8e75-d778d5b32cbc",...}
圖表翻譯:
graph LR A[建立 Pod] --> B[Gatekeeper 自動新增標籤] B --> C[檢查 Pod 的標籤和註解] C --> D[驗證變異結果]
此圖示展示了從建立 Pod 到驗證變異結果的整個流程。
Kubernetes 中的 OPA/Gatekeeper 策略管理與多租戶隔離實作
在現代的 Kubernetes 環境中,如何有效地管理和實施安全策略是一個重要的課題。Open Policy Agent(OPA)與 Gatekeeper 的結合提供了一種強大的策略管理機制,能夠幫助我們實作複雜的安全需求和資源隔離。本文將探討如何使用 OPA/Gatekeeper 來實作 Kubernetes 中的策略管理,特別是在多租戶隔離場景下的應用。
SeccompProfile 策略組態與實作
Seccomp(Secure Computing Mode)是一種 Linux 核心安全機制,用於限制容器內可執行的系統呼叫。在 Kubernetes 中,我們可以透過組態 SeccompProfile 來增強容器的安全性。下面是一個基礎的 Pod 組態範例:
spec:
containers:
- name: test-pod
image: gcr.io/google-containers/pause:3.2
imagePullPolicy: Always
securityContext:
allowPrivilegeEscalation: false
runAsUser: 1000
readOnlyRootFilesystem: true
runAsNonRoot: true
capabilities:
drop: ["ALL"]
使用 Gatekeeper 實施 SeccompProfile 策略
為了確保所有 Pod 都組態了適當的 SeccompProfile,我們可以使用 Gatekeeper 的 Assign 策略來自動為符合特定條件的 Pod 新增必要的組態。以下是一個範例策略:
apiVersion: mutations.gatekeeper.sh/v1
kind: Assign
metadata:
name: add-seccomp
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
namespaces: ["policy*"]
location: "spec.containers[name: *].securityContext.seccompProfile.type"
parameters:
pathTests:
- subPath: "spec.containers[name: *].securityContext.seccompProfile"
condition: MustNotExist
assign:
value: RuntimeDefault
策略解讀
- 策略匹配條件:此策略會匹配所有在名稱以 “policy” 開頭的 Namespace 中的 Pod。
- 自動組態 SeccompProfile:如果 Pod 的容器尚未組態 SeccompProfile,Gatekeeper 會自動將
seccompProfile.type
設定為RuntimeDefault
。 - 路徑測試:策略中使用了
pathTests
來檢查指定的路徑是否存在,若不存在則執行指定操作。
驗證策略效果
在應用了上述策略後,我們可以透過以下命令來驗證 Pod 是否被正確修改:
kubectl -n policy-test get pods another-test-pod -o=jsonpath='{.spec.containers[].securityContext.seccompProfile}'
預期的輸出應該顯示 {"type":"RuntimeDefault"}
,表明 SeccompProfile 已被成功組態。
多租戶隔離實作
在多租戶的 Kubernetes 環境中,資源隔離是確保不同租戶之間工作負載安全性的關鍵。以下是一個根據 Node Taints、Tolerations 和 Affinity 的隔離方案。
實作步驟
- 建立多個 Node Group:首先,需要在 Kubernetes 叢集中建立多個 Node Group,每個 Node Group 對應一個租戶。
- 設定 Node Taints 和 Labels:為特定的 Node Group 設定 Taints 和 Labels,以便後續的排程控制。
- 編寫 Mutation 和 Validation 策略:
- 使用 Mutation 策略為特定 Namespace 中的 Pod 自動新增 Tolerations 和 Node Affinity。
- 使用 Validation 策略驗證 Pod 是否具備正確的 Tolerations 和 Node Affinity。
範例組態
# Mutation 策略範例:新增 Toleration
apiVersion: mutations.gatekeeper.sh/v1
kind: Assign
metadata:
name: add-toleration
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
namespaces: ["tenant1*"]
location: "spec.tolerations"
parameters:
assign:
value:
key: "tenant1-taint"
operator: "Exists"
effect: "NoSchedule"
# Validation 策略範例:驗證 Toleration
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sTolerationConstraint
metadata:
name: toleration-constraint
spec:
match:
namespaces: ["tenant1*"]
parameters:
tolerations:
- key: "tenant1-taint"
operator: "Exists"
隨著 Kubernetes 和雲原生技術的不斷發展,安全策略管理將變得越來越重要。未來,我們可以期待 OPA/Gatekeeper 在以下幾個方面有更多的發展和改進:
- 更豐富的策略函式庫:提供更多預定義的策略範本,以滿足不同的安全需求。
- 更強大的策略驗證功能:增強策略驗證的能力,確保策略的有效性和正確性。
- 更好的整合性:與更多的 Kubernetes 生態系統工具和平台整合,提供無縫的安全管理體驗。
透過持續地探索和採用新的安全技術和實踐,我們可以更好地保護 Kubernetes 環境中的工作負載和資料。