【云原生与DevOps】03-K8s生产环境部署Checklist:你踩过这18个坑吗
·
专栏: 云原生 & DevOps
难度: 进阶
标签: Kubernetes 生产环境 checklist 踩坑 最佳实践
前言
K8s 在测试环境跑得好好的,一到生产就出问题。本文总结了真实血泪经验中的18个坑,每一条都是真实事故凝练的经验。
坑1:没配资源 limits,被一个Pod打挂整个节点
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"
教训: requests 用于调度,limits 用于限制。不配 limits,一个内存泄漏的 Pod 会把节点内存耗尽,导致 OOMKill 雪崩。
坑2:镜像标签用 latest,滚动更新失效
# 错误
image: myapp:latest
# 正确
image: myapp:1.2.3-abc1234 # 包含git commit hash
教训: latest 不是版本,imagePullPolicy: Always 会导致每次都拉镜像,降低启动速度。
坑3:没配健康检查,流量打到未就绪的Pod
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
教训: readinessProbe 控制是否接收流量,livenessProbe 控制是否重启容器,两者缺一不可。
坑4:PodDisruptionBudget 没配,滚动更新导致服务中断
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp-pdb
spec:
minAvailable: 2 # 滚动时保持至少2个可用
selector:
matchLabels:
app: myapp
坑5:没配 HPA,突发流量直接挂
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
坑6:ConfigMap 热更新不生效
默认情况下 Pod 不会感知 ConfigMap 的变更。解决方案:
- 使用 Reloader(推荐):https://github.com/stakater/Reloader
- 将配置版本写入 Deployment annotation,触发滚动更新
# 方案2:在annotation中记录configmap版本
spec:
template:
metadata:
annotations:
configmap-version: "v3" # 改这里触发滚动更新
坑7:Service 类型用 NodePort 暴露生产服务
生产环境应使用 LoadBalancer 或 Ingress,NodePort 端口范围有限且难以管理。
坑8:没配 Pod 反亲和性,所有副本跑在同一节点
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: myapp
topologyKey: "kubernetes.io/hostname"
坑9:Secret 明文写在 YAML 里推送到 Git
使用 Sealed Secrets 或 Vault:
# 安装 Sealed Secrets
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm install sealed-secrets sealed-secrets/sealed-secrets -n kube-system
# 加密Secret
kubeseal -o yaml < secret.yaml > sealed-secret.yaml
坑10:命名空间没做资源配额,Dev环境把生产资源耗尽
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: development
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
count/pods: "20"
坑11:没配terminationGracePeriodSeconds,应用被强杀
spec:
terminationGracePeriodSeconds: 60 # 给应用60秒优雅退出时间
containers:
- name: myapp
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"] # 等待LB摘除此Pod
坑12 - 坑18(核心原则速览)
| 坑号 | 问题 | 解决方案 |
|---|---|---|
| 12 | etcd 没备份 | 配置 etcd 自动备份到 S3/OSS |
| 13 | 节点磁盘打满,Pod 被驱逐 | 配置 evictionHard 阈值,及时清理镜像 |
| 14 | 日志直接写容器内,重启丢失 | 使用 DaemonSet 收集日志(Filebeat/Fluentd) |
| 15 | RBAC 给了 cluster-admin,权限过大 | 遵循最小权限原则 |
| 16 | 镜像拉取无重试,冷启动失败 | 配置 imagePullPolicy: IfNotPresent |
| 17 | 单 Master 高可用差 | 生产至少3个 Master 节点 |
| 18 | 升级 K8s 版本前未测试 | 在独立集群先验证,看 Changelog |
结语: 这18个坑没有一个是"偶然"发生的,都有据可查。把这个 checklist 贴在你们团队的部署规范里,可以避免80%的生产事故。
更多推荐
所有评论(0)