networkpolicy 生效依赖 cni 插件(如 terway)、集群 api 版本兼容、rbac 权限精准、podselector 正确配置四要素,缺一则策略仅存于 etcd 而不控制流量。

Go 本身不配置 NetworkPolicy,它只负责把策略对象提交给 kube-apiserver;真正生效靠的是 CNI 插件(如 Calico、Cilium 或 Terway),不是 Go 程序在本地写 iptables 规则。
用 client-go 创建 NetworkPolicy 对象必须传对 apiVersion
硬编码 networking.k8s.io/v1 看似省事,但集群升级后可能因 API 版本废弃导致创建失败。client-go 提供了 scheme.Scheme 来动态获取当前支持的版本:
- 调用
scheme.Scheme.GroupVersionFor(&networkingv1.NetworkPolicy{})获取适配集群的 GroupVersion - 若用
unstructured.Unstructured手动构造资源,必须确保apiVersion字段与集群实际支持的完全一致(比如某些旧集群仍用networking.k8s.io/v1beta1) - ACK Terway 集群要求
apiVersion: networking.k8s.io/v1,低于 1.9.0 的 Terway 版本不支持该版本
RBAC 权限缺失是 Forbidden 错误的最常见原因
运行 Go 程序的 ServiceAccount 必须显式授予 networkpolicies 资源的操作权限,否则会报 Forbidden: User "system:serviceaccount:default:my-controller" cannot create resource "networkpolicies":
- 最小权限 RBAC 示例中需包含
verbs: ["create", "update", "patch"]和resources: ["networkpolicies"] - 如果策略要跨命名空间引用(比如
namespaceSelector),还需在目标命名空间授予get和list权限 - 不要把权限绑在
cluster-admin上——NetworkPolicy 是命名空间级资源,过度授权违反最小权限原则
podSelector 为空时作用范围容易误判
podSelector: {} 表示“匹配当前命名空间下所有 Pod”,不是“不生效”。这个空 selector 是默认拒绝策略的关键,但也是误配高发点:
- 若想限制某组 Pod(如
app: redis),却漏写matchLabels,策略会意外覆盖整个命名空间 - 策略只作用于定义它的命名空间,
podSelector无法跨 ns 选择目标,跨 ns 控制必须靠namespaceSelector+podSelector组合 - 多个策略叠加时,空
podSelector的策略可能无意中放宽其他策略的限制(因为 NetworkPolicy 规则是“并集”逻辑)
Terway eBPF 模式下内核版本和节点配置有硬性要求
在 ACK 集群中用 Go 提交了合法的 NetworkPolicy,但流量没被拦截?大概率是底层没生效:
- Terway 1.9.0+ 使用 eBPF 实现策略,要求节点内核 ≥
4.19;低于此版本的 ECS 节点上,策略对象能创建成功,但实际不生效 - 仅支持共享 ENI 模式节点;独占 ENI 模式的节点直接忽略 NetworkPolicy
- 策略中若用了
ipBlock,它只能匹配集群外部地址(如公网 IP 或 VPC 内网段),不能用于匹配集群内 Pod IP —— 这种写法在 Calico/Cilium 下也一样受限
NetworkPolicy 的真实控制力不在 Go 代码里,而在 CNI 插件是否启用、节点内核是否达标、RBAC 是否精准、selector 是否写反这四点上。少一个环节,Go 提交的 YAML 就只是个静态对象。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











