K8s + SpringBoot实现零宕机发布

科技   2024-12-07 11:32   陕西  

这不,最近公司也在忙着把微服务的架构迁移到 Kubernetes 上,而我作为程序员当然要为大家分享一些经验了。


别看 Kubernetes 是个非常庞大的东西,但有了这些技巧,我们可以让应用在生产环境中实现真正的零宕机发布!下面就一起来看看这背后的配置和技术细节吧!

1. 健康检查,确保应用在 Kubernetes 上能持续健康

首先,咱们得聊聊健康检查,这可算是 Kubernetes 中非常重要的一环了。你想啊,容器是动态的,随时可能因为各种原因被替换或重启,而为了保证服务的稳定性和可用性,我们得时刻监控容器的健康状态。这里有两个常见的探针类型:就绪探针(readinessProbe)存活探针(livenessProbe)
  • 就绪探针(readinessProbe):它负责检测容器是否准备好接收请求。如果容器没准备好,Kubernetes 就不会把流量路由到它。
  • 存活探针(livenessProbe):它负责监控容器是否死掉。如果容器挂掉了,Kubernetes 就会重启它。
在 Spring Boot 中,我们可以通过 Spring Boot Actuator 来轻松集成健康检查。首先,确保你已经在 pom.xml 或者 build.gradle 中添加了 actuator 依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
然后,我们在 application.yaml 中配置健康检查的端点:
management:
  endpoints:
    web:
      exposure:
        include: health,info
  health:
    diskspace:
      enabled: true
      path: /
      threshold: 100MB
这个配置会暴露 /actuator/health 作为健康检查端点。你可以通过这个端点来检查应用的健康状况。当然,你也可以根据需要自定义其他探针,比如磁盘空间、数据库连接等。
接下来,我们在 Kubernetes 中配置健康探针。比如,下面是一个 deployment.yaml 配置示例:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-springboot-app
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: my-springboot-app
    spec:
      containers:
        - name: my-springboot-container
          image: myrepo/my-springboot-app:latest
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /actuator/health
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20
通过这种方式,我们能够确保应用在 Kubernetes 中稳定运行。健康检查的配置对于实现零宕机发布至关重要,因为它确保了流量只会路由到健康的实例。

2. 滚动更新:让应用更新不中断

在 Kubernetes 中,我们常常使用 滚动更新 来平滑地升级应用,而不会导致宕机。滚动更新是一种逐步替换旧版本应用实例的方式,这样在替换过程中,至少有一个实例在运行,从而避免了服务中断。
为了实现零宕机发布,我们可以配置以下参数:maxSurgemaxUnavailable
  • maxSurge:控制可以创建的最大额外 Pod 数量。
  • maxUnavailable:控制在更新期间最多可以不可用的 Pod 数量。
例如,在 deployment.yaml 中的配置如下:
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0
这意味着在更新过程中,最多会有一个新的 Pod 被启动,并且在任何时刻,当前版本的 Pod 数量不会少于原本的数量,从而避免了流量丢失。

3. 优雅停机:确保旧版本容器平滑退出

在 Kubernetes 中,应用的优雅停机也是实现零宕机发布的关键。当你需要关闭一个 Pod 时,Kubernetes 会触发 preStop 生命周期钩子,可以在容器终止之前执行一些清理工作。Spring Boot 也有优雅关机的机制,我们可以通过设置 shutdowntrue 来让应用执行优雅关机。
首先,在 application.yaml 中开启 Spring Boot 的优雅关机:
server:
  shutdown:
    graceful: true
然后,在 Dockerfile 中,我们确保容器能够执行健康检查,并且包含 curl 工具来检测健康状态:
FROM openjdk:11-jre-slim
RUN apt-get update && apt-get install -y curl
COPY target/my-springboot-app.jar /app/my-springboot-app.jar
CMD ["java""-jar""/app/my-springboot-app.jar"]
最后,我们在 Kubernetes 中使用 preStop 钩子来确保在 Pod 被终止之前执行必要的清理操作:
lifecycle:
  preStop:
    exec:
      command: ["sh", "-c", "curl --silent --fail http://localhost:8080/actuator/shutdown"]
通过这种方式,我们确保了应用在停止之前能够完成优雅的关机,减少了宕机时间。

4. 弹性伸缩:根据负载自动扩容

在 Kubernetes 中,我们可以通过配置容器的资源限制(resources)和 水平 Pod 自动伸缩(HPA) 来实现自动扩容。资源限制可以帮助 Kubernetes 确保每个容器不会消耗过多的 CPU 或内存,而 HPA 会根据 CPU 或内存的使用情况自动调整 Pod 数量。
deployment.yaml 中,配置容器资源限制如下:
resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "500m"
同时,我们可以配置 HPA 以便根据负载自动调整 Pod 数量:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-springboot-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-springboot-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50
通过这种配置,Kubernetes 会根据 CPU 使用率自动扩容或缩容容器,确保系统负载均衡。

5. Prometheus 监控:让我们时刻掌握应用状态

零宕机发布不仅仅需要健康检查和滚动更新,还需要实时的监控来掌握应用的运行状态。我们可以通过集成 Prometheus 来实现对 Spring Boot 应用的监控。
首先,添加 Prometheus 的依赖到 pom.xml 中:
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
然后,在 application.yaml 中配置 Prometheus 集成:
management:
  metrics:
    export:
      prometheus:
        enabled: true
接下来,我们需要确保 Kubernetes 配置正确,以便 Prometheus 能够拉取应用的监控数据。可以通过以下方式暴露 Prometheus 端点:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-springboot-app
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: my-springboot-app
    spec:
      containers:
        - name: my-springboot-container
          image: myrepo/my-springboot-app:latest
          ports:
            - containerPort: 8080
            - containerPort: 8081 # Prometheus metrics port
通过这种方式,Prometheus 就能够定期抓取应用的健康和性能数据,帮助我们实时监控应用状态。

6. 配置分离:灵活管理配置

在 Kubernetes 中,我们通常使用 ConfigMap 来分离配置文件和应用代码。这样可以确保不同的环境(开发、测试、生产)使用不同的配置,而不用重新构建镜像。
创建一个 ConfigMap 来管理配置文件:
kubectl create configmap my-app-config --from-file=application.yaml
然后,在 Kubernetes 部署中挂载这个 ConfigMap:
apiVersion: apps/v1
kind: Deployment
metadata:
  name

: my-springboot-app
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: my-springboot-app
    spec:
      containers:
        - name: my-springboot-container
          image: myrepo/my-springboot-app:latest
          volumeMounts:
            - name: config-volume
              mountPath: /config
      volumes:
        - name: config-volume
          configMap:
            name: my-app-config
这样一来,配置文件就能与应用代码分离,做到环境灵活切换。

总结

通过健康检查、滚动更新、优雅停机、弹性伸缩、Prometheus 监控和配置分离等一系列配置,我们可以在 Kubernetes 中实现零宕机发布,保证应用高可用、低风险地发布新版本。希望通过这篇文章,你能对在 Kubernetes 环境下如何配置和运维 Spring Boot 应用有更深入的了解!
对编程、职场感兴趣的同学,可以链接我,微信:coder301 拉你进入“程序员交流群”。

🔥东哥私藏精品 热门推荐🔥

东哥作为一名超级老码农,整理了全网最全《Java高级架构师资料合集》

资料包含了《IDEA视频教程》《最全Java面试题库》、最全项目实战源码及视频》及《毕业设计系统源码》总量高达 650GB 。全部免费领取!全面满足各个阶段程序员的学习需求。

Java面试那些事儿
回复 java ,领取Java面试题。分享AI编程,Java教程,Java面试辅导,Java编程视频,Java下载,Java技术栈,AI工具,Java开源项目,Java简历模板,Java招聘,Java实战,Java面试经验,IDEA教程。
 最新文章