Spring Boot: Kubernetes 部署
最后更新:2026-08-26
Kubernetes 是容器编排的操作系统——自动伸缩、滚动更新、自愈恢复,让应用永远在线。
1. 你将学到
- K8s Deployment 与 ReplicaSet:滚动更新与回滚策略
- Service 类型(ClusterIP / NodePort / LoadBalancer)与 Ingress 路由
- ConfigMap / Secret 管理应用配置与敏感信息
- Liveness / Readiness 探针与健康检查
- Bob 使用 Helm Chart 管理 OrderFlow 的 K8s 部署配置
2. 一个云原生运维的真实故事
(1) 痛点:手动运维不堪重负
OrderFlow 生产环境运行在 3 台服务器上,Bob 手动管理每台服务器的 Docker 容器。一次服务器宕机,Bob 凌晨 3 点手动在其他服务器上启动新容器。大促时需要扩容,Bob 手动启动更多容器然后配置负载均衡,每次扩容耗时 30 分钟。Charlie 要求自动伸缩,Bob 说"我做不到"。
(2) Kubernetes 的解法
K8s 声明式配置,自动管理:
YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: orderflow
spec:
replicas: 3
template:
spec:
containers:
- name: orderflow
image: orderflow-service:latest
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
节点宕机?K8s 自动在其他节点重启 Pod。流量激增?HPA 自动扩容。
(3) 收益
Bob 用 K8s 部署 OrderFlow 后:节点故障自动恢复(MTTR 从 2 小时降到 30 秒),HPA 自动伸缩(扩容从 30 分钟降到 2 分钟),Bob 再也不用凌晨修服务器了。
3. K8s 核心资源
(1) 资源依赖关系
graph TD
A[Ingress<br/>External Access] --> B[Service<br/>Internal LB]
B --> C[Deployment<br/>Pod Template]
C --> D[ReplicaSet<br/>Pod Replicas]
D --> E[Pod<br/>Container Group]
E --> F[Container<br/>OrderFlow App]
G[ConfigMap] --> F
H[Secret] --> F
| 资源 | 职责 | 类比 |
|---|---|---|
| Pod | 最小部署单元,包含容器 | 一个进程组 |
| Deployment | 管理 Pod 副本数和更新策略 | 进程管理器 |
| Service | 为 Pod 提供稳定访问入口 | 负载均衡器 |
| Ingress | HTTP 路由规则 | Nginx 反向代理 |
| ConfigMap | 非敏感配置 | 配置文件 |
| Secret | 敏感配置 | 加密配置文件 |
4. Deployment 与滚动更新
▶ 示例: OrderFlow Deployment
YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: orderflow
labels:
app: orderflow
spec:
replicas: 3
selector:
matchLabels:
app: orderflow
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: orderflow
spec:
containers:
- name: orderflow
image: registry.example.com/orderflow-service:1.0.0
ports:
- containerPort: 8080
- containerPort: 8081
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: orderflow-config
key: database.host
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: orderflow-secrets
key: database.password
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
输出:
TEXT
📖 仅展示
Deployment.apps/my-app created
Service/my-app-service exposed
Ingress/my-app-ingress created
| 滚动更新参数 | 含义 | 推荐值 |
|---|---|---|
maxUnavailable |
最多不可用 Pod 数 | 1(或 25%) |
maxSurge |
最多超出目标副本数 | 1(或 25%) |
▶ 示例: 滚动更新与回滚
BASH
# Update image version (triggers rolling update)
kubectl set image deployment/orderflow orderflow=registry.example.com/orderflow-service:2.0.0
# Check rollout status
kubectl rollout status deployment/orderflow
# Rollback to previous version
kubectl rollout undo deployment/orderflow
# View rollout history
kubectl rollout history deployment/orderflow
输出:
TEXT
📖 仅展示
# 命令执行成功
5. Service 与 Ingress
▶ 示例: Service 定义
YAML
# ClusterIP Service (internal access)
apiVersion: v1
kind: Service
metadata:
name: orderflow
spec:
selector:
app: orderflow
ports:
- name: http
port: 80
targetPort: 8080
- name: management
port: 8081
targetPort: 8081
type: ClusterIP
输出:
TEXT
📖 仅展示
Configuration applied successfully
| Service 类型 | 访问范围 | 适用场景 |
|---|---|---|
| ClusterIP | 集群内部 | 微服务间调用 |
| NodePort | 集群外部(节点 IP:端口) | 简单外部访问 |
| LoadBalancer | 云厂商负载均衡器 | 生产环境(云) |
| ExternalName | DNS CNAME | 引用外部服务 |
▶ 示例: Ingress 路由
YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orderflow-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: api.orderflow.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: orderflow
port:
number: 80
tls:
- hosts:
- api.orderflow.example.com
secretName: orderflow-tls
输出:
TEXT
📖 仅展示
Deployment.apps/my-app created
Service/my-app-service exposed
Ingress/my-app-ingress created
6. ConfigMap 与 Secret
▶ 示例: ConfigMap 和 Secret
YAML
# ConfigMap: non-sensitive configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: orderflow-config
data:
database.host: "mysql-service"
database.name: "orderflow"
redis.host: "redis-service"
spring.profiles.active: "prod"
management.server.port: "8081"
---
# Secret: sensitive configuration (base64 encoded)
apiVersion: v1
kind: Secret
metadata:
name: orderflow-secrets
type: Opaque
data:
database.password: b3JkZXJmbG93MTIz # base64 of "orderflow123"
redis.password: cmVkaXNwYXNz # base64 of "redispass"
jwt.private-key: LS0tLS1CRUdJTi... # base64 of private key
输出:
TEXT
📖 仅展示
Configuration applied successfully
| 维度 | ConfigMap | Secret |
|---|---|---|
| 数据类型 | 明文 | Base64 编码 |
| 适用内容 | 非敏感配置 | 密码、密钥、证书 |
| 存储方式 | etcd 明文 | etcd 可加密 |
| 大小限制 | 1MB | 1MB |
🔒 安全: Secret 只是 Base64 编码,不是加密。生产环境应启用 etcd 加密,或使用 Vault 等外部密钥管理。
7. Liveness 与 Readiness 探针
▶ 示例: 探针配置
YAML
spec:
containers:
- name: orderflow
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
输出:
TEXT
📖 仅展示
配置文件已生效
YAML
# application-prod.yml: Enable liveness/readiness groups
management:
endpoint:
health:
show-details: always
group:
liveness:
include: livenessState
readiness:
include: readinessState, db, redis
| 探针类型 | 用途 | 失败后果 |
|---|---|---|
livenessProbe |
检测进程是否存活 | 重启容器 |
readinessProbe |
检测是否准备好接收流量 | 从 Service 摘除 |
startupProbe |
检测应用是否启动完成 | 启动期间禁用其他探针 |
8. 综合示例:OrderFlow K8s 完整部署
YAML
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: orderflow
---
# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: orderflow-config
namespace: orderflow
data:
SPRING_PROFILES_ACTIVE: "prod"
DB_HOST: "mysql-service"
DB_NAME: "orderflow"
REDIS_HOST: "redis-service"
MANAGEMENT_SERVER_PORT: "8081"
---
# k8s/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: orderflow-secrets
namespace: orderflow
type: Opaque
data:
DB_PASSWORD: b3JkZXJmbG93MTIz
---
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: orderflow
namespace: orderflow
spec:
replicas: 3
selector:
matchLabels: { app: orderflow }
strategy:
rollingUpdate: { maxUnavailable: 1, maxSurge: 1 }
template:
metadata:
labels: { app: orderflow }
spec:
containers:
- name: orderflow
image: registry.example.com/orderflow-service:1.0.0
ports:
- { containerPort: 8080 }
- { containerPort: 8081 }
envFrom:
- configMapRef: { name: orderflow-config }
- secretRef: { name: orderflow-secrets }
resources:
requests: { memory: "512Mi", cpu: "250m" }
limits: { memory: "1Gi", cpu: "500m" }
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
initialDelaySeconds: 60; periodSeconds: 30; failureThreshold: 3
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
initialDelaySeconds: 30; periodSeconds: 10; failureThreshold: 3
---
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
name: orderflow
namespace: orderflow
spec:
selector: { app: orderflow }
ports:
- { name: http, port: 80, targetPort: 8080 }
type: ClusterIP
---
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orderflow-ingress
namespace: orderflow
spec:
ingressClassName: nginx
rules:
- host: api.orderflow.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service: { name: orderflow, port: { number: 80 } }
❓ 常见问题
Q Deployment 和 StatefulSet 有什么区别?
A Deployment 管理无状态应用(可随意替换),StatefulSet 管理有状态应用(固定网络标识、持久存储)。OrderFlow 是无状态服务,用 Deployment。MySQL 是有状态服务,用 StatefulSet 或 Operator。
Q 如何实现零停机部署?
A 1)配置 readinessProbe,Pod 就绪后才加入 Service;2)滚动更新策略 maxUnavailable=0;3)preStop hook 优雅关闭(
sleep 10 等待流量排空);4)应用实现优雅停机(server.shutdown=graceful)。Q ConfigMap 更新后 Pod 会自动获取新配置吗?
A 环境变量方式不会自动更新(需要重启 Pod)。Volume 挂载方式会自动更新(延迟约 60 秒)。Spring Cloud Kubernetes 支持配置热刷新。
Q 如何选择 CPU/内存的 requests 和 limits?
A requests 决定调度和最小保障,limits 决定最大可用。建议 limits = 2 × requests。设置过低导致 OOM Kill 或 CPU 限流,过高浪费资源。先观察实际用量再调优。
Q Helm Chart 的优势是什么?
A Helm 是 K8s 的包管理器,把所有 YAML 模板化,支持变量替换、版本管理、一键部署/升级/回滚。适合管理复杂的多资源部署。
Q 如何排查 Pod 启动失败?
A 1)
kubectl describe pod <name> 查看 Events;2)kubectl logs <name> 查看容器日志;3)kubectl get events --sort-by=.metadata.creationTimestamp 查看集群事件。📖 小节
- Deployment 管理 Pod 副本和滚动更新,maxUnavailable/maxSurge 控制更新节奏
- Service 提供 Pod 稳定访问入口,ClusterIP 内部、LoadBalancer 外部
- Ingress 配置 HTTP 路由和 TLS,相当于 K8s 的反向代理
- ConfigMap 管理非敏感配置,Secret 管理敏感信息(Base64 编码)
- Liveness/Readiness/Startup 探针分别检测存活、就绪、启动状态
- 声明式配置 + 滚动更新 = 零停机部署
📝 作业
-
基础题(难度⭐):为 OrderFlow 编写 Deployment + Service YAML,部署到本地 K8s(minikube 或 kind),验证应用可访问。
-
进阶题(难度⭐⭐):添加 ConfigMap + Secret + Ingress 配置,实现外部域名访问。配置 Liveness 和 Readiness 探针,模拟 Pod 故障验证自动恢复。
-
挑战题(难度⭐⭐⭐):使用 Helm Chart 管理 OrderFlow 的 K8s 部署,支持 values.yaml 变量替换(镜像版本、副本数、资源配置),实现
helm upgrade滚动更新和helm rollback回滚。