适用场景
NetworkPolicy 微隔离适用于以下典型场景:
- 多团队共用一个 Kubernetes 集群,需要限制不同命名空间之间的互访;
- 数据库、Redis 等敏感服务只允许特定后端 Pod 访问,避免集群内任意 Pod 都能连接;
- 降低攻击面:一旦某个 Pod 被入侵,阻止攻击者向集群内其他服务横向移动;
- 替换传统防火墙思路,实现以标签为中心的 Pod 级访问控制。
前置条件
- Kubernetes 1.25+ 集群,且 CNI 插件支持 NetworkPolicy(Calico、Cilium、Weave Net 均支持;Flannel 不支持,策略会创建成功但不生效);
- 本地已安装 kubectl 并具备集群管理员权限;
- 测试用镜像:busybox、nginx 等;
- 执行以下命令确认网络策略能力:
kubectl get pods -n kube-system | grep -E "calico|cilium|weave"。
原理说明
NetworkPolicy 是 Kubernetes 原生的网络访问控制 API。它的核心规则是:一旦某个 Pod 被 NetworkPolicy 选中,该 Pod 就进入”默认拒绝”状态——所有未被策略显式放行的 ingress(入站)和 egress(出站)流量都会被丢弃。策略通过三种选择器划定范围:
- podSelector:按标签选择同命名空间内的目标 Pod;
- namespaceSelector:按标签选择允许互访的命名空间;
- ipBlock:按 CIDR 网段放行或排除外部 IP。
策略由 CNI 插件在节点层面转化为 iptables/eBPF 规则执行,因此不依赖 Pod 内任何进程,容器无法绕过。
操作步骤
1. 部署演示应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
labels:
app: backend
spec:
replicas: 1
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
selector:
app: backend
ports:
- port: 80
2. 默认拒绝所有出入流量
先对 demo 命名空间实施全量默认拒绝,作为安全基线:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: demo
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
podSelector 为空({})表示选中命名空间内全部 Pod,policyTypes 同时包含 Ingress 和 Egress。
3. 放行 DNS 解析
默认拒绝会切断所有出站流量,必须先放行 DNS,否则服务无法解析域名:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: demo
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
4. 仅允许 frontend 访问 backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: demo
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80
5. 按网段放行外部来源(可选)
如需允许办公网段访问某个服务,使用 ipBlock:
ingress:
- from:
- ipBlock:
cidr: 10.20.0.0/16
except:
- 10.20.5.0/24
except 字段用于在 CIDR 内排除例外网段。
配置验证
# 前端 Pod 访问 backend:应返回 nginx 欢迎页
kubectl -n demo run test-front --image=busybox -l app=frontend --rm -it --restart=Never -- wget -qO- --timeout=3 http://backend
# 未打 frontend 标签的 Pod 访问:应超时失败
kubectl -n demo run test-other --image=busybox --rm -it --restart=Never -- wget -qO- --timeout=3 http://backend
第一条命令返回 HTML 内容、第二条超时,即说明策略生效。也可用 kubectl -n demo describe networkpolicy allow-frontend-to-backend 检查策略解析结果。
常见问题
FAQ 1:策略创建成功但完全不生效?
最常见原因是 CNI 插件不支持 NetworkPolicy(如 Flannel)。用 kubectl get pods -n kube-system 确认插件类型;不支持时需更换为 Calico 或 Cilium。此外检查标签拼写是否与 podSelector 完全一致。
FAQ 2:应用 DNS 解析失败、健康检查被切断?
默认拒绝策略会拦截所有出站流量。务必保留 allow-dns 策略放行 kube-system 的 53 端口;若使用 kubelet 探针,探针流量不受 NetworkPolicy 影响,但应用访问外部 API 需要单独放行 egress 规则。
总结
NetworkPolicy 通过”默认拒绝 + 白名单放行”的模型,为 Kubernetes 集群提供了原生、声明式的微隔离能力。落地时的关键顺序是:先部署 default-deny-all 基线,再逐条放行 DNS 与业务互访,最后用真实 Pod 验证正反两个方向的连通性。策略随 Pod 标签动态匹配,扩缩容无需额外维护规则,是云原生环境中最经济的东西向流量防护手段。