下载工作台
Spring Cloud 微服务

K8s 交付与 Python/Java 微服务对比

试读上半部分 · 解锁后可读全文

第 19 章 · Docker/K8s 微服务交付与模块结业

本章目标:为 svc-spring-demo 各服务编写多阶段 Dockerfile 与统一镜像规范;使用 docker-compose 编排应用与基础设施;在 deploy/k8s/ 编写 Deployment / Service / Ingress YAML;配置 ConfigMap / Secret健康探针;理解微服务交付与单体(spring-boot-web ch19)的差异;完成 Python/Java 微服务栈对比(§19.11)、spring-cloud-web 全模块回顾100 分进阶验收表;说明与 xiaozi-cloudarchitecture 模块的衔接路径。

学时建议:8~10 小时(含 4 小时容器构建与 K8s 部署演练)

前置spring-cloud-web ch01~ch18spring-boot-web ch19 容器基础;ch12 毕业项目;选修 xiaozi-cloud ch01~ch03


19.1 微服务交付 vs 单体交付

spring-boot-web ch19          spring-cloud-web ch19(本章)
shop-spring-demo              svc-spring-demo
  1 个 Dockerfile               N 个服务 Dockerfile + 公共父 POM 构建
  1 个 Deployment               gateway / bff / order / product / ...
  1 个 MySQL                    每服务独立库 + 共享中间件
维度单体微服务
镜像数量16~10+
配置单 application.ymlNacos + ConfigMap
启动顺序app 依赖 DBinfra → 注册中心 → 业务服务 → gateway
滚动更新单 Deployment多 Deployment 协调(ch15 灰度)
资源单 Pod 2Gi按服务分配 requests/limits

目标拓扑(虚构 api.example.com)

Internet
    │
    ▼ Ingress (api.example.com)
┌─────────────┐
│ gateway-svc │ ×2
└──────┬──────┘
       │ ClusterIP
┌──────┴──────────────────────────────┐
│ bff │ order │ product │ user │ auth │
└─────────────────────────────────────┘
       │
┌──────┴──────────────────────────────┐
│ Nacos │ MySQL×N │ Redis │ RabbitMQ │
│ Zipkin │ Seata TC │ Prometheus     │
└─────────────────────────────────────┘

19.2 多模块 Maven 构建策略

方案 A:每服务独立 Dockerfile(推荐教学)

svc-spring-demo/
├── order-svc/Dockerfile
├── product-svc/Dockerfile
├── gateway-svc/Dockerfile
└── pom.xml                    # 父 POM

方案 B:根目录统一构建脚本

# scripts/build-images.sh(虚构)
services=(gateway-svc bff-svc order-svc product-svc user-svc auth-svc)
for svc in "${services[@]}"; do
  docker build -f "$svc/Dockerfile" -t "registry.example.com/svc-spring/$svc:${GIT_SHA}" .
done

19.3 服务 Dockerfile 模板

order-svc/Dockerfile 为例(衔接 spring-boot-web ch19):

# ── 构建阶段:在仓库根目录构建(-f order-svc/Dockerfile .)
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /build
COPY pom.xml ./
COPY svc-common/pom.xml svc-common/
COPY order-svc/pom.xml order-svc/
# 仅下载依赖层(利用缓存)
RUN mvn -q -pl order-svc -am dependency:go-offline -DskipTests
COPY svc-common svc-common
COPY order-svc order-svc
RUN mvn -q -pl order-svc -am package -DskipTests

# ── 运行阶段
FROM eclipse-temurin:21-jre-alpine AS runtime
RUN addgroup -g 1000 app && adduser -u 1000 -G app -D app
WORKDIR /app
COPY --from=builder /build/order-svc/target/order-svc-*.jar app.jar
USER app
EXPOSE 8080 9090
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
# alpine 镜像的 wget 来自 busybox;若改用非 alpine 基础镜像(如 jammy)需先 apt 安装 wget/curl
HEALTHCHECK --interval=30s --timeout=3s --start-period=90s \
  CMD wget -qO- http://127.0.0.1:9090/actuator/health/liveness || exit 1
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
健康检查前提9090 管理端口与 liveness/readiness 探针端点来自 ch18 的 observability.ymlmanagement.server.port: 9090 + probes.enabled: true);二者缺一,HEALTHCHECK 会持续失败。

.dockerignore(仓库根):

**/target/
.git/
.idea/
*.iml
.env
logs/
deploy/
实践微服务特别注意
非 root每个镜像统一 UID 1000
多阶段镜像不含源码与 JDK
健康检查management 端口 9090(ch18)
标签registry.example.com/svc-spring/order-svc:1.0.0

19.4 docker-compose 分层编排

沿用 ch12 结构,拆为三层:

# deploy/docker-compose.infra.yml — Nacos, MySQL, Redis, RabbitMQ, Zipkin, Seata, Prometheus
# deploy/docker-compose.apps.yml   — 各业务镜像
# deploy/docker-compose.observability.yml — ch18 Grafana(可选)

docker-compose.apps.yml 片段:

services:
  gateway-svc:
    image: registry.example.com/svc-spring/gateway-svc:${VERSION:-latest}
    ports: ["8443:8443"]
    environment:
      SPRING_PROFILES_ACTIVE: docker
      NACOS_SERVER: nacos:8848
    depends_on:
      nacos: { condition: service_healthy }
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://127.0.0.1:9090/actuator/health/readiness"]
      interval: 15s
      timeout: 5s
      retries: 10

  order-svc:
    image: registry.example.com/svc-spring/order-svc:${VERSION:-latest}
    environment:
      SPRING_PROFILES_ACTIVE: docker
      NACOS_SERVER: nacos:8848
    depends_on: [nacos, mysql-order, rabbitmq]
    deploy:
      replicas: 2   # compose v3 swarm 模式;教学可用 scale

启动顺序:

docker compose -f deploy/docker-compose.infra.yml up -d
# 等待 Nacos 健康
docker compose -f deploy/docker-compose.apps.yml up -d
docker compose -f deploy/docker-compose.apps.yml run --rm scripts/smoke-svc.sh

19.5 Kubernetes 核心清单

Namespace svc-spring(ch13 Istio 选修):

# deploy/k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: svc-spring
  labels:
    istio-injection: enabled   # 选修 ch13

order-svc Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-svc
  namespace: svc-spring
spec:
  replicas: 2
  selector:
    matchLabels: { app: order-svc }
  template:
    metadata:
      labels: { app: order-svc, version: v1 }
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9090"
        prometheus.io/path: "/actuator/prometheus"
    spec:
      containers:
        - name: order-svc
          image: registry.example.com/svc-spring/order-svc:1.0.0
          ports:
            - { name: http, containerPort: 8080 }
            - { name: mgmt, containerPort: 9090 }
          envFrom:
            - configMapRef: { name: svc-spring-config }
            - secretRef: { name: svc-spring-secrets }
          resources:
            requests: { memory: "512Mi", cpu: "250m" }
            limits: { memory: "1Gi", cpu: "1000m" }
          livenessProbe:
            httpGet: { path: /actuator/health/liveness, port: mgmt }
            initialDelaySeconds: 90
          readinessProbe:
            httpGet: { path: /actuator/health/readiness, port: mgmt }
            initialDelaySeconds: 30
apiVersion: v1
kind: Service
metadata:
  name: order-svc
  namespace: svc-spring
spec:
  selector: { app: order-svc }
  ports: [{ port: 8080, targetPort: http }]

Gateway Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:

以下内容需解锁后阅读

试读已结束。解锁本章 ¥5.00,或开通年度会员畅读全部教程。
年度会员 ¥199.00/年; 小紫 AI 工作台有效会员 ¥99.00/年

正文仅在服务端鉴权后下发,未付费无法获取下半部分内容。