返回文章目录

一次 Kubernetes 发布如何完成:从镜像到可用实例

沿着镜像、Pod、Deployment、Service、探针和滚动更新,解释一次发布如何逐步变成可用服务。

内容说明本文为个人学习与教学示例,不代表真实生产项目。涉及生产配置时请结合环境评估并完成审查。

把代码推送到仓库并不等于服务已经可用。一次 Kubernetes 发布要经过构建不可变镜像、创建 Pod、满足探针、加入 Service 端点、逐步替换旧版本,并在异常时停止或回滚。

问题背景:提交代码不等于服务可用

发布系统面对三个不同事实:新的容器是否启动、应用是否准备接收请求、版本是否满足业务指标。进程存在只能说明启动命令没有退出;依赖初始化尚未完成时把流量送入,仍会产生错误。

因此发布要把制品、运行状态和服务质量分开观测。Kubernetes 负责协调期望状态,但不会理解订单成功率或业务数据正确性,后者需要监控和发布策略补充。

镜像:固定可交付物

镜像应由流水线构建一次,在不同环境复用同一个摘要。不要在生产服务器上重新编译,也不要只使用会漂移的 latest 标签。

dockerfile
01FROM golang:1.24-alpine AS build
02WORKDIR /src
03COPY go.mod go.sum ./
04RUN go mod download
05COPY . .
06RUN CGO_ENABLED=0 go build -trimpath -o /out/api ./cmd/api
07
08FROM gcr.io/distroless/static-debian12:nonroot
09COPY --from=build /out/api /api
10USER nonroot:nonroot
11ENTRYPOINT ["/api"]

多阶段构建减少运行镜像中的编译工具。示例仍需在实际项目中加入依赖校验、软件物料清单和漏洞扫描;基础镜像版本要定期更新而不是永久固定。

Pod、Deployment 与期望状态

Pod 是一组共享网络和存储命名空间的容器;Deployment 描述副本数、Pod 模板和更新策略;控制器持续比较期望状态与实际状态,创建或替换 Pod。

图中镜像是不可变制品,Deployment 驱动新 ReplicaSet,只有就绪探针通过的 Pod 才进入 Service 的可用端点集合。

Service 与请求路径

Pod IP 会随重建变化,Service 提供稳定的虚拟地址和服务发现名称。请求经过入口网关或负载均衡器到达 Service,再转发到就绪端点。Service 并不保证应用正确,只过滤尚未就绪或已经不健康的实例。

网络策略应按最小访问范围限制 Pod 之间的通信。不要假设集群内流量天然可信;服务身份、传输加密和授权仍要根据风险设计。

实践:带探针的部署

yaml
01apiVersion: apps/v1
02kind: Deployment
03metadata:
04 name: notes-api
05spec:
06 replicas: 3
07 strategy:
08 rollingUpdate:
09 maxUnavailable: 0
10 maxSurge: 1
11 selector:
12 matchLabels:
13 app: notes-api
14 template:
15 metadata:
16 labels:
17 app: notes-api
18 spec:
19 containers:
20 - name: api
21 image: registry.example/notes-api@sha256:REPLACE_WITH_REAL_DIGEST
22 ports:
23 - containerPort: 8080
24 resources:
25 requests:
26 cpu: 100m
27 memory: 128Mi
28 limits:
29 memory: 256Mi
30 startupProbe:
31 httpGet: { path: /health/startup, port: 8080 }
32 failureThreshold: 30
33 periodSeconds: 2
34 readinessProbe:
35 httpGet: { path: /health/ready, port: 8080 }
36 periodSeconds: 5
37 livenessProbe:
38 httpGet: { path: /health/live, port: 8080 }
39 periodSeconds: 10

示例中的仓库地址和摘要是占位符,不能直接用于生产。启动探针给慢启动应用时间;就绪探针决定是否接流量;存活探针只判断进程是否需要重启,不应因为下游数据库短暂故障就反复杀死所有实例。

资源 requests 参与调度,limits 约束运行上限。CPU 限制可能带来节流,内存超限会导致容器被终止,需要通过压测和真实指标调整。

滚动更新、失败与回滚

滚动更新逐个增加新实例并减少旧实例。maxUnavailable: 0 保持可用副本,但需要额外容量。发布时应观察 Pod 就绪、错误率、延迟、资源使用和关键业务指标。

配置错误可能让新 Pod 永远无法就绪,Deployment 会停止推进,但不会自动理解业务回归。可靠流水线需要超时、失败判定和回滚动作。数据库结构变化要采用向前兼容的扩展—迁移—收缩过程,避免回滚旧代码时无法读取新结构。

终止阶段也很重要:实例先从端点移除,再在优雅终止窗口内完成正在处理的请求。应用要响应终止信号,停止接收新任务并在截止时间前退出。

安全、观测与总结

容器使用非 root 用户,Secret 不写入镜像,服务账户只授予必要权限。发布记录应关联代码版本、镜像摘要、配置版本和操作者,便于审计。

Kubernetes 发布的关键链路是:不可变镜像 → 控制器创建实例 → 探针确认就绪 → Service 接入流量 → 指标验证 → 失败时停止或回滚。延伸阅读可继续进入容器网络、可观测性、金丝雀发布和高可用设计。

上一篇消息队列可靠性:从发送到消费的完整链路下一篇 高可用系统设计:消除单点并控制故障半径