把应用“跑进 Kubernetes”并不等于完成上线。一个可维护的部署还需要镜像可追踪、配置与密钥分离、资源边界、健康检查、稳定入口、滚动发布、监控和回滚方案。
一、上线前准备
先确认应用具备:
1. 可重复构建的容器镜像。
2. 明确的启动命令和监听端口。
3. 独立的健康检查接口。
4. 日志写到标准输出和标准错误。
5. 配置与代码分离。
6. 数据持久化与备份方案。
7. CPU、内存和副本数的初始估算。
生产镜像不要使用 latest。应使用明确版本标签,关键环境最好固定镜像摘要,并保留构建来源和漏洞扫描记录。
二、用 Deployment 管理无状态应用
Deployment 声明期望副本、Pod 模板和更新策略。示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app.kubernetes.io/name: web
spec:
replicas: 3
progressDeadlineSeconds: 600
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: web
template:
metadata:
labels:
app.kubernetes.io/name: web
spec:
containers:
- name: web
image: example.com/web@sha256:<DIGEST>
ports:
- name: http
containerPort: 8080
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 1
memory: 512Mi
selector 必须与 Pod 模板标签匹配。不要让多个控制器使用重叠 selector,否则可能互相争抢 Pod。
三、设置 requests 与 limits
调度器主要根据 requests 判断节点是否有能力接收 Pod。limits 则限制容器可使用的资源上限。
CPU 超过 limit 通常会被节流;内存超过 limit 可能触发 OOMKill。requests 设置过低会造成节点过度承诺,设置过高则可能让 Pod 长期 Pending。
初始值应基于测试和历史监控,而不是随意复制模板。上线后持续观察 CPU、内存、延迟和 OOM 事件,再逐步调整。
四、正确使用三类探针
startupProbe:给启动较慢的应用足够初始化时间。成功后,其他探针才开始工作。
readinessProbe:判断当前 Pod 是否应该接收 Service 流量。失败时 Pod 不会被杀死,但会从可用后端中移除。
livenessProbe:判断容器是否进入无法自行恢复的故障状态。连续失败会触发容器重启。
示例:
startupProbe:
httpGet:
path: /health/startup
port: http
periodSeconds: 5
failureThreshold: 60
readinessProbe:
httpGet:
path: /health/ready
port: http
periodSeconds: 5
failureThreshold: 3
livenessProbe:
httpGet:
path: /health/live
port: http
periodSeconds: 10
failureThreshold: 3
不要让 livenessProbe 强依赖数据库或外部 API,否则外部依赖抖动可能导致所有应用副本反复重启。
五、配置与密钥分离
非敏感配置可以放入 ConfigMap;密码、Token 和证书私钥应使用 Secret 或外部密钥管理方案。
ConfigMap 不提供保密能力,Secret 的 Base64 也不是加密。应结合 RBAC、静态数据加密、外部密钥管理和轮换流程保护敏感信息。
修改 ConfigMap 或 Secret 后,容器是否自动使用新内容取决于挂载方式和应用行为。生产变更应明确触发重载或滚动发布,而不是假设所有进程都会自动刷新。
六、通过 Service 提供稳定入口
为 Deployment 创建 ClusterIP Service:
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app.kubernetes.io/name: web
ports:
- name: http
port: 80
targetPort: http
检查 Service 是否找到后端:
kubectl get endpointslice \
-l kubernetes.io/service-name=web
没有 EndpointSlice 时,应检查 Pod 标签、readiness 和 targetPort。
七、通过 Ingress 或 Gateway 暴露 HTTP 服务
外部 HTTP/HTTPS 流量通常经 Ingress Controller 或 Gateway 实现进入 Service。需要准备:
1. 域名和 DNS 解析。
2. IngressClass 或 GatewayClass。
3. TLS 证书及 Secret。
4. 外部负载均衡和防火墙规则。
5. 超时、上传大小和代理协议等实现特定配置。
不要把每个业务都直接用 NodePort 暴露公网,也不要把管理接口与普通业务入口混用。
八、上线前预览变更
kubectl apply --dry-run=server \
--validate=strict -f manifests/
kubectl diff -f manifests/
确认差异后再应用:
kubectl apply -f manifests/
复杂项目可以使用 Kustomize 管理环境差异,或在确实需要模板化时使用 Helm。无论工具是什么,渲染后的最终 YAML 都应接受校验和审查。
九、观察滚动发布
kubectl rollout status deployment/web --timeout=10m
kubectl get pod -l app.kubernetes.io/name=web -w
kubectl get replicaset -l app.kubernetes.io/name=web
RollingUpdate 中,maxUnavailable 控制最多有多少旧副本不可用,maxSurge 控制可以临时多创建多少新副本。
maxUnavailable: 0 并不自动保证零停机。如果 readiness 不准确、应用未优雅关闭、容量不足或外部依赖不兼容,仍可能发生中断。
十、失败时回滚
查看历史:
kubectl rollout history deployment/web
回滚上一版:
kubectl rollout undo deployment/web
kubectl rollout status deployment/web
回滚镜像并不一定能回滚数据库结构、配置、外部 API 或消息格式。涉及数据迁移时,应使用向前兼容的发布设计和独立回滚方案。
十一、上线后验证
1. 检查 Deployment 副本是否全部 Available。
2. 检查 Pod 重启次数和事件。
3. 从集群内测试 Service。
4. 从外部测试域名和 TLS。
5. 检查延迟、错误率、吞吐和资源使用。
6. 确认日志、指标和告警已接入。
7. 验证 NetworkPolicy、RBAC 和 Pod 安全设置。
8. 确认备份任务和恢复流程。
常用命令:
kubectl get deployment,pod,service,ingress
kubectl describe deployment web
kubectl logs deployment/web --all-pods=true
kubectl get events --sort-by=.metadata.creationTimestamp
总结
可靠的 Kubernetes 上线流程是:构建可追踪镜像 → 声明 Deployment → 配置资源和探针 → 分离配置与密钥 → 创建 Service → 配置外部入口 → dry-run 和 diff → 滚动发布 → 监控验证 → 准备回滚。每个环节都应可审查、可重复、可恢复。
参考资料:
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/