简介
Network Policies
如果您希望在 IP 地址或端口层面控制 TCP、UDP 和 SCTP 等协议的网络流量,可以为集群中的特定应用使用 Kubernetes 网络策略(NetworkPolicy)。NetworkPolicy 是一种以应用为中心的策略机制,用于精细化地定义 Pod 如何与网络中的其他实体进行通信,特别适用于与 Pod 相关的网络连接场景。
您可以通过以下三种标识符来指定允许与 Pod 通信的实体:
1. 其他已被允许的 Pod(注意:Pod 无法阻止对自身的访问)。
2. 被允许的命名空间。
3. IP 块(注意:无论 Pod 或节点的 IP 地址是什么,Pod 与其所在节点之间的通信总是被允许)。
在定义基于 Pod 或命名空间的 NetworkPolicy 时,可以使用 标签选择器(Label Selector)来决定哪些流量可进入或离开符合该选择器条件的 Pod;而对于基于 IP 地址的 NetworkPolicy,则通过指定 IP 块(CIDR 范围)来进行相应的流量控制。
eNP
eNP(eBPF Network Policies)组件是一种基于 eBPF 技术的 NetworkPolicy 实现。它通过在 Pod 所在宿主机的 veth 的 tc 上挂载 eBPF 程序,在网卡处理报文时,根据五元组(源地址、源端口、目的地址、目的端口以及传输协议)去匹配 NetworkPolicy 的规则,判断该报文是放通还是丢弃。
架构
限制
1. 支持的 OS 版本为 TencentOS Server 3.1 以及 TencentOS Server 3.2。
2. TKE 1.22 及以上集群版本。
3. 网络插件为共享网卡 VPC-CNI。
4. 当前仅支持超级节点。
5. 仅支持 IPv4 集群,暂不支持 IPv4/IPv6 双栈集群。
组件架构
eNP 组件架构示意图如下:

1. eNP 组件引入一个 CRD(Custom Resource Definition),用来存储 NetworkPolicy 关联的实体。
2. tke-network-policy-controller 以 deployment 形式部署在控制面,其 list and watch NetworkPolicy 资源并为每个 Pod 计算生成 Policy-CRD。
3. tke-network-policy-agent 通过 DaemonSet 注入 的方式在每个业务 Pod 的 network namespace 内的默认网卡(eth0)上挂载 filter eBPF 程序。
4. agent 根据 Policy-CRD 在 eBPF map 中维护放通规则,挂载的 eBPF 程序根据放通 eBPF map 中的规则去放通或者丢弃某个报文。
eNP 组件 e2e 测试情况
运行 Kubernetes 社区的 NetworkPolicy 的 e2e 测试(release-1.26),该版本的测试项目来自两个测试集合,不同集合的网络模型不同,但两个集合之间的 测试项目有重叠,这里将 network_policy.go 内的测试项目标记为 network_policy,network_legacy.go 内的测试项目标记为 network_legacy,通过的 case 为:
编号 | Feature | 来源 |
1 | should support a 'default-deny-ingress' policy [Feature:NetworkPolicy] | network_legacy |
2 | should support a 'default-deny-all' policy [Feature:NetworkPolicy] | network_legacy |
3 | should enforce policy to allow traffic from pods within server namespace based on PodSelector [Feature:NetworkPolicy] | network_legacy |
4 | should enforce policy to allow traffic only from a different namespace, based on NamespaceSelector [Feature:NetworkPolicy] | network_legacy |
5 | should enforce policy based on PodSelector with MatchExpressions[Feature:NetworkPolicy] | network_legacy |
6 | should enforce policy based on NamespaceSelector with MatchExpressions[Feature:NetworkPolicy] | network_legacy |
7 | should enforce policy based on PodSelector or NamespaceSelector [Feature:NetworkPolicy] | network_legacy |
8 | should enforce policy based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_legacy |
9 | should enforce policy to allow traffic only from a pod in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_legacy |
10 | should enforce policy based on Ports [Feature:NetworkPolicy] | network_legacy |
11 | should enforce multiple, stacked policies with overlapping podSelectors [Feature:NetworkPolicy] | network_legacy |
12 | should support allow-all policy [Feature:NetworkPolicy] | network_legacy |
13 | should allow ingress access on one named port [Feature:NetworkPolicy] | network_legacy |
14 | should allow ingress access from namespace on one named port [Feature:NetworkPolicy] | network_legacy |
15 | should allow egress access on one named port [Feature:NetworkPolicy] | network_legacy |
16 | should enforce updated policy [Feature:NetworkPolicy] | network_legacy |
17 | should allow ingress access from updated namespace [Feature:NetworkPolicy] | network_legacy |
18 | should allow ingress access from updated pod [Feature:NetworkPolicy] | network_legacy |
19 | should deny ingress access to updated pod [Feature:NetworkPolicy] | network_legacy |
20 | should work with Ingress,Egress specified together [Feature:NetworkPolicy] | network_legacy |
21 | should enforce egress policy allowing traffic to a server in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_legacy |
22 | should enforce multiple ingress policies with ingress allow-all policy taking precedence [Feature:NetworkPolicy] | network_legacy |
23 | should enforce multiple egress policies with egress allow-all policy taking precedence [Feature:NetworkPolicy] | network_legacy |
24 | should stop enforcing policies after they are deleted [Feature:NetworkPolicy] | network_legacy |
25 | should enforce policies to check ingress and egress policies can be controlled independently based on PodSelector [Feature:NetworkPolicy] | network_legacy |
26 | should not allow access by TCP when a policy specifies only SCTP [Feature:NetworkPolicy] | network_legacy |
27 | should support a 'default-deny' policy [Feature:NetworkPolicy] | network_legacy |
28 | should enforce policy based on Ports [Feature:NetworkPolicy] | network_legacy |
29 | should enforce policy to allow traffic only from a pod in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_legacy |
30 | should support a 'default-deny-ingress' policy [Feature:NetworkPolicy] | network_policy |
31 | should support a 'default-deny-all' policy [Feature:NetworkPolicy] | network_policy |
32 | should enforce policy to allow traffic from pods within server namespace based on PodSelector [Feature:NetworkPolicy] | network_policy |
33 | should enforce policy to allow ingress traffic for a target [Feature:NetworkPolicy] | network_policy |
34 | should enforce policy to allow ingress traffic from pods in all namespaces [Feature:NetworkPolicy] | network_policy |
35 | should enforce policy to allow traffic only from a different namespace, based on NamespaceSelector [Feature:NetworkPolicy] | network_policy |
36 | should enforce policy based on PodSelector with MatchExpressions[Feature:NetworkPolicy] | network_policy |
37 | should enforce policy based on NamespaceSelector with MatchExpressions[Feature:NetworkPolicy] | network_policy |
38 | should enforce policy based on PodSelector or NamespaceSelector [Feature:NetworkPolicy] | network_policy |
39 | should enforce policy based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_policy |
40 | should enforce policy based on Multiple PodSelectors and NamespaceSelectors [Feature:NetworkPolicy] | network_policy |
41 | should enforce policy based on any PodSelectors [Feature:NetworkPolicy] | network_policy |
42 | should enforce policy to allow traffic only from a pod in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_policy |
43 | should enforce policy based on Ports [Feature:NetworkPolicy] | network_policy |
44 | should enforce multiple, stacked policies with overlapping podSelectors [Feature:NetworkPolicy] | network_policy |
45 | should support allow-all policy [Feature:NetworkPolicy] | network_policy |
46 | should allow ingress access on one named port [Feature:NetworkPolicy] | network_policy |
47 | should allow ingress access from namespace on one named port [Feature:NetworkPolicy] | network_policy |
48 | should enforce updated policy [Feature:NetworkPolicy] | network_policy |
49 | should allow ingress access from updated namespace [Feature:NetworkPolicy] | network_policy |
50 | should allow ingress access from updated pod [Feature:NetworkPolicy] | network_policy |
51 | should deny ingress from pods on other namespaces [Feature:NetworkPolicy] | network_policy |
52 | should deny ingress access to updated pod [Feature:NetworkPolicy] | network_policy |
53 | should deny egress from pods based on PodSelector [Feature:NetworkPolicy] | network_policy |
54 | should deny egress from all pods in a namespace [Feature:NetworkPolicy] | network_policy |
55 | should work with Ingress, Egress specified together [Feature:NetworkPolicy] | network_policy |
56 | should support denying of egress traffic on the client side (even if the server explicitly allows this traffic) [Feature:NetworkPolicy] | network_policy |
57 | should enforce egress policy allowing traffic to a server in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_policy |
58 | should enforce ingress policy allowing any port traffic to a server on a specific protocol [Feature:NetworkPolicy] [Feature:UDP] | network_policy |
59 | should enforce multiple ingress policies with ingress allow-all policy taking precedence [Feature:NetworkPolicy] | network_policy |
60 | should enforce multiple egress policies with egress allow-all policy taking precedence [Feature:NetworkPolicy] | network_policy |
61 | should stop enforcing policies after they are deleted [Feature:NetworkPolicy] | network_policy |
62 | should enforce policies to check ingress and egress policies can be controlled independently based on PodSelector [Feature:NetworkPolicy] | network_policy |
63 | should not mistakenly treat 'protocol: SCTP' as 'protocol: TCP', even if the plugin doesn't support SCTP [Feature:NetworkPolicy] | network_policy |
64 | should properly isolate pods that are selected by a policy allowing SCTP, even if the plugin doesn't support SCTP [Feature:NetworkPolicy] | network_policy |
65 | should not allow access by TCP when a policy specifies only UDP [Feature:NetworkPolicy] | network_policy |
66 | should enforce policy to allow traffic based on NamespaceSelector with MatchLabels using default ns label [Feature:NetworkPolicy] | network_policy |
67 | should enforce policy based on NamespaceSelector with MatchExpressions using default ns label [Feature:NetworkPolicy] | network_policy |
68 | should support a 'default-deny-ingress' policy [Feature:NetworkPolicy] | network_policy |
69 | should enforce policy based on Ports [Feature:NetworkPolicy] | network_policy |
70 | should enforce policy to allow traffic only from a pod in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_policy |
71 | should support a 'default-deny-ingress' policy [Feature:NetworkPolicy] | network_policy |
72 | should enforce policy based on Ports [Feature:NetworkPolicy] | network_policy |
73 | should enforce policy to allow traffic only from a pod in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy] | network_policy |
目前不支持的场景为:
1. 当 Pod 为某个 Service 的后端时,通过 egress 放通对该 Pod 访问,如果通过 Service IP 对该 Pod 进行访问会被拒绝(与原有 Network Policy 组件不同,原有的组件通过 Service IP 访问时可以访问到该 Pod )。
2. 不支持 named port 类型的规则。
具体的 e2e 测试 case 如下:
case | 现象 | 原因 |
should enforce except clause while egress access to server in CIDR block | 当在 NetworkPolicy 中放通某个 Pod 的 IP CIDR 时,不能放通 Pod 相关的 Service IP。 | 由于底层 ebpf 在 Pod 网卡 egress 处实现,此时报文的 Service IP 还未被 iptables/ipvs DNAT 为 Pod IP,因此会被挂载的 ebpf 程序丢弃。 |
should allow egress access to server in CIDR block | | |
should ensure an IP overlapping both IPBlock.CIDR and IPBlock.Except is allowed | | |
should allow egress access on one named port | egress 的 named port 不生效 (暂不支持) | 如果 egress 的 peer 是某个外网 IP 地址,那么 named port 没有源头获取,所以暂不支持。 |