首页 > 其他分享 >D24 kubernetes 通过钩子如果优雅的停机{PreStop}

D24 kubernetes 通过钩子如果优雅的停机{PreStop}

时间:2024-09-24 16:45:36浏览次数:10  
标签:容器 kubernetes 钩子 停机 D24 优雅 PreStop preStop pod

1、背景

	在 Kubernetes 中,每次微服务的代码发布都意味着创建新版本的 pod 并删除旧 pod,如果部署不够优雅的话,可能出现如下两个问题:
  1. 正在处理请求的pod被删除,在请求没有做幂等处理的情况下,就会出现数据重复、数据错误,亦或导致分布式系统数据不一致;
  2. Kubernetes 将流量路由到已被删除的 pod,导致处理请求失败造成用户体验不佳。
    所以,为了让代码发布的部署过程不影响业务的正常运行和用户无感知,我们需要实现容器的优雅停机。

2、容器的生命周期钩子

	在介绍优雅停机之前,我们先来了解下k8s的容器都有哪些生命周期钩子?作用是什么?要怎么使用?
  • Kubernetes的容器有两种生命周期钩子(Lifecycle Hooks):
**PostStart**
这个钩子会在容器被创建后立即执行,但无法保证会在容器的起始点 ENTRYPOINT之前执行,如果执行时间太长,将会阻止Pod状态进入running,可用于数据初始化、容器启动回调等场景。如果需要保证在应用程序启动前就要执行完的任务,可以考虑放在初始化容器( Init Containers)中去实现。
**PreStop**
这个钩子会在容器被结束前执行,执行期间Pod状态为 Terminating,运行时间受终止宽限期( terminationGracePeriodSeconds)约束,超出宽限期Pod将被强制杀死,可用于容器回收前的数据清理、优雅停机等场景。
	上述的两个钩子(PostStart 和 PreStop)都有四种类型,分别为:exec、httpGet、tcpSocket 和 sleep。由于这四种钩子类型在 PostStart 和 PreStop 中的使用方法一致,下面以 PreStop 为例介绍这四种钩子类型的使用方法:
  • exec(执行shell指令,可以是指令或shell脚本, 退出状态码为 0则为成功)
# shell指令模式
lifecycle:
  preStop:
    exec:
      command: ["/bin/sh", "-c", "echo 'Container is stopping'"]

# shell脚本模式
lifecycle:
  preStop:
    exec:
      command: ["/bin/sh", "-c", "/data/scripts/preStop.sh"]
  • httpGet(执行http get请求,响应状态码在[200,400)区间则为成功
lifecycle:
  preStop:
    httpGet:
      path: /shutdown  # 请求的uri
      port: 8080       # 端口
      host: api.yilingyi.com  # 主机域名,不加该字段将请求Pod本身
      scheme: HTTP     # http协议,默认值HTTP,支持HTTP、HTTPS
  • tcpSocket(执行tcp socket请求, TCP连接成功建立则为成功)
lifecycle:
  preStop:
    tcpSocket:
      port: 8080
  • sleep(将容器暂停5秒,Kubernetes 1.30的新特性 PodLifecycleSleepAction,待验证)
lifecycle:
  preStop:
    sleep:
      seconds: 5

请注意,如果 PostStart 或 PreStop 回调失败,容器将被杀死,所以回调处理的程序应尽量轻量级及把控好执行的时间。

3、微服务优雅停机实现

	本文将以k8s + SpringBoot + Nacos作为案例,介绍在实际业务场景中如何实现微服务的优雅停机,从而实现代码发布时的零宕机。
  • 首先,先看看pod的默认删除过程:
1. Kube-apiserver接收到pod的删除请求,在Etcd上更新pod的状态为Terminating;
2. Kubelet 清理节点上容器相关的资源,如存储、网络;
3. Kubelet向容器发送SIGTERM,如果容器内进程没有任何配置,则容器立即退出。
4. 如果容器在默认的 30 秒内没有退出,Kubelet 将发送 SIGKILL 并强制其退出。
	可以看出,在没有配置优雅停机之前,pod的删除相当暴力,所以为了更加优雅,我们加入了preStop hook,和将终止宽限期延长,具体实现如下:
1.  preStop hook做了两件事情:
    1)nacos反注册(也称 实例注销),确保在实例关闭期间不会再有新的请求被路由到该实例。
    2)  sleep 35s,nacos客户端的实例缓存为30s,30s后会重新拉取实例信息,超时为10s,一般不用10s这么长,所以我们设置为35s。
2.  springboot开启优雅停机后,最大等待时间为30s。
3.  terminationGracePeriodSeconds默认为30s,远小于preStop和springboot的时间之和,所以我们需要将其调大,我这里设置的是60s。
4.  其实在terminationGracePeriodSeconds耗尽后,k8s还给了一个2s的额外宽限期,最后才执行SIGKILL。

image

4、操作步骤

	在SpringBoot > 2.3.0的版本后支持应用程序优雅停机,需要在java微服务的配置中设置如下两个属性,这一步很重要!!!
server:
  # 默认值immediate:即立即关闭,graceful:即优雅停机
  shutdown: graceful
spring:
  lifecycle:
    # 优雅停机最大等待时间,默认30s
    timeout-per-shutdown-phase: 30s
  • 在微服务的yaml文件加上优雅停机的配置:通过env定义POD_IP获取当前Pod的ip,传递给preStop进行nacos反注册。
apiVersion: v1
kind: Pod
metadata:
  name: sre-yilingyi
spec:
  containers:
  - name: sre-yilingyi
    image: 'sre/yilingyi:1.0.0'
    env:
      - name: POD_IP
        valueFrom:
          fieldRef:
            apiVersion: v1
            fieldPath: status.podIP
    lifecycle:
      preStop:
        exec:
          command:
            - /bin/sh
            - '-c'
            - >
              curl -s --connect-timeout 10 -m 20 -X POST "http://nacos.yilingyi.com:8848/nacos/v1/ns/instance?port=8080&healthy=true&ip=${POD_IP}&weight=1&enabled=false&serviceName=sre-yilingyi&encoding=GBK&namespaceId=production" && sleep 35
  terminationGracePeriodSeconds: 60

至此,完成微服务的优雅停机配置。

标签:容器,kubernetes,钩子,停机,D24,优雅,PreStop,preStop,pod
From: https://www.cnblogs.com/suyj/p/18429547

相关文章

  • D23 kubernetes 工作负载资源对象-Job与CronJob
    1、简介 Deployment和DaemonSet资源主要用于部署和管理守护进程型的应用程序,如nginx、mysql、java进程等。这类应用程序的特点是持续运行,通常在没有明确停止或下线的情况下一直保持运行状态。此外,kubernetes还提供了Job和CronJob资源,用于管理一次性任务和定时任务,如计算任务、数......
  • Centos7.9部署kubernetes(一主两从)(版本1.17.4)
    部署kubernetes1、环境准备IP系统配置角色192.168.8.180centos7.92H4Gmaster192.168.8.181centos7.92H4Gnode1192.168.8.178centos7.92H4Gnode22、在所有节点上关闭swap分区masternode#临时关闭swap分区swapoff-asysctl-wvm.s......
  • 【Kubernetes基础】Helm工具入门与使用
    前言Helm是Kubernetes包管理工具,类似CentOS的yum包管理工具学习Kubernetes,了解如何通过Helm安装跟管理Kubernetes应用很有必要,下面就来介绍Helm的入门使用。一、Helm基本管理1.1检查Helm版本helmversionhelmversion二、配置Helm仓库Helm可以通过添加仓库源来使......
  • Kubernetes最新版本部署完整过程(1.31)
    参考官方文档进行部署:Kubernetes一、环境准备本次实验使用的操作系统为:Centosstream91.1节点规划一台兼容的Linux主机。Kubernetes项目为基于Debian和RedHat的Linux发行版以及一些不提供包管理器的发行版提供通用的指令。每台机器2GB或更多的RAM(......
  • 探索 Kubernetes 服务网格:Istio 实战指南
    ......
  • kubernetes集群公共服务 DNS
    1.我们先按照之前的方式新增加一个虚拟机。一、软件安装#yum-yinstallbind二、软件配置2.1主配置文件修改#vim/etc/named.conf#cat-n/etc/named.conf1//2//named.conf3//4//ProvidedbyRedHatbindpackagetoconfiguretheISCB......
  • Kubernetes-1. 介绍和安装
    1.Kubernetes介绍下载网址:https://github.com/kubernetes/kubernetes/releases1.1Kubernetes的概述容器编排技术:容器编排系统可以对多个docker主机进行统一的管理和调度,协调容器化应用程序的部署、伸缩、发现和管理。主要的容器编排系统如下DockerSwarm:Docker官方提供......
  • Kubernetes集群部署(kubernetes)
    三台主机恢复到docker快照状态;检查驱动器类型为sytemd;设置各个节点的主机名;然后同步会话,修改hosts文件;在k8s运行过程中不建议使用交换分区;关闭交换分区;但是这种方法是临时性的;如何设置永久不启用交换分区;交换分区也是以挂载的方式加入到系统中的;注释掉......
  • 【Kubernetes】常见面试题汇总(二十四)
    目录 71.假设一家公司想要修改它的部署方法,并希望建立一个更具可扩展性和响应性的平台。您如何看待这家公司能够实现这一目标以满足客户需求?72.考虑一家拥有非常分散的系统的跨国公司,期待解决整体代码库问题。您认为公司如何解决他们的问题?特别说明:题目69-113属于【Kube......
  • 【Kubernetes】常见面试题汇总(二十九)
    目录 81.简述你知道的几种CNI网络插件,并详述其工作原理。K8s常用的CNI网络插件(calico&&flannel),简述一下它们的工作原理和区别。特别说明:题目  1-68  属于【Kubernetes】的常规概念题,即“汇总(一)~(二十二)”。题目69-113属于【Kubernetes】的生产应用题。8......