Skip to content
返回部署

Kubernetes 部署模式

生产 K8s 模式:Deployment、Service、Ingress、HPA 和零停机滚动更新。

容器高级

为什么

Kubernetes 大规模编排容器化应用:自动愈合、自动扩缩、滚动更新和服务发现。它是跨云厂商生产容器负载的行业标准。

Docker is used by 59% of professional developers per the Stack Overflow 2024 survey,Kubernetes 在生产中运行 60% 的容器化工作负载(CNCF 2024 调查)。容器编排通过声明式滚动发布将部署相关事故减少 35%。

何时使用

当有 10+ 微服务、需要多云可移植性或每服务细粒度扩缩时采用 Kubernetes。简单单体应用应避免 — Vercel/Cloudflare 更简单。

如何做

1. 打包应用 — Docker 镜像推送到仓库(ECR/GCR/Docker Hub) 2. 编写 Deployment — 指定副本数、镜像、资源、探针 3. 编写 Service — 通过 ClusterIP(内部)或 LoadBalancer(外部)暴露 Pod 4. 配置 Ingress — 路由 HTTP 流量、TLS 终止、基于路径的路由 5. 设置 HPA — HorizontalPodAutoscaler 按 CPU/内存或自定义指标扩缩 6. 滚动更新 — kubectl set image deployment/app app=myapp:v2 7. 回滚 — kubectl rollout undo deployment/app 8. 监控 — Prometheus + Grafana 指标,Loki 日志

示例

# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 3 selector: matchLabels: { app: myapp } template: metadata: labels: { app: myapp } spec: containers: - name: myapp image: myapp:v2.0 ports: [{ containerPort: 3000 }] resources: requests: { cpu: "100m", memory: "128Mi" } limits: { cpu: "500m", memory: "512Mi" } livenessProbe: httpGet: { path: /health, port: 3000 } initialDelaySeconds: 10 periodSeconds: 30 readinessProbe: httpGet: { path: /ready, port: 3000 } initialDelaySeconds: 5 periodSeconds: 10 --- # hpa.yaml — CPU 达 70% 时自动扩缩 3-10 副本 apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: myapp-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: myapp minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: { type: Utilization, averageUtilization: 70 }

常见问题

  • ⚠无资源限制 — Pod 消耗节点所有内存,导致 OOMKilled 驱逐
  • ⚠缺少就绪探针 — 流量在 Pod 就绪前路由,导致 502
  • ⚠ImagePullPolicy: Always — 减慢 Pod 启动,标记镜像用 IfNotPresent
  • ⚠ConfigMap 变更不重启 Pod — 用 Reloader 或在 Deployment 名加哈希后缀

最佳实践

  • ✓始终设置资源请求和限制 — 防止嘈杂邻居和 OOM 问题
  • ✓使用 liveness + readiness 探针 — liveness 重启死 Pod,readiness 控制流量
  • ✓用 semver 或 git SHA 标记镜像 — 生产中绝不用 :latest
  • ✓用 kustomize 或 Helm 做环境覆盖 — 避免每环境重复 YAML

常见问题解答

Deployment 和 StatefulSet 用哪个?

无状态应用(Web 服务器、API)用 Deployment——Pod 可互换。有状态应用(数据库)用 StatefulSet——Pod 有稳定身份和持久卷。需有序启动或稳定存储时才用 StatefulSet。

为什么 Pod 一直被 OOMKilled?

容器超内存限制。kubectl describe pod 查限制,调高或修内存泄漏。requests 设接近实际用量(kubectl top pod 查)以便调度器正确放置。

如何回滚错误部署?

kubectl rollout undo deployment/<name> 立即回退到上一 ReplicaSet。kubectl rollout history 查历史。务必设 progressDeadlineSeconds 使卡住滚动自动失败。

为什么 Pod 一直 Pending?

集群无足够资源节点。kubectl describe pod <name> 看 Events——Insufficient cpu/memory 或 0/3 nodes available。扩节点池或降资源请求。

该用 Helm 还是原始清单?

多环境部署(dev/staging/prod)用 Helm——模板化值。一次性配置用原始清单。别手改 Helm 生成的清单;改 chart 再重新渲染。