17 · Spring Boot 部署 K8s 完整实战
一句话定位:把前面所有知识串起来,用一个 Spring Boot 订单服务从源码到 K8s 上线的端到端完整案例。
1. 场景
order-service(Spring Boot)部署到 K8s:
– 连 MySQL(StatefulSet)和 Redis
– 配置用 ConfigMap + Secret
– 3 副本 + 健康检查 + 资源限制
– Service + Ingress 对外
– 监控 + 日志
2. 第一步:Spring Boot 准备
# application.yml(配置从环境变量读,K8s 注入)
server:
port: 8080
shutdown: graceful # 优雅停机
spring:
application:
name: order–service
datasource:
url: ${SPRING_DATASOURCE_URL}
username: ${SPRING_DATASOURCE_USERNAME}
password: ${SPRING_DATASOURCE_PASSWORD}
data:
redis:
host: ${REDIS_HOST}
lifecycle:
timeout-per-shutdown-phase: 30s
management:
endpoints:
web:
exposure:
include: health,prometheus
endpoint:
health:
probes:
enabled: true # 暴露 liveness/readiness
3. 第二步:Dockerfile(多阶段 + 分层)
# 构建阶段
FROM maven:3.9-eclipse-temurin-17 AS builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
# 运行阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
RUN addgroup -S app && adduser -S app -G app # 非 root 用户
COPY –from=builder /build/target/*.jar app.jar
USER app
EXPOSE 8080
ENV JAVA_OPTS="-XX:MaxRAMPercentage=75.0 -XX:+UseG1GC"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
# 构建推送
docker build -t harbor.example.com/prod/order-service:1.0 .
docker push harbor.example.com/prod/order-service:1.0
4. 第三步:配置(ConfigMap + Secret)
apiVersion: v1
kind: ConfigMap
metadata:
name: order–config
namespace: prod
data:
SPRING_DATASOURCE_URL: "jdbc:mysql://mysql-0.mysql:3306/orderdb"
REDIS_HOST: "redis-master"
SPRING_DATASOURCE_USERNAME: "order"
—
apiVersion: v1
kind: Secret
metadata:
name: order–secret
namespace: prod
type: Opaque
stringData:
SPRING_DATASOURCE_PASSWORD: "orderpass"
5. 第四步:Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: order–service
namespace: prod
spec:
replicas: 3
selector:
matchLabels:
app: order–service
template:
metadata:
labels:
app: order–service
spec:
imagePullSecrets:
– name: harbor–secret
# 反亲和:分散到不同节点(高可用)
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
– weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: order–service
topologyKey: kubernetes.io/hostname
containers:
– name: order–service
image: harbor.example.com/prod/order–service:1.0
ports:
– containerPort: 8080
envFrom:
– configMapRef:
name: order–config
– secretRef:
name: order–secret
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
# 健康检查
startupProbe:
httpGet: { path: /actuator/health, port: 8080 }
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
initialDelaySeconds: 0
periodSeconds: 10
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
periodSeconds: 10
# 优雅停机
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"]
terminationGracePeriodSeconds: 40
6. 第五步:Service + Ingress
apiVersion: v1
kind: Service
metadata:
name: order–service
namespace: prod
spec:
selector:
app: order–service
ports:
– port: 80
targetPort: 8080
—
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: order–ingress
namespace: prod
spec:
ingressClassName: nginx
rules:
– host: api.example.com
http:
paths:
– path: /order
pathType: Prefix
backend:
service:
name: order–service
port: { number: 80 }
tls:
– hosts: [api.example.com]
secretName: tls–secret
7. 第六步:HPA 自动扩缩容
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order–hpa
namespace: prod
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order–service
minReplicas: 3
maxReplicas: 10
metrics:
– type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
8. 第七步:部署与验证
# 创建命名空间
kubectl create namespace prod
# 创建镜像拉取 Secret
kubectl create secret docker-registry harbor-secret \\
–docker-server=harbor.example.com \\
–docker-username=admin –docker-password=xxx -n prod
# 部署(按顺序)
kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
kubectl apply -f hpa.yaml
# 验证
kubectl get pods -n prod # 看 Pod 是否 Running
kubectl get svc,ingress -n prod # 看服务和入口
kubectl logs -f deployment/order-service -n prod # 看日志
curl https://api.example.com/order/health # 测试访问
9. 第八步:更新与回滚
# 更新镜像(滚动更新)
kubectl set image deployment/order-service \\
order-service=harbor.example.com/prod/order-service:1.1 -n prod
# 观察滚动更新
kubectl rollout status deployment/order-service -n prod
# 出问题回滚
kubectl rollout undo deployment/order-service -n prod
10. 上线检查清单
镜像:
– [ ] 多阶段构建、非 root、MaxRAMPercentage
– [ ] 推到私有仓库,tag 用版本号
配置:
– [ ] 配置 ConfigMap、密码 Secret
– [ ] 数据库/Redis 地址正确
Deployment:
– [ ] 多副本 + podAntiAffinity 分散
– [ ] resources requests/limits
– [ ] 三种健康检查
– [ ] 优雅停机(preStop + graceful shutdown)
网络:
– [ ] Service + Ingress + HTTPS
弹性:
– [ ] HPA 自动扩缩容
可观测:
– [ ] 暴露 /actuator/prometheus + ServiceMonitor
– [ ] 日志 stdout + 集中收集
– [ ] 告警配置
11. 本篇小结
- 完整流程:Spring Boot 配置外部化 → Dockerfile(多阶段/非 root)→ ConfigMap/Secret → Deployment(副本/反亲和/健康检查/优雅停机/资源)→ Service/Ingress → HPA → 部署验证 → 更新回滚。
- 健康检查三件套 + 优雅停机保证不中断。
- 反亲和分散 + HPA 弹性 + 监控告警保证高可用。
- 按上线清单逐项检查,稳妥上线。



