0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

K8s+SpringBoot实现零宕机发布

jf_ro2CN3Fa 来源:CSDN-lc_1203 2023-01-31 16:31 次阅读

前言

K8s + SpringBoot实现零宕机发布:健康检查+滚动更新+优雅停机+弹性伸缩+Prometheus监控+配置分离(镜像复用)。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。

项目地址:https://github.com/YunaiV/ruoyi-vue-pro

配置

健康检查

健康检查类型:就绪探针(readiness)+ 存活探针(liveness)

探针类型:exec(进入容器执行脚本)、tcpSocket(探测端口)、httpGet(调用接口

业务层面

项目依赖 pom.xml


org.springframework.boot
spring-boot-starter-actuator

定义访问端口、路径及权限 application.yaml

management:
server:
port:50000#启用独立运维端口
endpoint:#开启health端点
health:
probes:
enabled:true
endpoints:
web:
exposure:
base-path:/actuator#指定上下文路径,启用相应端点
include:health

将暴露/actuator/health/readiness和/actuator/health/liveness两个接口,访问方式如下:

http://127.0.0.1:50000/actuator/health/readiness
http://127.0.0.1:50000/actuator/health/liveness

运维层面

k8s部署模版deployment.yaml

apiVersion:apps/v1
kind:Deployment
spec:
template:
spec:
containers:
-name:{APP_NAME}
image:{IMAGE_URL}
imagePullPolicy:Always
ports:
-containerPort:{APP_PORT}
-name:management-port
containerPort:50000#应用管理端口
readinessProbe:#就绪探针
httpGet:
path:/actuator/health/readiness
port:management-port
initialDelaySeconds:30#延迟加载时间
periodSeconds:10#重试时间间隔
timeoutSeconds:1#超时时间设置
successThreshold:1#健康阈值
failureThreshold:6#不健康阈值
livenessProbe:#存活探针
httpGet:
path:/actuator/health/liveness
port:management-port
initialDelaySeconds:30#延迟加载时间
periodSeconds:10#重试时间间隔
timeoutSeconds:1#超时时间设置
successThreshold:1#健康阈值
failureThreshold:6#不健康阈值

滚动更新

k8s资源调度之滚动更新策略,若要实现零宕机发布,需支持健康检查

apiVersion:apps/v1
kind:Deployment
metadata:
name:{APP_NAME}
labels:
app:{APP_NAME}
spec:
selector:
matchLabels:
app:{APP_NAME}
replicas:{REPLICAS}#Pod副本数
strategy:
type:RollingUpdate#滚动更新策略
rollingUpdate:
maxSurge:1#升级过程中最多可以比原先设置的副本数多出的数量
maxUnavailable:1#升级过程中最多有多少个POD处于无法提供服务的状态

优雅停机

在K8s中,当我们实现滚动升级之前,务必要实现应用级别的优雅停机。否则滚动升级时,还是会影响到业务。使应用关闭线程、释放连接资源后再停止服务

业务层面

项目依赖 pom.xml


org.springframework.boot
spring-boot-starter-actuator

定义访问端口、路径及权限 application.yaml

spring:
application:
name:
profiles:
active:@profileActive@
lifecycle:
timeout-per-shutdown-phase:30s#停机过程超时时长设置30s,超过30s,直接停机

server:
port:8080
shutdown:graceful#默认为IMMEDIATE,表示立即关机;GRACEFUL表示优雅关机

management:
server:
port:50000#启用独立运维端口
endpoint:#开启shutdown和health端点
shutdown:
enabled:true
health:
probes:
enabled:true
endpoints:
web:
exposure:
base-path:/actuator#指定上下文路径,启用相应端点
include:health,shutdown

将暴露/actuator/shutdown接口,调用方式如下:

curl-XPOST127.0.0.1:50000/actuator/shutdown

运维层面

确保dockerfile模版集成curl工具,否则无法使用curl命令

FROMopenjdk:8-jdk-alpine
#构建参数
ARGJAR_FILE
ARGWORK_PATH="/app"
ARGEXPOSE_PORT=8080

#环境变量
ENVJAVA_OPTS=""
JAR_FILE=${JAR_FILE}

#设置时区
RUNln-sf/usr/share/zoneinfo/Asia/Shanghai/etc/localtime&&echo'Asia/Shanghai'>/etc/timezone
RUNsed-i's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g'/etc/apk/repositories
&&apkadd--no-cachecurl
#将maven目录的jar包拷贝到docker中,并命名为for_docker.jar
COPYtarget/$JAR_FILE$WORK_PATH/


#设置工作目录
WORKDIR$WORK_PATH



>基于SpringCloudAlibaba+Gateway+Nacos+RocketMQ+Vue&Element实现的后台管理系统+用户小程序,支持RBAC动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
>
>*项目地址:
>*视频教程

#指定于外界交互的端口
EXPOSE$EXPOSE_PORT
#配置容器,使其可执行化
ENTRYPOINTexecjava$JAVA_OPTS-jar$JAR_FILE

k8s部署模版deployment.yaml

注:经验证,java项目可省略结束回调钩子的配置

此外,若需使用回调钩子,需保证镜像中包含curl工具,且需注意应用管理端口(50000)不能暴露到公网

apiVersion:apps/v1
kind:Deployment
spec:
template:
spec:
containers:
-name:{APP_NAME}
image:{IMAGE_URL}
imagePullPolicy:Always
ports:
-containerPort:{APP_PORT}
-containerPort:50000
lifecycle:
preStop:#结束回调钩子
exec:
command:["curl","-XPOST","127.0.0.1:50000/actuator/shutdown"]

弹性伸缩

为pod设置资源限制后,创建HPA

apiVersion:apps/v1
kind:Deployment
metadata:
name:{APP_NAME}
labels:
app:{APP_NAME}
spec:
template:
spec:
containers:
-name:{APP_NAME}
image:{IMAGE_URL}
imagePullPolicy:Always
resources:#容器资源管理
limits:#资源限制(监控使用情况)
cpu:0.5
memory:1Gi
requests:#最小可用资源(灵活调度)
cpu:0.15
memory:300Mi
---
kind:HorizontalPodAutoscaler#弹性伸缩控制器
apiVersion:autoscaling/v2beta2
metadata:
name:{APP_NAME}
spec:
scaleTargetRef:
apiVersion:apps/v1
kind:Deployment
name:{APP_NAME}
minReplicas:{REPLICAS}#缩放范围
maxReplicas:6
metrics:
-type:Resource
resource:
name:cpu#指定资源指标
target:
type:Utilization
averageUtilization:50

Prometheus集成

业务层面

项目依赖 pom.xml

 

org.springframework.boot
spring-boot-starter-actuator


io.micrometer
micrometer-registry-prometheus

定义访问端口、路径及权限 application.yaml

management:
server:
port:50000#启用独立运维端口
metrics:
tags:
application:${spring.application.name}
endpoints:
web:
exposure:
base-path:/actuator#指定上下文路径,启用相应端点
include:metrics,prometheus

将暴露/actuator/metric和/actuator/prometheus接口,访问方式如下:

http://127.0.0.1:50000/actuator/metric
http://127.0.0.1:50000/actuator/prometheus

运维层面

deployment.yaml

apiVersion:apps/v1
kind:Deployment
spec:
template:
metadata:
annotations:
prometheus:io/port:"50000"
prometheus.io/path:/actuator/prometheus#在流水线中赋值
prometheus.io/scrape:"true"#基于pod的服务发现

配置分离

方案:通过configmap挂载外部配置文件,并指定激活环境运行

作用:配置分离,避免敏感信息泄露;镜像复用,提高交付效率

通过文件生成configmap

#通过dry-run的方式生成yaml文件
kubectlcreatecm-n--from-file=application-test.yaml--dry-run=1-oyaml>configmap.yaml

#更新
kubectlapply-fconfigmap.yaml

挂载configmap并指定激活环境

apiVersion:apps/v1
kind:Deployment
metadata:
name:{APP_NAME}
labels:
app:{APP_NAME}
spec:
template:
spec:
containers:
-name:{APP_NAME}
image:{IMAGE_URL}
imagePullPolicy:Always
env:
-name:SPRING_PROFILES_ACTIVE#指定激活环境
value:test
volumeMounts:#挂载configmap
-name:conf
mountPath:"/app/config"#与Dockerfile中工作目录一致
readOnly:true
volumes:
-name:conf
configMap:
name:{APP_NAME}

汇总配置

业务层面

项目依赖 pom.xml

 

org.springframework.boot
spring-boot-starter-actuator


io.micrometer
micrometer-registry-prometheus

定义访问端口、路径及权限 application.yaml

spring:
application:
name:project-sample
profiles:
active:@profileActive@
lifecycle:
timeout-per-shutdown-phase:30s#停机过程超时时长设置30s,超过30s,直接停机

server:
port:8080
shutdown:graceful#默认为IMMEDIATE,表示立即关机;GRACEFUL表示优雅关机

management:
server:
port:50000#启用独立运维端口
metrics:
tags:
application:${spring.application.name}
endpoint:#开启shutdown和health端点
shutdown:
enabled:true
health:
probes:
enabled:true
endpoints:
web:
exposure:
base-path:/actuator#指定上下文路径,启用相应端点
include:health,shutdown,metrics,prometheus

运维层面

确保dockerfile模版集成curl工具,否则无法使用curl命令

FROMopenjdk:8-jdk-alpine
#构建参数
ARGJAR_FILE
ARGWORK_PATH="/app"
ARGEXPOSE_PORT=8080

#环境变量
ENVJAVA_OPTS=""
JAR_FILE=${JAR_FILE}

#设置时区
RUNln-sf/usr/share/zoneinfo/Asia/Shanghai/etc/localtime&&echo'Asia/Shanghai'>/etc/timezone
RUNsed-i's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g'/etc/apk/repositories
&&apkadd--no-cachecurl
#将maven目录的jar包拷贝到docker中,并命名为for_docker.jar
COPYtarget/$JAR_FILE$WORK_PATH/


#设置工作目录
WORKDIR$WORK_PATH


#指定于外界交互的端口
EXPOSE$EXPOSE_PORT
#配置容器,使其可执行化
ENTRYPOINTexecjava$JAVA_OPTS-jar$JAR_FILE

k8s部署模版deployment.yaml

apiVersion:apps/v1
kind:Deployment
metadata:
name:{APP_NAME}
labels:
app:{APP_NAME}
spec:
selector:
matchLabels:
app:{APP_NAME}
replicas:{REPLICAS}#Pod副本数
strategy:
type:RollingUpdate#滚动更新策略
rollingUpdate:
maxSurge:1
maxUnavailable:0
template:
metadata:
name:{APP_NAME}
labels:
app:{APP_NAME}
annotations:
timestamp:{TIMESTAMP}
prometheus.io/port:"50000"#不能动态赋值
prometheus.io/path:/actuator/prometheus
prometheus.io/scrape:"true"#基于pod的服务发现
spec:
affinity:#设置调度策略,采取多主机/多可用区部署
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
-weight:100
podAffinityTerm:
labelSelector:
matchExpressions:
-key:app
operator:In
values:
-{APP_NAME}
topologyKey:"kubernetes.io/hostname"#多可用区为"topology.kubernetes.io/zone"
terminationGracePeriodSeconds:30#优雅终止宽限期
containers:
-name:{APP_NAME}
image:{IMAGE_URL}
imagePullPolicy:Always
ports:
-containerPort:{APP_PORT}
-name:management-port
containerPort:50000#应用管理端口
readinessProbe:#就绪探针
httpGet:
path:/actuator/health/readiness
port:management-port
initialDelaySeconds:30#延迟加载时间
periodSeconds:10#重试时间间隔
timeoutSeconds:1#超时时间设置
successThreshold:1#健康阈值
failureThreshold:9#不健康阈值
livenessProbe:#存活探针
httpGet:
path:/actuator/health/liveness
port:management-port
initialDelaySeconds:30#延迟加载时间
periodSeconds:10#重试时间间隔
timeoutSeconds:1#超时时间设置
successThreshold:1#健康阈值
failureThreshold:6#不健康阈值
resources:#容器资源管理
limits:#资源限制(监控使用情况)
cpu:0.5
memory:1Gi
requests:#最小可用资源(灵活调度)
cpu:0.1
memory:200Mi
env:
-name:TZ
value:Asia/Shanghai
---
kind:HorizontalPodAutoscaler#弹性伸缩控制器
apiVersion:autoscaling/v2beta2
metadata:
name:{APP_NAME}
spec:
scaleTargetRef:
apiVersion:apps/v1
kind:Deployment
name:{APP_NAME}
minReplicas:{REPLICAS}#缩放范围
maxReplicas:6
metrics:
-type:Resource
resource:
name:cpu#指定资源指标
target:
type:Utilization
averageUtilization:50

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 容器
    +关注

    关注

    0

    文章

    495

    浏览量

    22060
  • spring
    +关注

    关注

    0

    文章

    340

    浏览量

    14334
  • Boot
    +关注

    关注

    0

    文章

    149

    浏览量

    35819
  • GitHub
    +关注

    关注

    3

    文章

    468

    浏览量

    16423
  • 小程序
    +关注

    关注

    1

    文章

    234

    浏览量

    12125
  • SpringBoot
    +关注

    关注

    0

    文章

    173

    浏览量

    175

原文标题:K8s + SpringBoot实现零宕机发布

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于SpringBoot mybatis方式的增删改查实现

    SpringBoot mybatis方式实现增删改查
    发表于 06-18 16:56

    springboot集成mqtt

    springboot集成mqtt,大纲一.数据入库1.数据入库解决方案二.开发实时订阅发布展示页面1.及时通讯技术2.技术整合
    发表于 07-16 07:53

    怎样去使用springboot

    怎样去使用springboot呢?学习springboot需要懂得哪些?
    发表于 10-25 07:13

    TELNET拔网线输出信息较长时宕机怎么解决

    用netutils-1.3.2版本里的telnet,发现如下两个问题:1、登录telnet之后拔网线,立马宕机2、再telnet里输入netstat,假如netstat信息比较长,立马宕机再论坛里
    发表于 08-24 14:07

    开始入门 K8s | 调度器的调度流程和算法介绍

    Kubernetes 作为当下最流行的容器自动化运维平台,以声明式实现了灵活的容器编排,本文以 v1.16 版本为基础详细介绍了 K8s 的基本调度框架、流程,以及主要的过滤器、Score 算法实现
    发表于 03-09 17:04 1177次阅读

    Docker不香吗为什么还要用K8s

    Docker 虽好用,但面对强大的集群,成千上万的容器,突然感觉不香了。 这时候就需要我们的主角 Kubernetes 上场了,先来了解一下 K8s 的基本概念,后面再介绍实践,由浅入深步步为营
    的头像 发表于 06-02 11:56 3435次阅读

    简单说明k8s和Docker之间的关系

    这篇文章主要介绍了k8s和Docker关系简单说明,本文利用图文讲解的很透彻,有需要的同学可以研究下 最近项目用到kubernetes(以下简称k8sks之间有
    的头像 发表于 06-24 15:48 3399次阅读

    k8s-ovs一款基于ovs的k8s网络插件

    ./oschina_soft/k8s-ovs.zip
    发表于 05-13 11:28 0次下载
    <b class='flag-5'>k8s</b>-ovs一款基于ovs的<b class='flag-5'>k8s</b>网络插件

    mysql部署在k8s上的实现方案

    的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。这里主要讲 mysql 部署在 k8s 上,mysql 部署在 k8s 上的优势主要有以下几点。
    的头像 发表于 09-26 10:39 2502次阅读

    SpringBoot实现多线程

    SpringBoot实现多线程
    的头像 发表于 01-12 16:59 1811次阅读
    <b class='flag-5'>SpringBoot</b><b class='flag-5'>实现</b>多线程

    什么是 SpringBoot

    本文从为什么要有 `SpringBoot`,以及 `SpringBoot` 到底方便在哪里开始入手,逐步分析了 `SpringBoot` 自动装配的原理,最后手写了一个简单的 `start` 组件,通过实战来体会了 `
    的头像 发表于 04-07 11:28 1300次阅读
    什么是 <b class='flag-5'>SpringBoot</b>?

    SpringBoot的核心注解1

    今天跟大家来探讨下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot为什么不需要XML,达到配置
    的头像 发表于 04-07 14:34 695次阅读
    <b class='flag-5'>SpringBoot</b>的核心注解1

    SpringBoot的核心注解2

    今天跟大家来探讨下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot为什么不需要XML,达到配置
    的头像 发表于 04-07 14:34 1950次阅读
    <b class='flag-5'>SpringBoot</b>的核心注解2

    k8s是什么意思?kubeadm部署k8s集群(k8s部署)|PetaExpres

    ),Kubernetes提供了应用部署,规划,更新,维护的一种机制。 在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。 kubernetes(
    发表于 07-19 13:14 1111次阅读

    k8s生态链包含哪些技术

    1. Apache APISIX Ingress 定义   在 K8s 生态中,Ingress 作为表示 K8s 流量入口的一种资源,想要让其生效,就需要有一个 Ingress Controller
    的头像 发表于 08-07 10:56 1220次阅读
    <b class='flag-5'>k8s</b>生态链包含哪些技术