当前位置: 首页 > news >正文

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 --from=builder /app/target/*.jar app.jar # 健康检查 HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1 EXPOSE 8080 ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]

2. 构建配置

<!-- pom.xml 中的 Spring Boot Maven 插件配置 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <image> <name>registry.example.com/myapp:${project.version}</name> <builder>paketobuildpacks/builder-jammy-base:latest</builder> </image> <layers> <enabled>true</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:MaxRAMPercentage=75.0 -XX:InitialRAMPercentage=50.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: 1000

2. 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-app

3. 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:9092

2. 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-key"

3. 环境变量注入

# 在 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 ServiceMonitor

apiVersion: 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: 30s

2. 日志收集配置

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 技术的优雅之道。

http://www.jsqmd.com/news/593893/

相关文章:

  • 基于PLC智能家居控制系统设计
  • 集成学习完全指南:从AdaBoost到随机森林,揭秘为什么一群“弱鸡”能吊打“学霸”
  • 2026年厦门美妆护肤行业GEO优化方法解析与3家实力服务商推荐 - 小白条111
  • 2026年美国移民机构排名及综合实力分析 - 品牌排行榜
  • 2026年美国移民项目推荐公司选择指南 - 品牌排行榜
  • go学习笔记4(数组与切片,map,if,switch,for循环)
  • 2026年美妆护肤行业AI搜索优化怎么做效果好?推荐3家实力口碑兼具的GEO优化服务商 - 小白条111
  • Python数据类配置模式详解
  • 计算机毕业设计:Python智析二手车数据可视化及价格预测系统 Django框架 可视化 线性回归 数据分析 机器学习 深度学习 AI 大模型(建议收藏)✅
  • 算法分析与设计
  • 拒绝“骚扰”标签:国内企业品牌来电名片服务商综合实力调研 - 企业服务推荐
  • 手把手教你用RFSoC ZU47DR的DAC/ADC:从单音信号到1200MHz宽带调制的避坑实践
  • 深度解析:Agent 如何处理“开放性目标”与“约束性规则”的冲突?
  • 2026夏天穿长裤不想热成狗?5个品牌深度实测,上班户外多功能通勤裤,帮你避开80%的坑 - 行业深度观察
  • MTKClient技术内幕:从硬件交互到场景落地的深度探索
  • 53645
  • SPM处理fMRI数据卡住了?用Python脚本+dcm2niix实现DICOM到NII的批量分拆转换
  • Rancher国内网络卡脖子?手把手教你配置私有镜像仓库(避坑RKE2 registries.yaml)
  • 算法奇妙屋(四十二)-贪心算法学习之路 9
  • go学习笔记7(泛型,文件读写,测试)
  • HFSS新手避坑指南:手把手教你调出2.45GHz的侧馈矩形微带天线
  • 实战指南:基于快马平台生成企业级cc switch管理系统,助力游戏项目开发
  • 3分钟学会iOS虚拟定位:免费开源工具iFakeLocation终极指南
  • 深入理解Python @dataclass:从基础到高级用法
  • 2026最权威的十大降AI率平台实测分析
  • 【数据结构与算法】动态规划
  • 基于VSC控制的400kW光伏并网发电厂模型
  • # 微前端架构实战:基于 Vue 3+ qiankun 的模块化开发与部署优
  • Visio 2013小白必看:3分钟搞定E-R图绘制(附数据库模型图技巧)
  • 告别OBS!用JavaCV+FFmpeg在Windows上搭建个人直播推流服务器(含Nginx配置)