Kubernetes网络策略配置实战指南(从零到生产级防护)
目录导读
-
什么是Kubernetes网络策略?为什么必须配置?

-
网络策略的核心概念与工作原理
-
零基础:创建一个简单的Deny-All策略
-
实战案例:允许特定Pod访问(基于标签选择器)
-
进阶配置:对Ingress/Egress流量的精确控制
-
常见问题与排查技巧(附问答)
-
生产环境网络策略最佳实践
什么是Kubernetes网络策略?为什么必须配置?
问题: 我的Pod之间默认可以互相通信,这有什么风险?
解答: Kubernetes默认“全通”网络模型意味着集群内任意Pod都能访问其他Pod的服务,这带来了严重的安全隐患:一旦某个Pod被攻破,攻击者可以横向移动访问数据库、缓存等敏感服务,网络策略(NetworkPolicy)正是为了解决这个问题——它通过定义“哪些Pod可以访问哪些Pod/端口”,实现租户隔离、微服务安全防护和数据流控制,不配置网络策略的Kubernetes集群,等同于在互联网上裸奔。
网络策略的核心概念与工作原理
关键对象:
- PodSelector:目标Pod(被访问方)的选择器,基于标签匹配。
- Ingress规则:定义“哪些源对象”可以访问本Pod(入站流量)。
- Egress规则:定义“本Pod可以访问哪些目标”的出口流量。
- 策略类型:务必手动指定
podSelector: {}为“选择所有Pod”或具体标签。 - 命名空间选择器:跨命名空间访问控制(
namespaceSelector)。
工作原理:
每个命名空间默认没有网络策略,流量全部允许,当你创建一条NetworkPolicy并绑定到某个Pod组时,该Pod的所有流量将默认拒绝,只有规则中显式允许的流量才通过(白名单模式),注意:网络策略依赖CNI插件支持,如Calico、Cilium、Weave等,Flannel默认不支持。
零基础:创建一个简单的Deny-All策略
场景: 禁止所有Pod入站和出站流量(隔离整个命名空间)。
配置示例:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: production
spec:
podSelector: {} # 匹配该命名空间所有Pod
policyTypes:
- Ingress
- Egress
# 没有ingress和egress规则 → 默认全部拒绝
验证命令:
kubectl apply -f deny-all.yaml kubectl describe networkpolicy deny-all -n production
效果: 立刻阻止所有Pod间的双向通信,但不要忘记后续必须添加白名单规则,否则服务不可用。
实战案例:允许特定Pod访问(基于标签选择器)
需求: 只允许前端Pod(标签tier: frontend)访问后端Pod(标签app: backend)的8080端口。
前端Pod(源): 无需单独声明,只需在后端Pod的策略中定义入站规则。
后端Pod的策略文件:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
常见错误: 忘记写ports导致所有端口开放,或漏写namespaceSelector导致跨命名空间访问失败。
验证方法: 进入前端Pod执行curl <backend-pod-ip>:8080,确认能访问;再随机进入其他Pod访问同一地址,应超时。
进阶配置:对Ingress/Egress流量的精确控制
Egress示例:限制Pod只能访问外部的api.example.com:
spec:
egress:
- to:
- ipBlock:
cidr: 203.0.113.0/24 # 目标IP段
ports:
- port: 443
跨命名空间访问: 使用namespaceSelector和podSelector组合:
ingress:
- from:
- namespaceSelector:
matchLabels:
env: staging
podSelector: # 必须同时指定两个选择器,才能限制为“某个命名空间下的特定Pod”
matchLabels:
role: monitor
ports:
- port: 9090
注意: namespaceSelector和podSelector为“与”关系,表示“来自名称空间staging下,且标签为role=monitor的Pod”。
常见问题与排查技巧(附问答)
Q1:我创建了策略,但Pod之间依然可以互相访问?
A: 可能原因:
- CNI插件不支持(换Calico/Cilium)。
- 策略中未指定
policyTypes字段,导致默认不生效。 - PodSelector写错了标签名,不影响任何Pod。
- 多策略共存时未注意优先级(实际上所有策略并集生效)。
Q2:删除网络策略后,流量立刻恢复吗?
A: 是的,删除策略后该Pod立刻回到“全允许”状态,但注意这可能是安全漏洞。
Q3:如何查看当前生效的策略?
命令: kubectl get networkpolicies --all-namespaces
kubectl describe networkpolicy <policy-name>
Q4:为什么我的Egress规则无法访问集群外部?
A: 检查是否同时有Deny-All Egress策略,并且未添加允许出口到0.0.0/0的规则,生产环境建议:保留默认Deny-All,再针对特定目标白名单。
生产环境网络策略最佳实践
- 命名空间预隔离: 为每个命名空间创建一个默认Deny-All策略,然后逐步添加白名单。
- 分层设计: 按应用层(前端-后端-数据层)设计策略,避免“大而全”的单一策略。
- 使用命名空间标签: 通过
namespaceSelector实现组织级隔离(如dev/staging/prod互不访问)。 - 结合服务网格: 网络策略与Istio等Service Mesh的授权策略互补,后者提供更细粒度的HTTP路径级控制。
- 日志与监控: 开启CNI插件的流量日志(如Calico的Felix),用于稽核策略效果。
- 自动化测试: 在CI/CD中集成网络策略的单元测试,防止变更导致服务中断。
Kubernetes网络策略是实现零信任网络的基础工具,从简单的Deny-All开始,逐步精确控制流量,才能构建安全、可审计的容器网络,如果你刚开始接触,建议先在非生产环境用kubectl run创建测试Pod演练策略效果,再逐步应用到生产环境。
(全文完)