网络策略
概述
NetworkPolicy是Kubernetes中用于控制Pod之间网络流量的资源对象。它允许你定义细粒度的网络访问规则,实现Pod级别的网络隔离和安全控制。NetworkPolicy通过标签选择器来选择Pod,并定义允许的入站和出站流量规则。
NetworkPolicy核心功能
1. Pod网络隔离
- 基于标签选择器隔离Pod
- 控制入站流量(Ingress)
- 控制出站流量(Egress)
- 实现多租户网络隔离
2. 流量控制
- 基于Pod标签的访问控制
- 基于命名空间的访问控制
- 基于IP地址段的访问控制
- 基于端口的访问控制
3. 安全增强
- 实现零信任网络模型
- 限制横向移动攻击
- 保护敏感应用
- 满足合规要求
NetworkPolicy架构
┌─────────────────────────────────────────────────────────┐
│ NetworkPolicy │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Pod Selector: app=web │ │
│ │ Policy Types: Ingress, Egress │ │
│ └──────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────┘
│
┌────────────┴────────────┐
│ │
▼ ▼
┌───────────────┐ ┌──────────────┐
│ Ingress │ │ Egress │
│ (入站规则) │ │ (出站规则) │
└───────┬───────┘ └──────┬───────┘
│ │
│ │
▼ ▼
┌────────────────┐ ┌────────────────┐
│ 允许的来源 │ │ 允许的目标 │
│ - Pod选择器 │ │ - Pod选择器 │
│ - 命名空间 │ │ - 命名空间 │
│ - IP地址段 │ │ - IP地址段 │
│ - 端口 │ │ - 端口 │
└────────────────┘ └────────────────┘
│ │
│ │
▼ ▼
┌────────────────┐ ┌────────────────┐
│ 受保护的Pod │ │ 受保护的Pod │
│ (app=web) │◄─────┤ (app=web) │
└────────────────┘ └────────────────┘NetworkPolicy配置详解
1. 基本NetworkPolicy
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: basic-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 33062. 完整NetworkPolicy配置
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: complete-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: api
tier: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
podSelector:
matchLabels:
app: web
- ipBlock:
cidr: 192.168.1.0/24
except:
- 192.168.1.100/32
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8443
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 3306
- to:
- namespaceSelector:
matchLabels:
name: external-services
- ipBlock:
cidr: 10.0.0.0/8
ports:
- protocol: TCP
port: 443
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 533. 默认拒绝所有流量
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress4. 默认拒绝入站流量
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress5. 默认拒绝出站流量
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress6. 允许所有流量
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- {}
egress:
- {}NetworkPolicy规则详解
1. Pod选择器
yaml
spec:
podSelector:
matchLabels:
app: web
tier: frontend
matchExpressions:
- key: environment
operator: In
values:
- production
- staging2. 命名空间选择器
yaml
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production
environment: prod3. IP地址段选择器
yaml
spec:
ingress:
- from:
- ipBlock:
cidr: 192.168.0.0/16
except:
- 192.168.1.0/24
- 192.168.2.100/324. 组合选择器
yaml
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production
podSelector:
matchLabels:
app: frontend5. 端口配置
yaml
spec:
ingress:
- ports:
- protocol: TCP
port: 80
endPort: 8080
- protocol: UDP
port: 53操作命令
创建和管理NetworkPolicy
bash
# 创建NetworkPolicy
kubectl apply -f network-policy.yaml
# 查看NetworkPolicy
kubectl get networkpolicy
kubectl get netpol
# 查看详细信息
kubectl describe networkpolicy <policy-name>
# 查看YAML格式
kubectl get networkpolicy <policy-name> -o yaml
# 删除NetworkPolicy
kubectl delete networkpolicy <policy-name>
# 删除所有NetworkPolicy
kubectl delete networkpolicy --all -n <namespace>测试NetworkPolicy
bash
# 测试Pod间连接
kubectl run test --image=busybox --rm -it --restart=Never -- wget -O- http://<service-name>:<port>
# 测试特定Pod连接
kubectl exec -it <source-pod> -- wget -O- http://<target-service>:<port>
# 测试DNS解析
kubectl run test --image=busybox --rm -it --restart=Never -- nslookup kubernetes
# 测试外部连接
kubectl run test --image=curlimages/curl --rm -it --restart=Never -- curl http://example.com调试NetworkPolicy
bash
# 查看NetworkPolicy日志
kubectl logs -n kube-system -l k8s-app=<network-plugin>
# 查看网络插件状态
kubectl get pods -n kube-system -l k8s-app=<network-plugin>
# 检查NetworkPolicy是否生效
kubectl describe networkpolicy <policy-name>
# 查看Pod标签
kubectl get pods --show-labels
# 查看命名空间标签
kubectl get namespace --show-labels实践示例
示例1:多层应用网络隔离
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
namespace: production
spec:
podSelector:
matchLabels:
tier: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 8080
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: production
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
tier: database
ports:
- protocol: TCP
port: 3306
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
namespace: production
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 3306
egress:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53示例2:命名空间隔离
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: namespace-isolation
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production
egress:
- to:
- namespaceSelector:
matchLabels:
name: production
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53示例3:允许外部访问特定服务
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-access
namespace: production
spec:
podSelector:
matchLabels:
app: web
expose: external
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 192.168.0.0/16
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443示例4:数据库访问控制
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-access-control
namespace: database
spec:
podSelector:
matchLabels:
app: mysql
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production
podSelector:
matchLabels:
tier: backend
- namespaceSelector:
matchLabels:
name: staging
podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 3306
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: redis-access-control
namespace: database
spec:
podSelector:
matchLabels:
app: redis
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api
- podSelector:
matchLabels:
app: web
ports:
- protocol: TCP
port: 6379示例5:监控和日志访问
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-logging
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: logging
podSelector:
matchLabels:
app: elasticsearch
ports:
- protocol: TCP
port: 9200
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53示例6:多租户隔离
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tenant-a-isolation
namespace: tenant-a
spec:
podSelector:
matchLabels:
tenant: tenant-a
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tenant: tenant-a
egress:
- to:
- podSelector:
matchLabels:
tenant: tenant-a
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tenant-b-isolation
namespace: tenant-b
spec:
podSelector:
matchLabels:
tenant: tenant-b
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tenant: tenant-b
egress:
- to:
- podSelector:
matchLabels:
tenant: tenant-b
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53故障排查
常见问题
1. NetworkPolicy不生效
bash
# 检查网络插件是否支持NetworkPolicy
kubectl get pods -n kube-system -l k8s-app=<network-plugin>
# 检查NetworkPolicy是否创建
kubectl get networkpolicy -n <namespace>
# 检查NetworkPolicy配置
kubectl describe networkpolicy <policy-name> -n <namespace>
# 检查Pod标签
kubectl get pods -n <namespace> --show-labels
# 检查命名空间标签
kubectl get namespace --show-labels
# 查看网络插件日志
kubectl logs -n kube-system -l k8s-app=<network-plugin>2. Pod无法访问
bash
# 检查NetworkPolicy规则
kubectl describe networkpolicy -n <namespace>
# 测试Pod连接
kubectl run test --image=busybox --rm -it --restart=Never -- wget -O- http://<service-name>:<port>
# 检查Pod标签是否匹配
kubectl get pods -n <namespace> -l <label-key>=<label-value>
# 检查命名空间标签
kubectl get namespace <namespace> --show-labels
# 临时删除NetworkPolicy测试
kubectl delete networkpolicy <policy-name> -n <namespace>3. DNS解析失败
bash
# 检查DNS NetworkPolicy
kubectl get networkpolicy -n <namespace> -o yaml | grep -A 10 kube-dns
# 测试DNS解析
kubectl run test --image=busybox --rm -it --restart=Never -- nslookup kubernetes
# 检查DNS Pod标签
kubectl get pods -n kube-system -l k8s-app=kube-dns --show-labels
# 添加DNS允许规则
# 在NetworkPolicy的egress中添加:
# - to:
# - namespaceSelector: {}
# podSelector:
# matchLabels:
# k8s-app: kube-dns
# ports:
# - protocol: UDP
# port: 534. 外部访问被阻止
bash
# 检查egress规则
kubectl describe networkpolicy <policy-name> -n <namespace>
# 测试外部连接
kubectl run test --image=curlimages/curl --rm -it --restart=Never -- curl http://example.com
# 检查IP地址段配置
kubectl get networkpolicy <policy-name> -n <namespace> -o yaml | grep ipBlock -A 5
# 添加外部访问规则
# 在NetworkPolicy的egress中添加:
# - to:
# - ipBlock:
# cidr: 0.0.0.0/0
# except:
# - 10.0.0.0/8
# - 192.168.0.0/165. 跨命名空间访问失败
bash
# 检查命名空间标签
kubectl get namespace --show-labels
# 添加命名空间标签
kubectl label namespace <namespace> name=<namespace-name>
# 检查NetworkPolicy中的namespaceSelector
kubectl get networkpolicy <policy-name> -n <namespace> -o yaml | grep namespaceSelector -A 5
# 测试跨命名空间连接
kubectl exec -it <pod-name> -n <source-namespace> -- wget -O- http://<service-name>.<target-namespace>:<port>6. 性能问题
bash
# 检查NetworkPolicy数量
kubectl get networkpolicy --all-namespaces | wc -l
# 检查NetworkPolicy复杂度
kubectl get networkpolicy -n <namespace> -o yaml
# 查看网络插件性能
kubectl top pods -n kube-system -l k8s-app=<network-plugin>
# 检查网络插件日志
kubectl logs -n kube-system -l k8s-app=<network-plugin> --tail=100
# 简化NetworkPolicy规则
# 避免过于复杂的选择器和规则最佳实践
1. 网络隔离策略
- 默认拒绝所有流量
- 显式允许必要的流量
- 使用最小权限原则
- 定期审计网络策略
2. 命名空间规划
- 为命名空间添加标签
- 使用命名空间隔离不同环境
- 合理规划命名空间结构
- 文档化命名空间用途
3. 标签管理
- 使用一致的标签规范
- 为所有Pod添加必要标签
- 定期检查标签一致性
- 避免标签冲突
4. DNS访问
- 始终允许DNS访问
- 使用命名空间选择器
- 监控DNS查询
- 配置DNS缓存
5. 监控和日志
- 监控NetworkPolicy效果
- 记录网络访问日志
- 设置异常告警
- 定期审计策略
6. 测试和验证
- 测试所有网络策略
- 验证隔离效果
- 测试故障场景
- 文档化测试结果
7. 安全增强
- 实施零信任网络
- 限制横向移动
- 保护敏感应用
- 满足合规要求
8. 性能优化
- 简化NetworkPolicy规则
- 避免过于复杂的选择器
- 监控网络性能
- 优化规则顺序
NetworkPolicy支持的网络插件
1. Calico
- 完整的NetworkPolicy支持
- 支持高级网络策略
- 性能优秀
- 提供网络可视化和策略管理
2. Cilium
- 基于eBPF的高性能网络
- 完整的NetworkPolicy支持
- 支持七层网络策略
- 提供网络可视化和监控
3. Weave Net
- 完整的NetworkPolicy支持
- 简单易用
- 支持多主机网络
- 自动网络配置
4. Flannel
- 基本NetworkPolicy支持
- 需要配合Calico使用
- 简单轻量
- 适合小型集群
5. Kube-router
- 完整的NetworkPolicy支持
- 基于IPVS
- 性能良好
- 支持网络策略可视化
总结
NetworkPolicy是Kubernetes中实现网络安全隔离的关键组件。通过合理配置NetworkPolicy,可以实现细粒度的网络访问控制,保护应用安全,满足合规要求。理解NetworkPolicy的工作原理和最佳实践,对于构建安全的Kubernetes集群至关重要。