k8s优雅停服

2023-11-16

在应用程序的整个生命周期中,正在运行的 pod 会由于多种原因而终止。在某些情况下,Kubernetes 会因用户输入(例如更新或删除 Deployment 时)而终止 pod。在其他情况下,Kubernetes 需要释放给定节点上的资源时会终止 pod。无论哪种情况,Kubernetes 都允许在 pod 中运行的容器在可配置的时间内正常关闭。

请查看下面的图表,以便更好地了解删除 pod 时发生的情况。

在这里插入图片描述

以下是 Pod 关闭的 2 个场景。

优雅关机

在这种情况下,pod 中的容器会在宽限期内正常关闭。容器的“正常关闭”状态表示执行可选的 pre-stop hook 和 Pod 响应 SIGTERM 信号。一旦容器成功退出,Kubelet 就会从 API Server 中删除 pod。

强制关机

在这种情况下,容器无法在宽限期内关闭。关闭失败可能是由于多种原因,包括

  • 应用程序忽略 SIGTERM 信号,
  • pre-stop hook 花费的时间超过宽限期,
  • 应用程序清理资源花费的时间超过宽限期
  • 以上的组合

当应用程序在宽限期内无法关闭时,Kubelet 会发送一个 SIGKILL 信号来强制关闭 pod 中运行的进程。根据应用程序,这可能会导致数据丢失和面向用户的错误。

在本文中,我们将重点分析优雅关闭部分。

识别问题

在 Kubernetes 中,每次部署都意味着在删除旧 pod 的同时创建新版本的 pod。
如果在此过程中没有正常关闭,可能会出现两个问题:
1.当前正在处理请求的 pod 被移除,如果请求不是幂等的,则会导致状态不一致。
2.Kubernetes 将流量路由到已经被删除的 Pod,导致处理请求失败,用户体验差。

分析问题

在删除 Kubernetes pod 的过程中,有两条平行的时间线,如下图所示。一是改变网络规则的时间线。另一个是 pod 的删除。

在这里插入图片描述

当运维人员或部署管道执行kubectl delete pod 命令时,两个过程开始。

网络规则生效

1.kube-apiserver 接收到 pod 删除请求,将 pod 在 Etcd 中的状态更新为 Terminating;
2.Endpoint Controller 从 Endpoint 对象中删除 pod 的 IP;
3.kuber-proxy 根据 Endpoint 对象的变化更新 iptables 的规则,不再将流量路由到被删除的 Pod。

删除 pod

1.kube-apiserver 接收到 Pod 删除请求,将 Pod 的再 Etcd 中的状态更新为 Terminating
2.Kubelet 在节点清理容器相关资源,如存储、网络
3.Kubelet 向容器发送 SIGTERM;如果容器内的进程没有配置,容器将立即退出。
4.如果容器在默认的 30 秒内没有退出,Kubelet 将发送 SIGKILL 并强制它退出。

通过删除 pod 的过程,我们可以看到如果容器内的进程没有配置,容器会立即退出,导致问题 1。
由于更新网络规则和删除 Pod 是同时进行的,因此不能保证在删除 Pod 之前更新网络规则。这就是可能导致问题 2 的原因。

解决方案

以下配置可以解决这些问题:

1.为容器内的进程设置正常关闭。
2.添加 preStopHook。
3.修改终止 GracePeriodSeconds。

下图显示了设置后的时间线

在这里插入图片描述

对于问题 1:为容器内的进程设置正常关闭

以 SpringBoot 为例,启用优雅关闭可以 Spring Boot 配置文件中添加下面设置:

server:
    shutdown: graceful

spring:
    lifecycle:
         timeout-per-shutdown-phase: 30s

通过使用上述配置,Spring Boot 保证在收到 SIGTERM 后不再接受新请求,并在超时内完成所有正在进行的请求的处理。即使无法及时完成,也会记录相关信息,然后强制退出。

对于 timeout 的值,应参考处理请求的最大允许持续时间。根据我们的经验,除特殊情况外,所有请求通常在 30 秒内完成处理。对于未在定义的超时时间内完成的,我们将在日志监控中捕获超时并发送警报,然后解决超时的根本原因并采取相应的措施。

这就是可以解决问题 1 的方法。其他语言和框架应该有类似的配置。

对于问题 2:添加 preStopHook

要处理问题 2,我们必须在不再将新流量路由到该 pod 后开始删除该 pod。因此,应该将 preStopHook 添加到 Kubernetes yaml 文件中,让 Kubelet 在收到删除 pod 事件时“sleep 一下”,并在开始删除 pod 之前留出足够的时间来更新网络规则。

lifecycle:
  preStop:
     exec:
        command: ["sh", "-c", "sleep 10"]  # set prestop hook

上述配置将导致 Kubelet 等待设定的时间。

修改终止 GracePeriodSeconds

参考之前删除 Pod 的分析,Kubernetes 为容器删除留下了 30 秒的最大时间尺度。如果 Spring 的优雅关闭超时时间和 Kubernetes 的 preStopHooks 之和超过 30 秒,可能会导致 Kubernetes 在 Spring Boot 处理完请求之前强行删除容器。因此,如果过程超过 30 秒,则应将 timerminationGracePeriodSeconds 调整为超出 Spring 加 preStopHook 的优雅关闭超时。

terminationGracePeriodSeconds: 45

最后,完整的 Kubernetes yaml 文件如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
   name: gracefulshutdown-app
spec:
  replicas: 3
  selector:
     matchLabels:
           app: gracefulshutdown-app
  template:
    metadata:
       labels:
         app: gracefulshutdown-app
    spec:
      containers:
        - name: graceful-shutdown-test
          image: gracefulshutdown-app:latest
          ports:
            - containerPort: 8080
          lifecycle:
            preStop:
              exec:
                command: ["sh", "-c", "sleep 10"]  #set prestop hook
       terminationGracePeriodSeconds: 45 # terminationGracePeriodSeconds

1.在Spring Boot中设置正常关闭可确保在容器终止之前完成处理正在进行的请求。
2.设置 preStopHook 确认删除 pod 和更新网络规则之间的顺序关系。3. 最后,为了给进程留出充裕的时间来处理所有请求,设置 terminationGracePeriodSeconds。

通过这三个步骤,我们可以充分解决这两个问题。本文描述了一种解决方案,用于确保假设服务将正确处理零停机部署所需的所有请求。因此,构建此功能将丰富用户体验并减少将缺陷引入服务的影响。

最后,推荐一个部署应用的平台: https://github.com/512team/dhorse

演示地址:http://dhorse-demo2.512.team

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

k8s优雅停服 的相关文章

随机推荐

  • RT1010 PWM 组成配置和 PWMX 的使用

    1 前言 本篇博文将着眼于 i MX RT1010 内部的 eFlexPWM 介绍其各个功能模块 以及 PWM 产生的原理 2 功能模块组成 以下是 RT1010 内部 PWM 的一个 Submoudle 的组成框图 从框图中我们可以看到
  • 操作系统——分页和分段

    连续分配方式会产生很多 碎片 而紧凑方式会将碎片合成可以使用的较大空间 但是代价比较大 所以产生了散列式存储 主要有一下三种方式 目录 分页 分段 段页式 分页和分段的区别 分页 分页式存储管理 将用户程序的地址空间分成若干个固定大小的区域
  • 【代码随想录】——回溯算法理论基础

    回溯是递归的副产品 只要有递归就会有回溯 虽然回溯法很难 很不好理解 但是回溯法并不是什么高效的算法 因为回溯的本质是穷举 穷举所有可能 然后选出我们想要的答案 如果想让回溯法高效一些 可以加一些剪枝的操作 但也改不了回溯法就是穷举的本质
  • AbstractExecutorService 抽象类

    java util concurrent AbstractExecutorService 是 Java 并发编程中的一个抽象类 它定义了 ExecutorService 接口的基本行为 ExecutorService 是一个接口 它提供了一
  • 驱动学习(六)ioctl

    驱动学习 六 ioctl 文章目录 驱动学习 六 ioctl 1 ioctl 2 命令码 2 1 自定义命令码 2 2 标准命令码 2 2 1 合成标准命令码的宏函数 3 测试ioctl linux内核给用户提供了两类系统调用函数 一类是数
  • 计算机中数据的表示

    机器码和真值 机器码 用二进制0 1表示数字的正负 0 表示正号 1 表示负号 且把这个数字放在最高位数字前表示 及把符号位和数值放在一起的称为机器码 真值 就是我们平常表示数字的方式 举例 真值 1001345 机器数就是0 100134
  • 【基于python实现UI自动化】3.2 selenium通过JS定位元素

    python UI自动化之selenium元素定位 1 0 selenium工具介绍 2 0 selenium环境搭建 3 0 selenium常见8大元素定位 3 1 selenium通过By定位元素 3 2 selenium通过JS定位
  • 中小学创客法则

    现在很多小学为了巩固教育成果 帮助孩子提高学习成绩 都会开设一些专业课 格物斯坦表示 想要帮助青少年们在人工智能领域学有所成 就必须掌握一门机器人编程 开展此编程离不开专业创客实验室的布局的 资源的共享 知识的碰撞 思想的创新 行动的实施这
  • 苹果手机代数_iPhone所有型号上市顺序

    iPhone所有型号上市顺序 从2007年1月9日至今 苹果已经发布了十三代iPhone手机产品 虽然并不是每一代的iPhone都是惊世之作 但任何一款都凝聚了苹果对智能手机前沿技术的思考和应用 为了方便大家了解iPhone所有型号上市顺序
  • AltiumDesigner99——常用快捷键

    lt gt 1 PCB布线下 PcbDoc p a 在keep out层画线 u a 清除所有布线 l 将顶层元器件放到底层 注意使用系统自带的英文输入法 q 切换坐标轴单位 mm mil 2 原理图库编辑下 SchLib ctrl hom
  • Linux中闲置一段时间后自动结束会话,[已退出进程,代码为0(0x00000000)]

    Linux中闲置一段时间后自动结束会话 最近在学习Linux时 常常因为闲置几分钟无操作而被结束会话 问题页面如下所示 最终发现问题在于会话配置中的参数ClientAliveInterval设置的太小了 在我的配置中 ClientAlive
  • 关于time模块使用

    在日常使用python中 会遇到很多时间转化的问题 python中时间的格式有很多种 本次主要介绍time模块中的数据格式与各数据格式之间的转化函数 time时间数据的类型 time模块中的时间总共有3种 1 struct time类型 以
  • JQUERY的AJAX中 get()、post()的跨域方法

    get 请求 ajax type get url 你的请求地址 dataType jsonp jsonp进行跨域请求 只支持get data 这里填写是传给服务端的数据 可传可不传 数据必须是json格式 a b c d success f
  • 如何在机器学习中实现分类?

    机器学习和统计学中的分类是一种监督学习方法 其中计算机程序从给定的数据中学习并进行新的观察或分类 在本文中 我们将详细了解机器学习中的分类 本博客涵盖以下主题 目录 什么是机器学习中的分类 机器学习中的分类术语 分类算法
  • 【分治算法】-1.金块问题:递归和分治策略

    例14 2 金块问题 有一个老板有一袋金块 每个月将有两名雇员会因其优异的表现分别被奖励一个金块 按规矩 排名第一的雇员将得到袋中最重的金块 排名第二的雇员将得到袋中最轻的金块 根据这种方式 除非有新的金块加入袋中 否则第一名雇员所得到的金
  • 了解搜索引擎技术

    百度 Google搜索引擎核心技术是怎么实现的 搜索引擎 搜索引擎 search engine 是指根据一定的策略 运用特定的计算机程序搜集互联网上的信息 在对信息进行组织和处理后 并将处理后的信息显示给用户 是为用户提供检索服务的系统 全
  • 源于老师的博客

    Javascript学习 老师的博客 JavaScript概述 ECMAScript和JavaScript的关系 1996年11月 JavaScript的创造者 Netscape公司 决定将JavaScript提交给国际标准化组织ECMA
  • VSCODE(十)C++语言特有设置

    C C 插件为C C 开发者提供了丰富的设置项 包括三个方面的设置 env 用户自定义的变量 可以通过类似
  • 人工神经网络建模过程,人工神经网络建模例子

    利用人工神经网络建立模型的步骤 人工神经网络有很多种 我只会最常用的BP神经网络 不同的网络有不同的结构和不同的学习算法 简单点说 人工神经网络就是一个函数 只是这个函数有别于一般的函数 它比普通的函数多了一个学习的过程 在学习的过程中 它
  • k8s优雅停服

    在应用程序的整个生命周期中 正在运行的 pod 会由于多种原因而终止 在某些情况下 Kubernetes 会因用户输入 例如更新或删除 Deployment 时 而终止 pod 在其他情况下 Kubernetes 需要释放给定节点上的资源时