Skip to content

01 - K8s 生产最佳实践

资源管理

必须设置 requests 和 limits

yaml
resources:
  requests:          # 调度保证
    memory: "128Mi"
    cpu: "100m"
  limits:            # 上限
    memory: "256Mi"
    cpu: "500m"

经验法则

  • requests 设置为应用正常负载的使用量
  • limits 设置为 requests 的 2-3 倍
  • 内存 limits 不要设太大(OOM 时整个节点可能受影响)
  • CPU 超限只是被限流,内存超限直接被杀

LimitRange(命名空间默认限制)

yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: production
spec:
  limits:
  - default:           # 默认 limits
      memory: "256Mi"
      cpu: "500m"
    defaultRequest:    # 默认 requests
      memory: "128Mi"
      cpu: "100m"
    type: Container

ResourceQuota(命名空间配额)

yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: ns-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    pods: "50"
    services: "20"

健康检查

每个生产 Pod 都必须配置探针

yaml
containers:
- name: app
  livenessProbe:           # 应用还活着吗?
    httpGet:
      path: /healthz
      port: 8080
    initialDelaySeconds: 15 # 启动后等待时间
    periodSeconds: 10       # 检查间隔
    timeoutSeconds: 3       # 超时时间
    failureThreshold: 3     # 连续失败次数
  readinessProbe:          # 准备好接受流量了吗?
    httpGet:
      path: /ready
      port: 8080
    initialDelaySeconds: 5
    periodSeconds: 5
  startupProbe:            # 启动完成了吗?(慢启动应用)
    httpGet:
      path: /healthz
      port: 8080
    failureThreshold: 30
    periodSeconds: 10       # 最多等 300 秒启动

滚动更新策略

yaml
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 25%           # 更新时最多多出 25% Pod
    maxUnavailable: 0       # 不允许不可用(零停机)

优雅终止

yaml
spec:
  terminationGracePeriodSeconds: 60  # 给应用 60 秒优雅关闭
  containers:
  - name: app
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh", "-c", "sleep 10"]  # 等连接排空

Pod 反亲和(高可用)

确保同一 Deployment 的 Pod 分散在不同节点:

yaml
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app: web
        topologyKey: kubernetes.io/hostname

PodDisruptionBudget(中断预算)

防止维护操作导致服务不可用:

yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  minAvailable: 2          # 至少保持 2 个可用
  # 或者 maxUnavailable: 1 # 最多 1 个不可用
  selector:
    matchLabels:
      app: web

标签规范

yaml
labels:
  app.kubernetes.io/name: web-server
  app.kubernetes.io/instance: web-prod
  app.kubernetes.io/version: "1.5.0"
  app.kubernetes.io/component: frontend
  app.kubernetes.io/part-of: my-app
  app.kubernetes.io/managed-by: helm

生产检查清单

  • [ ] 所有容器设置了 resources requests/limits
  • [ ] 所有容器配置了 liveness 和 readiness 探针
  • [ ] Deployment replicas >= 2
  • [ ] 配置了 PodDisruptionBudget
  • [ ] 配置了 Pod 反亲和(分散部署)
  • [ ] 使用 ConfigMap/Secret 管理配置
  • [ ] 镜像使用固定 tag,不使用 latest
  • [ ] 容器以非 root 用户运行
  • [ ] 设置了合适的 terminationGracePeriodSeconds
  • [ ] 配置了 NetworkPolicy
  • [ ] 监控和告警已就位
  • [ ] 日志收集已配置

下一步

02 - Helm 包管理