深色模式
镜像安全与准入控制 OPA/Gatekeeper
摘要:本文面向需要超出 RBAC 与 PSA 能力、在对象级强制自定义策略(镜像仓库白名单、禁止
:latest、强制标签)的平台工程师。覆盖 Gatekeeper 的 ConstraintTemplate/Constraint 模型、Rego、enforcementAction 与审计模式。适用版本:Gatekeeper v3.14+(apiVersiontemplates.gatekeeper.sh/v1GA)。
适用版本与前提
- Kubernetes:v1.28+;Gatekeeper v3.14+(ConstraintTemplate
templates.gatekeeper.sh/v1自 v3.8 GA) - 需 cluster-admin 安装 Gatekeeper(
gatekeeper-system命名空间) - 已了解 RBAC 与 PSA 的边界
为什么需要 Gatekeeper
RBAC 只管"谁能调 API",PSA 只管 Pod 安全基线。它们都覆盖不到"业务级策略":
- 所有镜像必须来自公司仓库
- Deployment 必须有
team标签 - 禁止
:latest镜像标签 - 禁止
hostNetwork/hostPID
OPA Gatekeeper 把这些规则表达为 policy as code,作为 validating admission webhook 在资源创建/更新时拦截。它是 OPA(Open Policy Agent)在 K8s 的集成形态。
两个核心对象
ConstraintTemplate:可复用策略逻辑
定义一次策略(注册一个新 CRD + 内嵌 Rego)。spec.crd.spec.names.kind 决定实例的 Kind,targets[].rego 是策略主体,targets[].target 必须是 admission.k8s.gatekeeper.sh。
yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sallowedrepos
spec:
crd:
spec:
names:
kind: K8sAllowedRepos
validation:
openAPIV3Schema:
type: object
properties:
repos:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sallowedrepos
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not starts_with(container.image, input.parameters.repos[_])
msg := sprintf("container %v uses image %v not from allowed repos", [container.name, container.image])
}
violation[{"msg": msg}] {
container := input.review.object.spec.initContainers[_]
not starts_with(container.image, input.parameters.repos[_])
msg := sprintf("initContainer %v uses image %v not from allowed repos", [container.name, container.image])
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Constraint:策略实例(带参数与范围)
把模板实例化为具体策略,设定参数、匹配范围、豁免命名空间、执行动作。
yaml
apiVersion: constraints.gatekeeper.sh/v1
kind: K8sAllowedRepos
metadata:
name: require-registry
spec:
enforcementAction: deny
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
- apiGroups: ["apps"]
kinds: ["Deployment", "StatefulSet", "DaemonSet"]
excludedNamespaces:
- kube-system
- gatekeeper-system
parameters:
repos:
- "registry.internal.example.com/"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enforcementAction 三档
| 值 | 行为 | 适用阶段 |
|---|---|---|
deny | 拒绝违规请求 | 确认策略无误后 |
warn | 放行但返回警告 | 过渡 |
dryrun | 放行,仅记录到 status.violations | 先审计再强制 |
永远先 dryrun
生产落地铁律:新策略先 enforcementAction: dryrun,用 kubectl get k8sallowedrepos require-registry -o yaml 查看 status.violations 审计存量违规,确认无误再切 deny。Gatekeeper 也提供 Prometheus 指标观察违规数。
禁用特权容器(补充 PSA)
Gatekeeper 可与 PSA 互补,覆盖 initContainer、ephemeral container 等 PSA 不易覆盖的点:
yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sblockprivileged
spec:
crd:
spec:
names:
kind: K8sBlockPrivileged
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sblockprivileged
violation[{"msg": msg}] {
c := input.review.object.spec.containers[_]
c.securityContext.privileged == true
msg := sprintf("privileged container not allowed: %v", [c.name])
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
审计(Audit)能力
Gatekeeper 的 gatekeeper-audit 组件周期性扫描集群已有资源的违规,不拦截创建,只记录到 Constraint 的 status.violations。这是"准入 + 审计"双管齐下的关键:既防新违规,又发现历史漂移。
常见坑
Webhook 可用性直接影响集群可用性
Gatekeeper 是 validating webhook。若其 Pod 全挂且 failurePolicy: Fail(推荐值),所有命中匹配的资源创建都会被拒绝——等于临时关闭了整个 API 的某个写入路径。务必保证 gatekeeper-controller-manager 多副本、跨节点、有 PodDisruptionBudget。对可容忍放行的非关键策略可用 failurePolicy: Ignore 并加告警。[版本相关:具体 failurePolicy 取舍需按可用性评估]
- Rego 语法错误:ConstraintTemplate 编译失败,用
kubectl describe constrainttemplate <name>看错误。 - 忘记排除系统命名空间:会阻断 kube-system / gatekeeper-system 自身资源,务必
excludedNamespaces。
回滚与清理
- 把策略
enforcementAction改回dryrun或warn即可立即放行,无需删模板。 - 删除 Constraint 不影响已创建资源;删除 ConstraintTemplate 会级联删除其 Constraint。
- 卸载 Gatekeeper 前先删所有 Constraint,避免 webhook 配置残留导致全集群写入失败。
调试与排障
bash
# 查看 Gatekeeper 组件
kubectl get pods -n gatekeeper-system
# 查看某 Constraint 的审计违规
kubectl get k8sallowedrepos require-registry -o yaml | yq '.status.violations'
# 查看 webhook 配置(failurePolicy 等关键项)
kubectl get validatingwebhookconfigurations -o yaml | grep -A2 gatekeeper1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
镜像签名验证放在哪
与本文的边界
Gatekeeper 本身不直接验证镜像签名。镜像签名与准入验证属于供应链安全范畴,需用 cosign 配合专门的验证 webhook(如 Kyverno verifyImages、Connaisseur、sigstore policy-controller)。详见 供应链安全与镜像签名。
参考资料
- OPA Gatekeeper 官方文档,访问日期:2026-10-08。
- Gatekeeper - ConstraintTemplate 参考,访问日期:2026-10-08。
- OPA Rego 语言文档,访问日期:2026-10-08。
- Kubernetes 官方文档 - Admission Controllers,访问日期:2026-10-08。
- Kubernetes Recipes - OPA Gatekeeper Policies,访问日期:2026-10-08。