OPA Gatekeeper能否在Ingress创建/更新时校验NetworkPolicy存在
OPA Gatekeeper 校验Ingress同命名空间NetworkPolicy实现方法
要实现创建/更新Ingress时校验同命名空间下是否存在NetworkPolicy,核心是先让Gatekeeper缓存目标资源,再在Rego规则中查询缓存的资源数据,具体步骤如下:
1. 配置Gatekeeper同步NetworkPolicy资源
Gatekeeper默认不会缓存除待准入资源外的其他K8s对象,需要先在gatekeeper-system命名空间下的Config资源中声明要同步的NetworkPolicy,让Gatekeeper把全集群的NetworkPolicy拉到本地缓存供策略调用:
apiVersion: config.gatekeeper.sh/v1alpha1 kind: Config metadata: name: config namespace: gatekeeper-system spec: sync: syncOnly: - group: networking.k8s.io version: v1 kind: NetworkPolicy
注意:如果是自定义安装的Gatekeeper,需要确认集群角色已授予Gatekeeper对networking.k8s.io/v1/networkpolicies资源的list、watch权限,否则同步会失败。
2. 编写ConstraintTemplate规则
同步完成后,所有NetworkPolicy资源会存储在Rego的data.inventory路径下,规则中直接按Ingress所属命名空间查询对应NetworkPolicy列表即可,核心Rego逻辑示例:
package k8srequirednetworkpolicy violation[{"msg": msg}] { # 匹配准入的Ingress资源 input.review.object.kind == "Ingress" input.review.object.apiVersion == "networking.k8s.io/v1" # 获取Ingress所属命名空间 ns := input.review.object.metadata.namespace # 查询该命名空间下所有NetworkPolicy all_np := data.inventory.cluster["networking.k8s.io"].v1.networkpolicies[ns] np_count := count([np | np := all_np[_]]) # 不存在NetworkPolicy时抛出违规提示 np_count == 0 msg := sprintf("当前命名空间%v下未定义NetworkPolicy,会导致CertManager自动申请ACME证书失败,请先配置NetworkPolicy后再创建Ingress", [ns]) }
基于这个模板创建对应的Constraint资源,绑定需要生效的范围(比如全集群、指定命名空间)后,准入校验就会生效。
补充说明
- 上述规则仅校验命名空间下是否存在NetworkPolicy,如果需要更精准校验(比如确认存在的NetworkPolicy已放行CertManager Pod的出站ACME请求流量),可以扩展Rego逻辑,遍历
all_np里每个NetworkPolicy的spec规则做匹配判断。 - 该准入校验仅对新建/更新的Ingress生效,存量违规Ingress可以通过开启Gatekeeper的Audit功能扫描发现。
- 如果同步资源后规则里查不到data.inventory数据,可以等1-2分钟让Gatekeeper完成首次全量资源同步后再测试。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

