K8s 网络策略与服务网格:集群内流量管控,从默认全通到精细隔离
一、K8s 默认网络的零信任缺失:Pod 间无隔离的安全隐患
Kubernetes 集群默认允许所有 Pod 之间自由通信,这在开发环境便利但在生产环境是严重安全隐患。攻击者一旦突破一个 Pod,即可横向移动到集群内任何服务。金融、医疗等合规场景要求严格的网络隔离——前端 Pod 不应直接访问数据库 Pod,不同租户的 Pod 之间必须隔离。
NetworkPolicy 是 K8s 原生的网络隔离机制,但功能有限(仅支持 L3/L4 层规则)。服务网格(Service Mesh)如 Istio 提供了 L7 层的流量管控能力,可以实现基于 HTTP 方法和路径的精细访问控制。
二、网络策略与服务网格的分层架构
flowchart TB A[入站流量] --> B[Ingress] B --> C[Service Mesh: L7 策略] C --> D[NetworkPolicy: L3/L4 策略] D --> E[Pod] subgraph L7 层管控 F[HTTP 方法限制: GET only] G[路径白名单: /api/*] H[请求头校验: X-Token] end subgraph L3/L4 层管控 I[IP 段白名单] J[端口限制] K[命名空间隔离] end C --> F C --> G C --> H D --> I D --> J D --> K最佳实践是两层联动:NetworkPolicy 做 L3/L4 粗粒度隔离(命名空间级、IP 段级),Service Mesh 做 L7 细粒度控制(HTTP 方法、路径、头)。
三、生产级配置:NetworkPolicy + Istio AuthorizationPolicy
# network-policy.yaml — K8s NetworkPolicy 配置 # 设计意图:实现命名空间级别的网络隔离, # 仅允许有明确授权的流量通过 # 默认拒绝所有入站流量 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress namespace: production spec: podSelector: {} # 匹配所有 Pod policyTypes: - Ingress # 无 ingress 规则 = 拒绝所有入站 --- # 允许前端访问后端 API apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-frontend-to-api namespace: production spec: podSelector: matchLabels: app: api-server policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: frontend ports: - port: 8080 protocol: TCP --- # 允许 API 访问数据库(仅限同一命名空间) apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-api-to-database namespace: production spec: podSelector: matchLabels: app: postgres policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: api-server ports: - port: 5432 protocol: TCP --- # 允许监控采集(Prometheus) apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-prometheus-scraping namespace: production spec: podSelector: {} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: name: monitoring podSelector: matchLabels: app: prometheus ports: - port: 9090 protocol: TCP# istio-authorization.yaml — Istio L7 授权策略 # 设计意图:在 L7 层实现基于 HTTP 方法和路径的精细访问控制 # 仅允许 GET 请求访问公开 API apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: api-server-read-only namespace: production spec: selector: matchLabels: app: api-server action: ALLOW rules: - to: - operation: methods: ["GET"] paths: ["/api/public/*"] # 写操作需要认证令牌 - to: - operation: methods: ["POST", "PUT", "DELETE"] paths: ["/api/*"] when: - key: request.headers[x-auth-token] notValues: [""] --- # 前端只能访问特定路径 apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: frontend-restricted-paths namespace: production spec: selector: matchLabels: app: api-server action: DENY rules: - from: - source: principals: ["cluster.local/ns/production/sa/frontend"] to: - operation: paths: ["/api/admin/*", "/api/internal/*"]四、Trade-offs:网络策略的性能与运维成本
NetworkPolicy 的 CNI 依赖。NetworkPolicy 的实际效果依赖 CNI 插件实现——Calico、Cilium 完整支持,Flannel 部分支持。选择 CNI 时需确认 NetworkPolicy 支持程度,否则策略配置了但不生效。
策略调试的困难。NetworkPolicy 拒绝的流量不会产生日志(在内核层面丢弃),排查"为什么 Pod A 无法访问 Pod B"需要逐一检查所有相关策略。建议使用kubectl exec在 Pod 内测试连通性,或使用 Cilium 的 Hubble 可视化网络流量。
服务网格的性能开销。Istio 的 Sidecar 代理在每个 Pod 中注入 Envoy,增加约 2—5ms 的请求延迟和约 100MB 的内存开销。对延迟敏感的服务(如交易系统)需评估是否可接受。替代方案:使用 Cilium 替代 Istio,基于 eBPF 在内核层实现 L7 策略,无 Sidecar 开销。
策略爆炸的管理成本。大规模集群中 NetworkPolicy 数量可能达到数百条,管理复杂度极高。建议使用策略生成工具(如 OPA/Gatekeeper)根据标签自动生成策略,而非手动编写每条规则。
五、总结
K8s 网络策略与服务网格是集群内流量管控的两层防线,NetworkPolicy 做 L3/L4 粗粒度隔离,Service Mesh 做 L7 细粒度控制。落地路径:第一步,部署支持 NetworkPolicy 的 CNI(推荐 Cilium),实现默认拒绝策略;第二步,按服务依赖关系逐步开放必要的通信路径;第三步,引入 Istio 或 Cilium 的 L7 授权策略,实现基于 HTTP 方法和路径的访问控制;第四步,建立策略的自动化测试和审计流程。核心原则:默认拒绝,按需开放——每条允许规则都应有明确的业务理由。