记一次K8S无感知不停机升级优化

2023-12-28 19:50

本文主要是介绍记一次K8S无感知不停机升级优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 背景
    • Deployment滚动更新策略
    • 容器探针
      • 检查机制
      • 探测结果
      • 探测类型
    • 删除和新建Pod情况分析
      • 【1】新Pod启动时请求处理
      • 【2】删除pod时请求处理
    • 参考

背景

在部署项目版本升级过程中发现每次都会出现2分钟左右的502停机情况,在进行问题和排查过程中发现如下配置中存在一些可以优化的点,本文是这次操作过程的总结以及一些简单的扩展。
在这里插入图片描述
分析下上面配置,使用是没有问题的,但是没有很好的利用K8s的一些特性机制来提升升级的效率,首先我们使用了Deployment声明式组件,该组件为 Pods 和 ReplicaSets 提供声明式的更新能力,提供了默认的滚动更新机制,如果按照下面所示先执行kubectl delete操作那么会将所有pod删除,等待删除后再依次创建新的pod,那么中间必然存在一个较大的空档期,即副本数被删除完毕,开始创建第一个Pod副本时,此时访问应用就会出现502网关问题,更友好的一种方式是使用RollingUpdate 滚动更新方式,这也是默认的配置。其次,最后俩行的配置是重复了,直接执行kubectl apply是可以完成修改升级操作的。
修改完成之后再次部署发现整个发布过程还是存在一些问题,多次请求下间断性出现一些502和404的错误,经过排查发现是因为Pod启动时未完全启动成功就接入流量导致4XX问题,还有在Pod已经删除后还依然有流量接入导致出现502问题.

Deployment滚动更新策略

疑问:有了Pod组件为什么还需要Deployment组件?
分析
【1】Pod是K8S调度的最小单元。但是Pod中容器出现异常终止了是不会重启的。
【2】Deployment拥有更加灵活强大的升级、回滚功能,并且支持滚动更新
【3】使用Deployment升级Pod只需要定义Pod的最终状态,k8s会为你执行必要的操作
【4】pod是k8s里调度的最小单位,而deployment是更高一层的定义。纯pod我们是无法确保其运行,无法对其异常做出处理的。
在这里插入图片描述
Deployment提供了俩个升级机制RollingUpdate滚动更新,这也是默认的机制。即先创建一个新的 Pod,并待其成功运行以后,再删除旧的。另外一个策略是Recreate,即先删除现有的 Pod,再创建新的。关于 Deployment,还可以设置最大不可用(maxUnavailable)和最大增量(maxSurge),来更精确地控制滚动更新操作,在RollingUpdate滚动更新策略下,Deployment 控制器会不断对 ReplicaSet 进行调和,滚动更新的最大好处就是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性。

容器探针

Kubernetes 中提供了一系列的健康检查,可以定制调用,来帮助解决类似的问题,我们称之为 Probe(探针)。
probe 是由 kubelet 对容器执行的定期诊断。 要执行诊断,kubelet 既可以在容器内执行代码,也可以发出一个网络请求。

检查机制

使用探针来检查容器有四种不同的方法。 每个探针都必须准确定义为这四种机制中的一种:
exec
在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
grpc
使用 gRPC 执行一个远程过程调用。 目标应该实现 gRPC健康检查。 如果响应的状态是 “SERVING”,则认为诊断成功。 gRPC 探针是一个 alpha 特性,只有在你启用了 “GRPCContainerProbe” 特性门控时才能使用。
httpGet
对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。
tcpSocket
对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。 如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的。

探测结果

每次探测都将获得以下三种结果之一:
Success(成功)
容器通过了诊断。
Failure(失败)
容器未通过诊断。
Unknown(未知)
诊断失败,因此不会采取任何行动。

探测类型

针对运行中的容器,kubelet 可以选择是否执行以下三种探针,以及如何针对探测结果作出反应:
livenessProbe
指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success。
readinessProbe
指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。
startupProbe
指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。

删除和新建Pod情况分析

【1】新Pod启动时请求处理

默认情况下,一旦某个 pod 中的所有容器全部启动,k8s 就会认为该 pod 处于就绪状态,从而将流量发往该 pod。但某些应用启动后,还需要完成数据或配置文件的加载工作才能对外提供服务,因此通过容器是否启动来判断其是否就绪并不严谨。通过为容器配置就绪探针,能让 k8s 更准确地判断容器是否就绪,从而构建出更健壮的应用。K8s 保证只有 pod 中的所有容器全部通过了就绪探测,才允许 service 将流量发往该 pod。一旦就绪探测失败,k8s 会停止将流量发往该 pod。
对于Java语言程序来说,可能还需要启动spring boot框架,连接数据库等待,注册服务等等。这样就会导致短暂的服务不可用。尤其是对于启动耗时的应用来说更是如此,就拿参与项目为例,平均启动时间都在30s以上,在升级过程中经常会出现404的问题。
对于该类情况,就需要进行ReadinessProbe 探测来检验容器是否满足需求

【2】删除pod时请求处理

当 Pod 在 kube-proxy 或 Ingress 控制器删除之前终止,我们可能会遇到停机时间。此时,Kubernetes 仍将流量路由到 IP 地址,但 Pod 已经不存在了。Ingress 控制器、kube-proxy、CoreDNS 等也没有足够的时间从其内部状态中删除 IP地址。
理想情况下,在删除 Pod 之前,Kubernetes 应该等待集群中的所有组件更新了 endpoint 列表,但是 Kubernetes 不是那样工作的。

Kubernetes 提供了原语来分发 endpoint(即 Endpoint 对象和更高级的抽象,例如 Endpoint Slices),所以 Kubernetes 不会验证订阅 endpoint 更改的组件是否是最新的集群状态信息。

那么,如何避免这种竞争情况并确保在 endpoint 广播之后删除 Pod?我们需要等待,当 Pod 即将被删除时,它会收到 SIGTERM 信号。我们的应用程序可以捕获该信号并开始关闭。由于 endpoint 不会立即从 Kubernetes 的所有组件中删除。
处理过程:
1:等待一定的时间,然后退出
2:即便有 SIGTERM 信号,但仍然可以处理传入流量。
3:最后,关闭现有的长期连接。关闭该进程。

那么我们应该等多久?默认情况下,Kubernetes 将发送 SIGTERM 信号并等待 30 秒,然后强制终止该进程。因此,我们可以使用前 15 秒继续操作。该间隔应足以将 endpoint 删除信息传播到 kube-proxy、Ingress 控制器、CoreDNS 等,然后,到达 Pod 的流量会越来越少,直到停止。15 秒后,我们就可以安全地关闭与数据库的连接并终止该过程。

如果我们认为需要更多时间,那么可以在 20 或 25 秒时停止该过程。这里有一点要注意,Kubernetes 将在 30 秒后强行终止该进程(除非我们更改 Pod 定义中的 terminationGracePeriodSeconds)。如果我们无法更改代码以获得更长的等待时间要怎么办?我们可以调用脚本以获得固定的等待时间,然后退出应用程序。

在调用 SIGTERM 之前,Kubernetes 会在 Pod 中公开一个 preStop hook。我们可以将 preStop hook 设置为等待 15 秒。下面是一个例子:

apiVersion: v1
kind: Pod
metadata:name: my-pod
spec:containers:- name: webimage: nginxports:- name: webcontainerPort: 80lifecycle:preStop:exec:command: ["sleep", "15"]

目前的解决方式:
1:设置prestop休眠15秒
2:启动时延迟几十秒,进行tcp端口的探测,其中8888端口是容器应用的端口
3:通过本次的修改在现阶段的发布部署基本上不会有任何的升级停机切换的感知了,是非常平稳的滚动升级

       lifecycle:preStop:exec:command: ["sleep","15"]readinessProbe:failureThreshold: 3initialDelaySeconds: 15periodSeconds: 30successThreshold: 1tcpSocket:port: 8888timeoutSeconds: 1

上面的休眠的方式只是一种简单的处理方式,如果你先想要自己的业务更友好的去处理启动和停机,对于SpringBoot应用来说可以进行一些特定的配置修改来完成应用上的优雅停机,Spring Boot 2.3.0.RELEASE引入了Graceful Shutdown的功能。其中所有四个嵌入式Web服务器(Tomcat,Undertow,Netty和Jetty)都为响应式和基于Servlet的Web应用程序提供优雅停机功能。

参考

Pod 的生命周期
https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/#container-probes

Spring Boot 2.3.0配置Graceful-Shutdown,Readiness和Liveness
https://blog.csdn.net/fly910905/article/details/106895363

Liveness and Readiness Probes in Spring Boot
https://www.baeldung.com/spring-liveness-readiness-probes

K8s 中优雅停机和零宕机部署
https://zhuanlan.zhihu.com/p/188357747

K8s 应用管理之道 - 升级篇(一)
https://developer.aliyun.com/article/688626?spm=a2c6h.14164896.0.0.47b977b5MUvfoW

这篇关于记一次K8S无感知不停机升级优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/547094

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

macOS升级后SVN升级

问题 svn: error: The subversion command line tools are no longer provided by Xcode. 解决 sudo chown -R $(whoami) /usr/local/Cellar brew install svn

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟