网络策略 #

一、网络策略概述 #

NetworkPolicy是Kubernetes中控制Pod间网络通信的资源,实现网络隔离和安全控制。

1.1 网络策略功能 #

text
NetworkPolicy功能
    │
    ├── 入站控制
    │   └── 限制进入Pod的流量
    │
    ├── 出站控制
    │   └── 限制Pod发出的流量
    │
    ├── 命名空间隔离
    │   └── 跨命名空间访问控制
    │
    └── 细粒度控制
        └── 基于标签选择器

1.2 网络插件支持 #

网络插件 NetworkPolicy支持
Calico 完全支持
Cilium 完全支持
Weave Net 完全支持
Flannel 需要额外配置

二、网络策略基础 #

2.1 默认行为 #

text
默认网络行为
    │
    ├── 无NetworkPolicy时
    │   ├── 所有入站流量允许
    │   └── 所有出站流量允许
    │
    └── 有NetworkPolicy时
        ├── 未匹配的流量被拒绝
        └── 匹配的流量被允许

2.2 基本示例 #

yaml
# deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
bash
# 应用策略
kubectl apply -f deny-all.yaml

# 此时default命名空间所有Pod
# 入站和出站流量都被拒绝

三、入站规则 #

3.1 允许特定Pod访问 #

yaml
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

3.2 允许特定命名空间访问 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-namespace
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: development
    ports:
    - protocol: TCP
      port: 8080

3.3 允许特定IP段访问 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-ip
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 192.168.1.0/24
        except:
        - 192.168.1.100/32
    ports:
    - protocol: TCP
      port: 8080

3.4 组合规则 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-combined
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    - namespaceSelector:
        matchLabels:
          name: monitoring
    - ipBlock:
        cidr: 10.0.0.0/8
    ports:
    - protocol: TCP
      port: 8080

四、出站规则 #

4.1 允许访问特定Service #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress-db
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: mysql
    ports:
    - protocol: TCP
      port: 3306

4.2 允许DNS查询 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

4.3 允许外部访问 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-external-egress
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16

五、完整策略示例 #

5.1 多层应用策略 #

yaml
# frontend-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-policy
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 8080
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
---
# backend-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-policy
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: mysql
    ports:
    - protocol: TCP
      port: 3306
  - to:
    - podSelector:
        matchLabels:
          app: redis
    ports:
    - protocol: TCP
      port: 6379
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
---
# database-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database-policy
spec:
  podSelector:
    matchLabels:
      app: mysql
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 3306
  egress:
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53

5.2 命名空间隔离 #

yaml
# namespace-isolation.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
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: production
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53

六、常用策略模式 #

6.1 默认拒绝所有 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

6.2 默认拒绝入站 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress

6.3 默认拒绝出站 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress

6.4 允许所有入站 #

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - {}

七、网络策略管理 #

7.1 查看策略 #

bash
# 查看NetworkPolicy
kubectl get networkpolicy

# 查看详情
kubectl describe networkpolicy <policy-name>

# 查看特定命名空间
kubectl get networkpolicy -n <namespace>

7.2 测试策略 #

bash
# 测试Pod间连通性
kubectl exec -it <source-pod> -- wget -qO- <target-service>:<port>

# 测试DNS解析
kubectl exec -it <pod> -- nslookup kubernetes

# 测试外部访问
kubectl exec -it <pod> -- curl -I https://www.google.com

八、故障排查 #

8.1 常见问题 #

bash
# 查看NetworkPolicy
kubectl get networkpolicy -A

# 查看策略详情
kubectl describe networkpolicy <policy-name>

# 检查Pod标签
kubectl get pods --show-labels

# 检查命名空间标签
kubectl get namespace --show-labels

8.2 问题诊断 #

问题 原因 解决方案
连接被拒绝 策略限制 检查策略规则
DNS解析失败 未允许DNS 添加DNS出站规则
跨命名空间不通 命名空间隔离 添加命名空间选择器

九、最佳实践 #

9.1 策略设计原则 #

text
策略设计原则
    │
    ├── 默认拒绝
    │   └── 先拒绝所有,再按需开放
    │
    ├── 最小权限
    │   └── 只开放必要的端口和来源
    │
    ├── 分层控制
    │   └── 前端→后端→数据库
    │
    └── 命名空间标签
        └── 给命名空间添加标签便于选择

9.2 命名空间标签 #

bash
# 给命名空间添加标签
kubectl label namespace production name=production
kubectl label namespace development name=development
kubectl label namespace ingress-nginx name=ingress-nginx

十、总结 #

10.1 核心要点 #

要点 说明
入站规则 控制进入Pod的流量
出站规则 控制Pod发出的流量
选择器 基于标签匹配Pod
默认行为 无策略时允许所有

10.2 下一步 #

掌握了网络策略后,让我们学习 服务发现,深入了解Kubernetes的DNS机制。

最后更新:2026-03-28