通过设置 Network Policy,可以允许被 Label Selector 选定的 Pods 被哪些 IP 地址访问(Ingress 入站策略),以及允许选定的 Pods 去访问哪些 IP 地址(Egress 出站)。本质上是以 App/Pod 为中心的 L3-4 ACL(访问控制策略)设计。
Network Policy 通常与某个 Namespace 绑定,默认情况下,如果 Namespace 中不存在 Network Policy,则所有 Ingress/Egress 该 Namespace 中的 Pods 的流量都被允许。并且针对某个 App/Pod 的多条 Policies 的效果是叠加的,所以不存在顺序和冲突的情况。
需要注意的是,Network Policy 由 CNI 支撑,所以 Network Policy 支持的能力取决于 CNI 的能力。
一个 Network Policy 的示例:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
示例 1:为 Namespace test-ns2 创建 Network Policy default-deny Ingress,表示默认拒绝 Namespace 内所有 Pods 的 Ingress 流量。
示例 2:允许 Subnet 20.10.10.0/24 里的 Pods 访问 Namespace test-ns1 中有 Label nginx-ns1 的 Pods 的 Port 80,并且将 IP 20.10.10.3/32 的 Pod 除外。
示例 1:禁止 Namespace test-ns1 中的 Label nginx-ns1 的 Pods 去(egress 出站)请求 Namespace test-ns2 的 ClusterIP Service 10.96.0.12。
Network Policy 支持在 Ingress Rule 的 from 或 Egress Rule 的 to 部分中指定 4 种 Selectors(选择器):
namespaceSelector:此选择器将选择特定的名字空间,应将所有 Pod 用作其 入站流量来源或出站流量目的地。
namespaceSelector 和 podSelector:一个指定 namespaceSelector 和 podSelector 的 to/from 条目选择特定名字空间中的特定 Pod。 注意使用正确的 YAML 语法;下面的策略:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
spec:
podSelector: # 规则对具有 role=db 标签的 Pod 生效
matchLabels:
role: db
ingress: # 表示入规则
- from:
- namespaceSelector: # 只允许具有 project=myproject 标签的命名空间中的 Pod 访问
matchLabels:
project: myproject
ports: # 只能使用 TCP 协议访问 6379 端口
- protocol: TCP
port: 6379
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
policyTypes:
- Ingress
- Egress
podSelector: # 规则对具有 role=db 标签的 Pod 生效
matchLabels:
role: db
ingress: # 表示入规则
- from:
- podSelector: # 只允许具有 role=frontend 标签的 Pod 访问
matchLabels:
role: frontend
ports: # 只能使用 TCP 协议访问 6379 端口
- protocol: TCP
port: 6379
egress: