# Implementing Network Policies For Kubernetes

> 通过配置 Kubernetes NetworkPolicy 资源实施 Pod 级别的网络分段，强制执行最小权限通信并限制集群内的横向移动（Lateral Movement）。

- Skill: `killvxk/implementing-network-policies-for-kubernetes` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add killvxk/implementing-network-policies-for-kubernetes`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/implementing-network-policies-for-kubernetes/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/implementing-network-policies-for-kubernetes

---


# 为 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 插件支持

```bash
# 检查已安装的 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：为每个命名空间实施默认拒绝策略

```yaml
# default-deny-all.yaml - 拒绝所有入站和出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}  # 匹配命名空间中的所有 Pod
  policyTypes:
  - Ingress
  - Egress
```

```bash
# 为关键命名空间应用默认拒绝策略
for ns in production staging default; do
  kubectl apply -f default-deny-all.yaml -n $ns
done

# 验证策略已应用
kubectl get networkpolicies --all-namespaces
```

### 步骤 3：允许必要的 DNS 出站流量

```yaml
# 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：配置应用特定策略

三层应用（前端 → 后端 → 数据库）示例：

```yaml
# 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：配置跨命名空间策略

```yaml
# 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
```

```bash
# 为监控命名空间添加 Label
kubectl label namespace monitoring kubernetes.io/metadata.name=monitoring
```

### 步骤 6：实施出站限制

```yaml
# 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：阻断云元数据端点访问

```yaml
# 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 元数据
```

## 监控与验证

### 测试策略

```bash
# 测试 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
```

### 查看策略

```bash
# 列出所有命名空间的策略
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 插件的可观测性功能检测策略违规

## 参考资料

- [Kubernetes NetworkPolicy 文档](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
- [Calico 网络策略](https://docs.tigera.io/calico/latest/network-policy/)
- [Cilium 网络策略](https://docs.cilium.io/en/stable/security/policy/)
- [网络策略编辑器](https://editor.networkpolicy.io/)

