在Kubernetes集群中,Pod之间默认是完全互通的------无论是同一命名空间内的Pod,还是不同命名空间的Pod,都能自由发起网络请求。这种"无隔离"的模式在开发环境可能没问题,但在生产环境中,会带来严重的安全风险:比如前端Pod被入侵后,攻击者可直接访问后端数据库Pod,造成数据泄露。
而Kubernetes网络策略(NetworkPolicy),就是解决这个问题的核心工具------它像集群内部的"防火墙",通过定义规则,精准控制Pod的入站(Ingress)和出站(Egress)流量,实现Pod间的网络隔离与访问控制。
本文将从"是什么→为什么用→怎么用→怎么验证→踩坑总结",带你从零吃透NetworkPolicy,全程搭配实操命令和配置示例,新手也能跟着上手实践。
一、先搞懂:NetworkPolicy 核心基础
1. 什么是NetworkPolicy?
NetworkPolicy是Kubernetes的一种资源对象,用于定义Pod之间、Pod与外部网络之间的流量规则。它的核心作用是:通过"选择器"匹配目标Pod,通过"流量规则"允许/拒绝特定流量。
关键注意点:
-
NetworkPolicy仅对"被选中的Pod"生效,未被任何策略选中的Pod,依然保持默认互通。
-
策略的规则是"白名单模式"------默认拒绝所有流量,只有明确允许的流量才能通过(除非策略明确配置"允许所有")。
-
NetworkPolicy依赖CNI插件支持(如Calico、Cilium、Flannel+),如果你的集群CNI不支持,创建策略也不会生效(这是新手最常踩的坑之一)。
2. 为什么必须用NetworkPolicy?
举3个生产环境中最常见的场景,帮你理解其必要性:
-
安全隔离:数据库Pod仅允许后端服务Pod访问,拒绝前端Pod、测试Pod的请求,防止数据泄露。
-
环境隔离:开发环境的Pod不能访问生产环境的Pod,避免测试操作影响生产服务。
-
流量管控:限制Pod只能访问指定的外部接口(如仅允许访问第三方支付接口),禁止访问无关外网地址。
简单说:没有NetworkPolicy,Kubernetes集群的网络就像"不设防的小区",任何人都能随意进出;有了NetworkPolicy,就能实现"分区管控、按需放行",提升集群安全性。
3. NetworkPolicy 核心组成部分
任何一个NetworkPolicy配置文件,都包含4个核心部分,理解这4部分,就能读懂所有策略:
| 组成部分 | 作用 | 示例 |
|---|---|---|
| podSelector | 选择"要应用策略的Pod",通过标签匹配 | podSelector: { matchLabels: { app: nginx } }(匹配所有app=nginx的Pod) |
| policyTypes | 指定策略管控的流量类型,可选Ingress(入站)、Egress(出站) | policyTypes: [Ingress, Egress](同时管控入站和出站) |
| ingress | 定义"允许进入Pod的流量"规则(来源、端口) | 允许来自app=backend的Pod,访问80端口 |
| egress | 定义"允许Pod发出的流量"规则(目标、端口) | 允许访问外部IP为10.0.0.10,端口3306(数据库) |
补充:podSelector为空(podSelector: {})时,表示匹配"当前命名空间内的所有Pod";如果需要跨命名空间匹配,可使用namespaceSelector。
二、实操必备:5个常用NetworkPolicy配置示例
以下所有示例均基于「Calico CNI」(最常用的CNI之一),配置文件可直接复制使用,注释已写清楚,新手可直接上手测试。
提示:所有策略均作用于「default命名空间」,如果需要作用于其他命名空间,可在metadata中添加namespace字段。
示例1:默认拒绝所有入站流量(default-deny-ingress)
最基础、最常用的策略之一:拒绝当前命名空间内所有Pod的入站流量,即所有Pod都无法被其他Pod访问(但Pod可主动发起出站请求)。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress # 策略名称,自定义
namespace: default # 策略作用的命名空间
spec:
podSelector: {} # 匹配当前命名空间所有Pod
policyTypes:
- Ingress # 仅管控入站流量
# 没有定义ingress规则 → 默认拒绝所有入站流量
应用命令:kubectl apply -f default-deny-ingress.yaml
示例2:允许所有入站流量(allow-all-ingress)
与示例1相反,允许当前命名空间内所有Pod接收来自任何来源的入站流量,等价于"关闭入站隔离",恢复Pod默认互通状态。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
namespace: default
spec:
podSelector: {}
ingress:
- {} # 空规则表示允许所有入站流量
policyTypes:
- Ingress
示例3:默认拒绝所有出站流量(default-deny-egress)
拒绝当前命名空间内所有Pod的出站流量,即所有Pod都无法主动访问其他Pod、外部网络(但可接收入站请求)。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress # 仅管控出站流量
# 没有定义egress规则 → 默认拒绝所有出站流量
示例4:允许所有出站流量(allow-all-egress)
允许当前命名空间内所有Pod向任何目标发起出站请求,等价于"关闭出站隔离"。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
namespace: default
spec:
podSelector: {}
egress:
- {} # 空规则表示允许所有出站流量
policyTypes:
- Egress
示例5:精准管控(最实用)------ 仅允许后端Pod访问数据库Pod
生产环境最常用的场景:假设我们有两类Pod------backend(后端服务,标签app=backend)、db(数据库,标签app=db,端口3306),要求:仅允许backend Pod访问db Pod的3306端口,拒绝其他所有Pod访问。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-db
namespace: default
spec:
podSelector:
matchLabels:
app: db # 策略应用于db Pod(管控谁的入站流量)
policyTypes:
- Ingress
ingress:
- from: # 允许的流量来源
- podSelector:
matchLabels:
app: backend # 仅允许app=backend的Pod访问
ports: # 允许访问的端口
- protocol: TCP
port: 3306 # db Pod的数据库端口
说明:这个策略是"作用于db Pod",管控db Pod的入站流量,只有backend Pod能访问它的3306端口,其他Pod(如frontend)的请求会被拒绝。
三、关键实操:如何验证NetworkPolicy是否生效?
很多新手创建策略后,不知道怎么确认策略是否生效,这里以「示例1:default-deny-ingress」为例,教你完整的验证流程(通用所有策略)。
核心原则:NetworkPolicy仅管控Pod与Pod之间的流量,节点与Pod之间的流量默认不受管控(这是新手最容易混淆的点!)。
验证步骤(全程实操)
-
应用策略
kubectl apply -f default-deny-ingress.yaml ``# 确认策略已创建 ``kubectl get networkpolicies # 简称:kubectl get netpol输出中能看到default-deny-ingress,说明策略创建成功。 -
创建两个测试Pod (均在default命名空间,用nginx镜像,自带curl工具)
# 创建pod-a(作为被访问方) ``kubectl run pod-a --image=nginx ``# 创建pod-b(作为访问方) ``kubectl run pod-b --image=nginx等待Pod状态变为Running:kubectl get pods -
获取被访问方Pod的IP
# 获取pod-a的IP(假设为10.244.140.75) ``POD_A_IP=$(kubectl get pod pod-a -o jsonpath='{.status.podIP}') ``echo $POD_A_IP # 输出Pod IP,后续使用 -
在pod-b中访问pod-a(Pod到Pod流量,受策略管控)
kubectl exec -it pod-b -- curl --connect-timeout 5 $POD_A_IP✅ 预期结果:请求超时(curl: (28) Connection timed out),说明入站流量被策略拦截,策略生效。 -
对比验证(删除策略,确认流量恢复)
# 删除策略 ``kubectl delete netpol default-deny-ingress ``# 再次在pod-b中访问pod-a ``kubectl exec -it pod-b -- curl --connect-timeout 5 $POD_A_IP✅ 预期结果:返回nginx默认页面的HTML内容,说明流量恢复正常,进一步确认策略之前确实生效。
常见验证误区
❌ 误区1:在集群节点(如master节点)上执行curl Pod IP,期望被拦截。
原因:节点与Pod之间的流量,默认不受NetworkPolicy管控,即使策略拒绝所有入站,节点访问Pod依然能成功。
❌ 误区2:Pod状态为Running,就认为能正常访问。
原因:Pod Running仅表示容器启动成功,若镜像精简(如部分busybox镜像),可能缺少curl、wget工具,导致无法执行测试命令,可换用nginx或busybox:1.36镜像。
四、新手必踩的5个坑及解决方案
结合我自己学习和实操的经历,整理了新手最常遇到的问题,每个问题都附解决方案,帮你少走弯路。
坑1:创建策略后,流量依然互通/被拒绝,策略不生效
✅ 解决方案:
-
检查CNI插件是否支持NetworkPolicy:Flannel默认不支持,需替换为Calico、Cilium,或安装Flannel的扩展插件。
-
检查策略的namespace是否正确:策略仅作用于自身所在的命名空间,跨命名空间的策略不生效。
-
检查podSelector是否匹配目标Pod:标签是否正确(如app=nginx,不要写错为app=ngnix),空selector匹配所有Pod。
坑2:执行kubectl exec时,提示"container not found"
✅ 解决方案:
-
检查Pod名称是否正确:用kubectl get pods查看准确的Pod名称,避免手动输入错误。
-
检查Pod状态是否为Running:若为ContainerCreating或CrashLoopBackOff,等待Pod就绪或重新创建。
-
显式指定容器名称:kubectl exec -it pod-b -c pod-b -- curl ...(单容器Pod可省略,但显式指定更稳妥)。
坑3:策略配置正确,但部分流量依然能通过
✅ 解决方案:
-
检查是否有多个NetworkPolicy作用于同一个Pod:多个策略的规则会"叠加",只要有一个策略允许某类流量,该流量就会通过。
-
检查流量类型是否在policyTypes中:若策略只配置了Ingress,則出站流量不受管控;反之亦然。
坑4:跨命名空间的Pod无法访问,即使配置了策略
✅ 解决方案:
默认策略仅匹配当前命名空间的Pod,跨命名空间访问需在ingress.from中添加namespaceSelector,示例:
ingress:
- from:
- podSelector:
matchLabels:
app: backend
namespaceSelector: # 匹配指定命名空间的Pod
matchLabels:
name: dev-namespace
坑5:删除策略后,流量依然被拦截
✅ 解决方案:
-
检查是否有其他默认拒绝策略:如default-deny-all,若存在,需同时删除。
-
重启Pod:部分CNI插件(如Calico)在策略删除后,需重启Pod才能恢复流量(kubectl rollout restart pod xxx)。
五、学习总结与进阶方向
1. 核心总结
-
NetworkPolicy是Kubernetes集群内部的"防火墙",核心是"匹配Pod + 管控流量"。
-
规则是白名单模式:默认拒绝所有流量,仅允许明确配置的流量通过。
-
仅管控Pod与Pod之间的流量,节点与Pod之间的流量默认不受管控。
-
常用策略:默认拒绝入站/出站、允许所有入站/出站、精准管控Pod间访问(生产核心)。
2. 进阶学习方向
如果想深入掌握NetworkPolicy,可继续学习以下内容:
-
复杂规则配置:结合namespaceSelector、ipBlock(管控外部IP)、端口范围等。
-
CNI插件与NetworkPolicy的联动:如Calico的策略日志、流量可视化。
-
生产环境最佳实践:如按命名空间隔离、按服务层级配置策略、策略的版本控制与备份。
-
高级特性:如Egress流量的DNS匹配、策略的优先级配置。
最后
NetworkPolicy看似简单,但实操中容易踩坑,建议新手先从本文的5个示例入手,亲手应用、验证,理解"Pod选择器"和"流量规则"的关联,再逐步尝试复杂场景。
记住:网络策略的核心是"最小权限原则"------只允许必要的流量通过,拒绝所有无关流量,这样才能最大化提升Kubernetes集群的安全性。
后续我会继续更新NetworkPolicy的进阶实操(如Calico策略日志、跨命名空间管控),关注我,一起吃透Kubernetes!
如果本文对你有帮助,欢迎点赞、收藏、转发,若有疑问,可在评论区留言,我会逐一回复~