87·安全高级

网络策略

kubernetessecuritynetworknetworkpolicy

网络策略

学习目标

  1. 理解网络策略的重要性
  2. 掌握 NetworkPolicy 的配置方法
  3. 了解网络策略的最佳实践

核心概念

一句话解释

NetworkPolicy 控制 Pod 之间的网络通信,实现网络级别的访问控制。

默认网络行为

┌─────────────────────────────────────────────────────────────┐
│                    默认网络行为                              │
├─────────────────────────────────────────────────────────────┤
│  无 NetworkPolicy 时:                                      │
│  ├── 所有 Pod 可以互相通信                                   │
│  ├── 所有 Pod 可以访问外部网络                               │
│  └── 所有外部流量可以访问 Pod                               │
├─────────────────────────────────────────────────────────────┤
│  有 NetworkPolicy 时:                                      │
│  ├── 只允许显式定义的通信                                   │
│  ├── 未定义的通信被拒绝                                     │
│  └── 实现零信任网络                                         │
└─────────────────────────────────────────────────────────────┘

NetworkPolicy 工作流程

1. 创建 NetworkPolicy
   │
   ▼
2. 选择目标 Pod (podSelector)
   │
   ▼
3. 定义入站规则 (ingress)
   │
   ▼
4. 定义出站规则 (egress)
   │
   ▼
5. CNI 插件执行策略

NetworkPolicy 示例

# 基本网络策略:只允许特定 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:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

NetworkPolicy 字段说明

字段说明
podSelector选择目标 Pod
policyTypes策略类型 (Ingress/Egress)
ingress入站规则
egress出站规则
from允许的来源
to允许的目标
ports允许的端口

选择器类型

# Pod 选择器
- podSelector:
    matchLabels:
      app: frontend

# 命名空间选择器
- namespaceSelector:
    matchLabels:
      env: production

# IP 块
- ipBlock:
    cidr: 10.0.0.0/8
    except:
    - 10.0.1.0/24

# 组合选择器
- podSelector:
    matchLabels:
      app: frontend
  namespaceSelector:
    matchLabels:
      env: production

常见网络策略模式

# 模式 1:默认拒绝所有入站
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress

---
# 模式 2:默认拒绝所有出站
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress

---
# 模式 3:默认拒绝所有
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

允许 DNS 查询

# 允许 DNS 查询 (通常需要)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

微服务网络策略

# 前端只能访问后端
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-to-backend
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

---
# 后端只能访问数据库
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-to-database
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 5432

---
# 数据库只能被后端访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: backend

调试网络策略

# 查看命名空间的网络策略
kubectl get networkpolicies -n default

# 查看网络策略详情
kubectl describe networkpolicy allow-frontend -n default

# 测试网络连通性
kubectl exec -it frontend-pod -- curl backend-service:8080

# 查看 CNI 插件日志
# 不同 CNI 插件有不同的调试方法

实践练习

练习 1:创建基本网络策略

# 创建默认拒绝所有入站的策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
# 应用策略
kubectl apply -f default-deny.yaml

# 测试:应该无法访问
kubectl run test --image=nginx --restart=Never
kubectl exec -it test -- curl <pod-ip>

练习 2:创建微服务网络策略

# 创建完整的微服务网络策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: microservice-policy
  namespace: default
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

常见误解

1. NetworkPolicy 是默认启用的

事实:NetworkPolicy 需要 CNI 插件支持
误解:创建 NetworkPolicy 就会生效
解决:确保使用支持 NetworkPolicy 的 CNI (Calico, Cilium, Weave)

2. NetworkPolicy 替代防火墙

事实:NetworkPolicy 是 Pod 级别的网络控制
误解:NetworkPolicy 可以替代传统防火墙
解决:结合传统防火墙和 NetworkPolicy 实现多层防护

小结

要点说明
NetworkPolicyPod 级别的网络访问控制
默认行为无策略时允许所有通信
策略类型Ingress (入站)、Egress (出站)
选择器podSelector、namespaceSelector、ipBlock
最佳实践默认拒绝、最小权限、允许 DNS

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「密钥管理」 以巩固所学知识。