Kubernetes 部署 Spring Boot 应用:从入门到生产实践

张开发
2026/4/5 22:52:10 15 分钟阅读

分享文章

Kubernetes 部署 Spring Boot 应用:从入门到生产实践
Kubernetes 部署 Spring Boot 应用从入门到生产实践别叫我大神叫我 Alex 就好。一、引言大家好我是 Alex。Kubernetes 已经成为云原生应用部署的事实标准而 Spring Boot 是 Java 微服务开发的首选框架。今天我想和大家分享一下如何在 Kubernetes 上部署和管理 Spring Boot 应用的最佳实践。二、容器化 Spring Boot 应用1. 优化 Dockerfile# 多阶段构建 FROM eclipse-temurin:21-jdk-alpine AS builder WORKDIR /app COPY .mvn/ .mvn COPY mvnw pom.xml ./ RUN ./mvnw dependency:go-offline COPY src ./src RUN ./mvnw clean package -DskipTests # 运行阶段 FROM eclipse-temurin:21-jre-alpine WORKDIR /app # 创建非 root 用户 RUN addgroup -S spring adduser -S spring -G spring USER spring:spring # 复制 jar 文件 COPY --frombuilder /app/target/*.jar app.jar # 健康检查 HEALTHCHECK --interval30s --timeout3s --start-period60s --retries3 \ CMD wget --no-verbose --tries1 --spider http://localhost:8080/actuator/health || exit 1 EXPOSE 8080 ENTRYPOINT [java, -XX:UseContainerSupport, -XX:MaxRAMPercentage75.0, -jar, app.jar]2. 构建配置!-- pom.xml 中的 Spring Boot Maven 插件配置 -- plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration image nameregistry.example.com/myapp:${project.version}/name builderpaketobuildpacks/builder-jammy-base:latest/builder /image layers enabledtrue/enabled /layers /configuration /plugin三、Kubernetes 部署配置1. Deployment 配置apiVersion: apps/v1 kind: Deployment metadata: name: spring-boot-app labels: app: spring-boot-app spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: spring-boot-app template: metadata: labels: app: spring-boot-app spec: containers: - name: app image: registry.example.com/myapp:1.0.0 imagePullPolicy: Always ports: - containerPort: 8080 name: http env: - name: SPRING_PROFILES_ACTIVE value: kubernetes - name: JAVA_OPTS value: -XX:UseG1GC -XX:MaxRAMPercentage75.0 -XX:InitialRAMPercentage50.0 - name: SERVER_PORT value: 8080 - name: MANAGEMENT_SERVER_PORT value: 8081 resources: requests: memory: 512Mi cpu: 500m limits: memory: 1Gi cpu: 1000m livenessProbe: httpGet: path: /actuator/health/liveness port: 8081 initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /actuator/health/readiness port: 8081 initialDelaySeconds: 30 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3 startupProbe: httpGet: path: /actuator/health/liveness port: 8081 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 30 volumeMounts: - name: tmp mountPath: /tmp volumes: - name: tmp emptyDir: {} securityContext: runAsNonRoot: true runAsUser: 1000 fsGroup: 10002. Service 配置apiVersion: v1 kind: Service metadata: name: spring-boot-app labels: app: spring-boot-app spec: type: ClusterIP ports: - port: 80 targetPort: 8080 protocol: TCP name: http - port: 8081 targetPort: 8081 protocol: TCP name: management selector: app: spring-boot-app3. Ingress 配置apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: spring-boot-app annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/ssl-redirect: true nginx.ingress.kubernetes.io/proxy-body-size: 10m nginx.ingress.kubernetes.io/rate-limit: 100 spec: ingressClassName: nginx tls: - hosts: - api.example.com secretName: api-tls-secret rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: spring-boot-app port: number: 80四、配置管理1. ConfigMap 配置apiVersion: v1 kind: ConfigMap metadata: name: spring-boot-config data: application-kubernetes.yml: | server: port: 8080 management: server: port: 8081 endpoints: web: exposure: include: health,info,metrics,prometheus endpoint: health: probes: enabled: true show-details: always spring: datasource: url: jdbc:postgresql://postgres:5432/mydb hikari: maximum-pool-size: 10 minimum-idle: 5 redis: host: redis port: 6379 kafka: bootstrap-servers: kafka:90922. Secret 配置apiVersion: v1 kind: Secret metadata: name: spring-boot-secrets type: Opaque stringData: DB_USERNAME: dbuser DB_PASSWORD: dbpassword REDIS_PASSWORD: redispassword JWT_SECRET: your-jwt-secret-key3. 环境变量注入# 在 Deployment 中引用 ConfigMap 和 Secret env: - name: SPRING_CONFIG_LOCATION value: classpath:/,file:/config/ - name: DB_USERNAME valueFrom: secretKeyRef: name: spring-boot-secrets key: DB_USERNAME - name: DB_PASSWORD valueFrom: secretKeyRef: name: spring-boot-secrets key: DB_PASSWORD volumeMounts: - name: config mountPath: /config volumes: - name: config configMap: name: spring-boot-config五、水平自动扩缩容apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: spring-boot-app-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: spring-boot-app minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 80 behavior: scaleUp: stabilizationWindowSeconds: 60 policies: - type: Percent value: 100 periodSeconds: 60 scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 10 periodSeconds: 60六、监控与日志1. Prometheus ServiceMonitorapiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: spring-boot-app-metrics labels: release: prometheus spec: selector: matchLabels: app: spring-boot-app endpoints: - port: management path: /actuator/prometheus interval: 30s2. 日志收集配置apiVersion: v1 kind: ConfigMap metadata: name: fluent-bit-config data: fluent-bit.conf: | [INPUT] Name tail Path /var/log/containers/spring-boot-app*.log Parser docker Tag kube.* Refresh_Interval 5 [FILTER] Name kubernetes Match kube.* Kube_URL https://kubernetes.default.svc:443 Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token [OUTPUT] Name es Match * Host elasticsearch Port 9200 Index spring-boot-logs Type _doc七、CI/CD 集成1. GitLab CI 配置stages: - build - test - package - deploy variables: MAVEN_OPTS: -Dmaven.repo.local.m2/repository DOCKER_REGISTRY: registry.example.com IMAGE_NAME: $DOCKER_REGISTRY/myapp build: stage: build image: eclipse-temurin:21-jdk script: - ./mvnw compile cache: paths: - .m2/repository test: stage: test image: eclipse-temurin:21-jdk script: - ./mvnw test artifacts: reports: junit: target/surefire-reports/*.xml package: stage: package image: docker:24 services: - docker:24-dind script: - docker build -t $IMAGE_NAME:$CI_COMMIT_SHA -t $IMAGE_NAME:latest . - docker push $IMAGE_NAME:$CI_COMMIT_SHA - docker push $IMAGE_NAME:latest deploy: stage: deploy image: bitnami/kubectl:latest script: - kubectl set image deployment/spring-boot-app app$IMAGE_NAME:$CI_COMMIT_SHA - kubectl rollout status deployment/spring-boot-app only: - main八、生产环境最佳实践1. 资源管理始终设置资源请求和限制使用垂直 Pod 自动扩缩容VPA优化资源分配监控资源使用情况及时调整配置2. 安全加固使用非 root 用户运行容器启用安全上下文SecurityContext使用 NetworkPolicy 限制网络访问定期扫描镜像漏洞3. 高可用配置配置 Pod 反亲和性确保 Pod 分布在不同节点使用 PodDisruptionBudget 保证最小可用副本数配置多区域部署提高容灾能力affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - spring-boot-app topologyKey: kubernetes.io/hostname九、总结Kubernetes 为 Spring Boot 应用提供了强大的部署和管理能力。通过合理的配置和最佳实践我们可以构建出高可用、可扩展、易维护的云原生应用。这其实可以更优雅一点。希望这篇文章能帮助大家更好地在 Kubernetes 上部署 Spring Boot 应用。如果你有任何问题欢迎在评论区留言。关于作者我是 Alex一个在 CSDN 写 Java 架构思考的暖男。喜欢手冲咖啡养了一只叫Java的拉布拉多。如果我的文章对你有帮助欢迎关注我一起探讨 Java 技术的优雅之道。

更多文章