Kubernetes 网络策略(NetworkPolicy)完全指南:声明式 Pod 通信管控
1. Before you begin(前置条件)
1.1 核心要求
-
Kubernetes 集群需支持 NetworkPolicy API(Kubernetes 1.7+ 版本默认支持)。
-
部署支持网络策略的网络插件(以下按字母排序,无推荐优先级):
-
Calico
-
Romana
-
Weave 网络
-
本文示例适用于所有上述网络插件,无需修改配置即可直接使用。
2. 创建 Nginx Deployment 并暴露服务
作为演示目标,先创建被访问的 Nginx 服务(后续通过网络策略限制其访问权限):
2.1 部署 Nginx 应用
# 创建 Deployment(2 个副本)
$ kubectl run nginx --image=nginx --replicas=2
# 暴露 Service(ClusterIP 类型,端口 80)
$ kubectl expose deployment nginx --port=80
2.2 验证资源状态
$ kubectl get svc,pod
# 预期输出(确认 Nginx Pod 运行正常、Service 已创建)
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kubernetes 10.100.0.1 443/TCP 46m
svc/nginx 10.100.0.16 0/TCP 33s
NAME READY STATUS RESTARTS AGE
po/nginx-701339712-e0qfq 1/1 Running 0 35s
po/nginx-701339712-o00ef 1/1 Running 0 35s
3. 测试服务能够被其它 Pod 访问
默认情况下,Kubernetes 集群内 Pod 可自由通信。验证无网络策略时,其他 Pod 能否访问 Nginx 服务:
# 启动临时 busybox Pod(执行后进入交互终端)
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
# 在交互终端中测试访问 Nginx Service(--spider 仅检查连通性,不下载内容)
/ # wget --spider --timeout=1 nginx
# 成功输出:Connecting to nginx (10.100.0.16:80)(无超时)
结论:无网络策略时,任意 Pod 可访问 Nginx 服务。
4. 限制访问 Nginx 服务(创建 NetworkPolicy)
通过 NetworkPolicy 定义规则:仅允许带有 access: "true" 标签的 Pod 访问 Nginx 服务。
4.1 编写 NetworkPolicy 配置文件
创建 nginx-policy.yaml,内容如下:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1 # 核心 API 版本(必填)
metadata:
name: access-nginx # 网络策略名称
spec:
podSelector: # 目标 Pod 选择器(指定保护哪些 Pod)
matchLabels:
run: nginx # 匹配 Nginx Pod 的标签(与 Deployment 一致)
ingress: # 入站规则(允许哪些流量进入目标 Pod)
- from:
- podSelector: # 来源 Pod 选择器(仅允许带以下标签的 Pod 访问)
matchLabels:
access: "true" # 允许标签:access=true
4.2 核心字段说明
| 字段 | 作用 |
|---|---|
podSelector |
定义策略作用的目标 Pod(通过标签匹配),本文中为 Nginx Pod |
ingress.from.podSelector |
定义允许访问的来源 Pod(通过标签匹配),本文中为带 access: true 的 Pod |
apiVersion |
必须指定为 networking.k8s.io/v1(标准稳定版 API) |
5. 为服务指定策略(应用 NetworkPolicy)
执行以下命令创建网络策略:
$ kubectl create -f nginx-policy.yaml
# 成功输出:networkpolicy "access-nginx" created
# 验证策略是否生效
$ kubectl get networkpolicy
NAME POD-SELECTOR AGE
access-nginx run=nginx 10s
6. 当访问标签没有定义时测试访问服务
验证无 access: true 标签的 Pod 是否被拒绝访问:
# 启动无标签的 busybox Pod(交互模式)
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
# 测试访问 Nginx 服务
/ # wget --spider --timeout=1 nginx
# 失败输出:wget: download timed out(请求超时,策略生效)
结论:无指定标签的 Pod 被网络策略拦截,无法访问 Nginx 服务。
7. 定义访问标签后再次测试
验证带有 access: true 标签的 Pod 是否允许访问:
# 启动带标签的 busybox Pod(--labels 指定标签)
$ kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh
# 测试访问 Nginx 服务
$ wget --spider --timeout=1 nginx
# 成功输出:Connecting to nginx (10.100.0.16:80)(无超时,访问允许)
结论:符合标签条件的 Pod 可正常访问 Nginx 服务,网络策略按预期生效。
扩展:NetworkPolicy 核心能力补充
1. 更多规则配置示例
-
允许特定命名空间的 Pod 访问:
ingress:
-
from:
-
namespaceSelector: # 匹配命名空间标签
matchLabels:
environment: production
-
-
允许特定 IP 段访问:
ingress:
-
from:
-
ipBlock:
cidr: 192.168.0.0/16 # 允许的 IP 段
except:
- 192.168.1.0/24 # 排除的 IP 段
-
-
限制特定端口访问:
ingress:
-
ports:
-
protocol: TCP
port: 80 # 仅允许 80 端口访问(拒绝其他端口)
from:
-
podSelector:
matchLabels:
access: "true"
-
2. 关键注意事项
-
默认行为:无网络策略时,Pod 可接收所有入站流量;创建网络策略后,仅允许策略中明确允许的流量。
-
出站规则 :除了
ingress(入站),还可通过egress定义 Pod 的出站流量规则(限制 Pod 访问外部资源)。 -
标签匹配 :
podSelector和namespaceSelector支持复杂标签匹配(如matchExpressions),满足多条件筛选需求。
总结
Kubernetes NetworkPolicy 提供了声明式的 Pod 通信管控能力,核心价值在于:
-
实现 Pod 间的访问隔离,提升集群安全性(如限制数据库 Pod 仅允许应用 Pod 访问)。
-
按标签、命名空间、IP 段等维度灵活定义规则,适配复杂业务场景。
-
与网络插件解耦,无需修改应用代码,仅通过 YAML 配置即可生效。
建议在生产环境中为核心服务(如数据库、缓存、API 服务)配置网络策略,最小化访问权限,降低安全风险。