Imported from killvxk/cybersecurity-skills-zh (
skills/implementing-network-policies-for-kubernetes/SKILL.md). Install upstream withnpx skills add killvxk/cybersecurity-skills-zh --skill implementing-network-policies-for-kubernetes. Copyright stays with the author (Apache-2.0).
为 Kubernetes 实施网络策略
概述
Kubernetes NetworkPolicy(网络策略)是实现集群内 Pod 间通信安全的原生机制。通过定义精细的入站(Ingress)和出站(Egress)规则,可以强制执行最小权限原则并防止横向移动(Lateral Movement)。本技能涵盖默认拒绝(Default Deny)模式的实施、应用特定策略配置、跨命名空间隔离以及出站限制,使用 Calico、Cilium 或 Antrea 等 CNI 插件。
前置条件
- 已运行的 Kubernetes 集群(1.20+)
- 支持 NetworkPolicy 的 CNI 插件(Calico、Cilium、Antrea 或 Weave)
- kubectl CLI 工具,具有集群管理权限
- 了解 Kubernetes Pod、Namespace、Label 和 Selector 的基本概念
- 集群中已部署应用(用于测试策略)
核心概念
策略类型
| 类型 | 说明 | 用途 |
|---|---|---|
| Ingress(入站) | 控制到 Pod 的入站流量 | 限制哪些来源可以访问 Pod |
| Egress(出站) | 控制从 Pod 发出的流量 | 限制 Pod 可以访问哪些目标 |
| 默认拒绝 | 隐式拒绝所有未匹配流量 | 零信任(Zero Trust)基础 |
选择器类型
- podSelector - 根据 Label 匹配同一命名空间中的 Pod
- namespaceSelector - 匹配整个命名空间中的 Pod
- ipBlock - 基于 CIDR 范围匹配外部 IP
CNI 插件支持
| 插件 | NetworkPolicy | 扩展策略 | eBPF |
|---|---|---|---|
| Calico | 是 | GlobalNetworkPolicy | 否 |
| Cilium | 是 | CiliumNetworkPolicy | 是 |
| Antrea | 是 | ClusterNetworkPolicy | 否 |
| Weave | 是 | 否 | 否 |
实施步骤
步骤 1:验证 CNI 插件支持
# 检查已安装的 CNI 插件
kubectl get pods -n kube-system | grep -E "calico|cilium|antrea|weave"
# 验证 NetworkPolicy 支持(测试策略)
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-policy
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
EOF
kubectl delete networkpolicy test-policy
步骤 2:为每个命名空间实施默认拒绝策略
# default-deny-all.yaml - 拒绝所有入站和出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {} # 匹配命名空间中的所有 Pod
policyTypes:
- Ingress
- Egress
# 为关键命名空间应用默认拒绝策略
for ns in production staging default; do
kubectl apply -f default-deny-all.yaml -n $ns
done
# 验证策略已应用
kubectl get networkpolicies --all-namespaces
步骤 3:允许必要的 DNS 出站流量
# allow-dns-egress.yaml - 允许 Pod 进行 DNS 解析
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
步骤 4:配置应用特定策略
三层应用(前端 → 后端 → 数据库)示例:
# frontend-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
namespace: production
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0 # 允许外部流量访问前端
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 80
egress:
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8080
- ports: # DNS
- protocol: UDP
port: 53
---
# backend-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- ports: # DNS
- protocol: UDP
port: 53
---
# database-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
egress:
- ports: # 仅 DNS
- protocol: UDP
port: 53
步骤 5:配置跨命名空间策略
# allow-monitoring.yaml - 允许监控命名空间抓取指标
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring-scrape
namespace: production
spec:
podSelector: {} # 应用到所有 Pod
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
- protocol: TCP
port: 8080
# 为监控命名空间添加 Label
kubectl label namespace monitoring kubernetes.io/metadata.name=monitoring
步骤 6:实施出站限制
# restrict-egress.yaml - 限制后端服务的出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-egress-restrict
namespace: production
spec:
podSelector:
matchLabels:
app: backend-service
policyTypes:
- Egress
egress:
# 允许访问同命名空间内的数据库
- to:
- podSelector:
matchLabels:
tier: database
ports:
- protocol: TCP
port: 5432
# 允许访问外部 API(特定 CIDR)
- to:
- ipBlock:
cidr: 10.0.0.0/8
except:
- 10.0.10.0/24 # 排除敏感子网
ports:
- protocol: TCP
port: 443
# 允许 DNS
- ports:
- protocol: UDP
port: 53
步骤 7:阻断云元数据端点访问
# block-metadata.yaml - 阻断 AWS/GCP 实例元数据服务
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: block-cloud-metadata
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32 # AWS/GCP 元数据
- 100.100.100.200/32 # Alibaba Cloud 元数据
监控与验证
测试策略
# 测试 Pod 间连通性
kubectl exec -it frontend-pod -n production -- curl http://backend-service:8080
# 验证被阻断的连接
kubectl exec -it frontend-pod -n production -- curl http://database-service:5432
# 应该超时或被拒绝
# 使用 netcat 测试端口连通性
kubectl exec -it test-pod -- nc -zv backend-service 8080
查看策略
# 列出所有命名空间的策略
kubectl get networkpolicies --all-namespaces
# 查看特定策略详情
kubectl describe networkpolicy backend-policy -n production
# 以 YAML 格式导出策略
kubectl get networkpolicy -n production -o yaml
最佳实践
- 先默认拒绝 - 从拒绝所有流量开始,然后根据需要开放
- 按命名空间隔离 - 为每个环境(生产、暂存)使用独立命名空间
- 精确使用 Label - 为策略选择器设计一致的 Label 命名规范
- 始终允许 DNS - 不要忘记在出站策略中开放 UDP 53 端口
- 测试再部署 - 在非生产环境中验证策略
- 版本控制策略 - 将所有 NetworkPolicy YAML 存入 Git 仓库
- 监控流量 - 使用 CNI 插件的可观测性功能检测策略违规