K8s默认网络是全开放的——任何Pod可以访问任何Pod。NetworkPolicy是K8s的"网络防火墙",实现微隔离(Micro-segmentation),控制Pod间的网络流量。
┌─────── 默认:全开放 ───────┐ ┌───── NetworkPolicy:微隔离 ─────┐
│ │ │ │
│ [frontend] ←→ [backend] │ │ [frontend] → [backend] │
│ ↕ ↕ │ │ ✗ ↕ │
│ [db] ←→ [cache] │ │ [db] ← [backend] │
│ ↕ ↕ │ │ ✗ │
│ [monitor] ←→ [logger] │ │ [monitor] → [所有](只读) │
│ │ │ │
│ 所有Pod互相可访问 │ │ 只允许必要的流量路径 │
│ ❌ 不安全! │ │ ✅ 零信任网络 │
└──────────────────────────────┘ └────────────────────────────────────┘
NetworkPolicy关键特性:
🔹 命名空间级资源,只影响同namespace的Pod
🔹 基于Pod标签选择器匹配Pod
🔹 控制Ingress(入站)和Egress(出站)流量
🔹 需要CNI插件支持(Calico/Cilium/Weave等)
🔹 多个NetworkPolicy对同一Pod是累加关系
# networkpolicy-syntax.yaml - 完整语法
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-policy
namespace: default
spec:
# Pod选择器:策略应用到哪些Pod
podSelector:
matchLabels:
app: backend # 匹配app=backend的Pod
# {} 匹配所有Pod
# 策略类型
policyTypes:
- Ingress # 控制入站流量
- Egress # 控制出站流量
# 入站规则(白名单)
ingress:
- from: # 允许的来源(OR关系)
# 来源选择器之间是AND关系
- podSelector: # 同namespace的Pod
matchLabels:
app: frontend
- namespaceSelector: # 其他namespace
matchLabels:
env: production
- ipBlock: # IP段
cidr: 10.0.0.0/8
except:
- 10.0.1.0/24 # 排除子网
ports: # 允许的端口
- protocol: TCP
port: 8080
- protocol: TCP
port: 443
# 出站规则(白名单)
egress:
- to: # 允许的目标
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 3306
- to: # 允许DNS解析
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
# default-deny-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: default
spec:
podSelector: {} # 匹配所有Pod
policyTypes:
- Ingress # 拒绝所有入站(无ingress规则=全部拒绝)
# ✅ 验证通过 - 所有Pod无法被外部访问
kubectl apply -f default-deny-ingress.yaml
# 测试:从其他Pod无法访问default命名空间的Pod
# default-deny-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress # 拒绝所有出站
# ⚠️ 注意:这会阻止DNS解析!需要额外规则允许DNS
# default-deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress # 拒绝所有入站+出站
# 三层架构:frontend → backend → database
# 1. Frontend:只允许外部入站80端口,允许出站到backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
namespace: default
spec:
podSelector:
matchLabels:
tier: frontend
policyTypes: [Ingress, Egress]
ingress:
- ports:
- port: 80
protocol: TCP
egress:
- to:
- podSelector:
matchLabels:
tier: backend
ports:
- port: 8080
protocol: TCP
- to: # 允许DNS
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
---
# 2. Backend:只允许frontend入站,只允许出站到database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: default
spec:
podSelector:
matchLabels:
tier: backend
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- port: 8080
protocol: TCP
egress:
- to:
- podSelector:
matchLabels:
tier: database
ports:
- port: 3306
protocol: TCP
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
---
# 3. Database:只允许backend入站3306,无出站需求
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
namespace: default
spec:
podSelector:
matchLabels:
tier: database
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- port: 3306
protocol: TCP
# ✅ 验证通过 - 验证隔离效果
# Frontend可以访问Backend
kubectl exec frontend-pod -- curl -s backend-service:8080/health
# OK
# Frontend不能直接访问Database
kubectl exec frontend-pod -- curl -s database-service:3306
# Connection timed out ✅ 隔离生效
# 允许dev命名空间访问prod的只读API
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dev-readonly
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels:
env: development # 需要给namespace打标签
ports:
- port: 8080
protocol: TCP
# 给namespace打标签
kubectl label namespace development env=development
kubectl label namespace production env=production
# Cilium提供增强版NetworkPolicy
# 支持L7层(HTTP/gRPC/Kafka等)策略
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l7-policy
spec:
endpointSelector:
matchLabels:
app: api
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET # 只允许GET请求
path: "/api/.*" # 只允许/api/路径
- method: POST
path: "/api/data"
# 检查CNI是否支持NetworkPolicy
kubectl get pods -n kube-system | grep -E 'calico|cilium|weave'
# Flannel默认不支持!需要用Calico或Cilium
# 检查NetworkPolicy是否存在
kubectl get networkpolicy -A
# 检查Pod标签是否匹配
kubectl get pods --show-labels | grep backend
# 现象:Pod无法解析域名
# 原因:Egress策略阻止了到DNS Pod的流量
# 解决:添加DNS放行规则
egress:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
下一课预告:第13课深入Prometheus监控——K8s可观测性基石。
12-networkpolicy补充要点K8s生产实践扩展
🔹 资源配额(ResourceQuota):限制命名空间总资源
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: production
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
limits.memory: 80Gi
pods: "50"
services: "10"
🔹 LimitRange:设置默认资源限制
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
spec:
limits:
- type: Container
default:
cpu: "200m"
memory: 256Mi
defaultRequest:
cpu: "100m"
memory: 128Mi
max:
cpu: "2"
memory: 4Gi
🔹 Pod优先级与抢占
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
---
spec:
preemptionPolicy: PreemptLowerPriority
🔹 优雅处理Pod中断
• PDB保证最小可用副本
• preStop钩子处理连接排空
• terminationGracePeriodSeconds充足
• 应用必须处理SIGTERM信号
🔹 生产环境Checklist
✅ 设置resources requests/limits
✅ 配置liveness/readiness探针
✅ 使用PDB保护关键服务
✅ 实现优雅关闭(SIGTERM)
✅ 配置HPA自动伸缩
✅ 使用NetworkPolicy隔离
✅ 开启RBAC最小权限
✅ 日志结构化输出
✅ 指标暴露/metrics端点
✅ 配置PVC数据备份
12-networkpolicy生产环境进阶要点
🔹 性能优化关键参数
• kubelet: --max-pods=110 --pods-per-core=10
• kube-apiserver: --max-requests-inflight=800
• etcd: --quota-backend-bytes=8589934592
• kube-scheduler: --percentage-of-nodes-to-score=50
🔹 集群容量规划
• 控制平面:3节点,8C16G起步
• Worker节点:按应用类型分组
• etcd:SSD磁盘,<2ms延迟
• 网络带宽:10Gbps+集群内互联
🔹 故障自愈最佳实践
1. Pod: livenessProbe自动重启
2. Deployment: ReplicaSet保证副本数
3. Node: kubelet自注册+健康检查
4. Cluster: Cluster Autoscaler增减节点
5. Multi-Cluster: Karmada联邦容灾
🔹 K8s版本升级策略
• 每次只升一个minor版本
• 先升级控制平面,再升级Worker
• 使用kubeadm upgrade plan预检
• 准备回滚方案
• 在staging环境验证后再升级prod