Open Policy Agent Gatekeeper 突变功能详解
什么是突变功能
Open Policy Agent Gatekeeper 的突变功能允许在请求时根据自定义的突变策略修改 Kubernetes 资源。这一功能自 Gatekeeper v3.10 版本起已稳定可用。
突变 CRD 类型
Gatekeeper 提供了三种专门用于定义突变策略的 CRD(自定义资源定义):
- AssignMetadata - 用于修改资源的元数据部分
- Assign - 用于修改元数据以外的任何部分
- ModifySet - 用于从列表中添加或删除条目,例如容器的参数列表
突变 CRD 结构解析
每个突变 CRD 都包含三个主要部分:
1. 变更范围 (Extent of changes)
这部分定义了哪些资源会被修改,使用与约束相同的匹配条件。示例:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
scope: Namespaced
kinds:
- apiGroups: ["*"]
kinds: ["Pod"]
namespaces: ["default"]
关键点说明:
applyTo
字段是 Assign 和 ModifySet 必须的,AssignMetadata 不需要applyTo
帮助 Gatekeeper 理解被修改对象的模式match
部分支持多种匹配条件:- scope: 资源作用域(Namespaced/Cluster)
- kinds: 资源类型
- labelSelector: 标签选择器
- namespaces: 允许的命名空间列表
- namespaceSelector: 命名空间选择器
- excludedNamespaces: 排除的命名空间列表
- name: 对象名称(支持前缀通配符,如
pod-*
)
2. 变更意图 (Intent)
这部分指定了资源中要修改的内容。示例:
location: "spec.containers[name: foo].imagePullPolicy"
parameters:
assign:
value: "Always"
关键点说明:
location
指定要修改的路径parameters.assign.value
指定要设置的值- 路径可以指向简单子元素或列表中的元素
- 支持通配符(如
name: *
) - 值可以是简单字符串或复合值
从元数据赋值
Assign 和 AssignMetadata 可以通过 fromMetadata
字段从元数据中获取值:
parameters:
assign:
fromMetadata:
field: namespace # 可以是 namespace 或 name
3. 变更条件 (Conditionals)
定义应用突变的条件。示例:
parameters:
pathTests:
- subPath: "spec.containers[name: foo]"
condition: MustExist
三种突变类型详解
1. AssignMetadata
专门用于修改资源的元数据部分,目前仅允许添加标签或注解,不能修改已存在的标签或注解。
示例:添加 owner 标签
apiVersion: mutations.gatekeeper.sh/v1
kind: AssignMetadata
metadata:
name: demo-annotation-owner
spec:
location: "metadata.labels.owner"
parameters:
assign:
value: "admin"
2. Assign
用于修改元数据以外的任何部分。
示例:设置特定容器的安全上下文
apiVersion: mutations.gatekeeper.sh/v1
kind: Assign
metadata:
name: demo-privileged
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: "spec.containers[name:foo].securityContext.privileged"
parameters:
assign:
value: false
3. ModifySet
用于从列表中添加或删除条目,操作类似于集合操作。
示例:从容器参数中移除特定参数
apiVersion: mutations.gatekeeper.sh/v1
kind: ModifySet
metadata:
name: remove-err-logging
spec:
location: "spec.containers[name: *].args"
parameters:
operation: prune # 可以是 merge 或 prune
values:
fromList:
- --alsologtostderr
实用场景示例
场景1:为所有命名空间(除system外)的Pod设置imagePullPolicy
apiVersion: mutations.gatekeeper.sh/v1
kind: Assign
metadata:
name: demo-image-pull-policy
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
excludedNamespaces: ["system"]
location: "spec.containers[name:*].imagePullPolicy"
parameters:
assign:
value: Always
场景2:为Pod添加网络边车容器
apiVersion: mutations.gatekeeper.sh/v1
kind: Assign
metadata:
name: demo-sidecar
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
location: "spec.containers[name:networking]"
parameters:
assign:
value:
name: "networking"
image: quay.io/foo/bar:latest
command: ["/bin/bash", "-c", "sleep INF"]
场景3:设置Pod的DNS策略和配置
apiVersion: mutations.gatekeeper.sh/v1
kind: Assign
metadata:
name: demo-dns-policy
spec:
location: "spec.dnsPolicy"
parameters:
assign:
value: None
---
apiVersion: mutations.gatekeeper.sh/v1
kind: Assign
metadata:
name: demo-dns-config
spec:
location: "spec.dnsConfig"
parameters:
assign:
value:
nameservers:
- 1.2.3.4
最佳实践建议
- 谨慎修改元数据:元数据修改可能产生意外后果,特别是名称和命名空间
- 使用条件测试:利用 pathTests 确保只在特定条件下应用突变
- 明确变更范围:尽量缩小 match 范围,避免不必要的突变
- 模式一致性:确保 applyTo 与 location 路径匹配,避免模式冲突
- 变更记录:启用突变注解功能以记录突变操作
通过合理使用 Gatekeeper 的突变功能,可以实现 Kubernetes 资源的自动化修改,确保集群中的资源符合组织标准和最佳实践。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考