k8s優雅重啟

理論上處于terminating狀態的pod,k8s 就會把它從service中移除了,只用配置一個優雅停機時長就行了。kubectl get endpoints 驗證

因此,優雅重新的核心問題,是怎么讓空閑長連接關閉,再等待處理中的請求執行完。
一些底層 HTTP 服務器(如 uvicorn),在收到SIGTERM 信號后會優雅地關閉進程,這包括清理所有的活動連接(包括空閑的 HTTP Keep-Alive 長連接),可以通過以下方法驗證:

telnet <ip> <port># 輸入以下內容按兩次Enter
GET /health HTTP/1.1
Host: <ip>
Connection: keep-alive

你將看到正常的HTTP響應,且連接沒有被關閉:

date: Fri, 24 Jan 2025 02:05:43 GMT
server: uvicorn
content-length: 4
content-type: application/json"ok"

這個時候你去讓這個pod處于terminating狀態,你會發現這個連接被關閉了:Connection closed by foreign host.

簡介

使用kubernetes啟動容器時,一般都會配置一些探針來保證pod的健康,并通過terminationGracePeriodSeconds控制pod 在接收到終止信號后等待完成清理的最大時間。

apiVersion: apps/v1
kind: Deployment
metadata:name: my-applabels:app: my-app
spec:replicas: 3selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:terminationGracePeriodSeconds: 60containers:- name: my-app-containerimage: my-app:latestports:- containerPort: 8080readinessProbe:httpGet:path: /healthport: 8080initialDelaySeconds: 5periodSeconds: 10timeoutSeconds: 2successThreshold: 1failureThreshold: 3livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 10periodSeconds: 10timeoutSeconds: 2successThreshold: 1failureThreshold: 10

通過就緒探針存活探針,使得容器啟動就緒后才會有流量轉發進來,容器故障后也能自動重啟。
但對于請求成功率要求較為嚴格的應用,這種方式存在一個較為嚴重問題:
pod滾動發布的過程中,雖然terminationGracePeriodSeconds讓容器在一定時間后再退出,給了執行中的請求一些處理時間。但是terminating的過程中還是不斷會有新請求進來,最終還是會有些請求受影響。

優雅重啟原理

優雅重啟最核心的問題就是pod在銷毀過程中,不要再轉發新請求進來。pod切換到terminating狀態時,會發送一個SIG_TERM信號,應用端需要捕獲到這個信號,將就緒探針的健康檢查接口返回400+的狀態碼(503表示未準備好),這樣失敗failureThreshold次后,k8s就不會再轉發新請求進來,在給一定時間讓在途請求處理完成。

簡介中給的yaml示例,pod在收到SIG_TERM信號后,將健康檢查接口標記為不可用,就緒探針每10秒檢查一次,連續3次失敗就不再轉發流量到該pod(30-40秒),terminationGracePeriodSeconds配置的是60秒,執行的請求此刻則還剩20-30秒時間處理。如果你覺得時間不夠,可以考慮加大terminationGracePeriodSeconds的值。

優雅重啟示例

python

python可以使用signal這個內置庫來監聽信號。

stop_event = threading.Event()def _handler_termination_signal(signum, frame, app: FastAPI) -> None:match signum:case signal.SIGINT:logging.info("Received SIGINT signal, mark service to unhealthy.")case signal.SIGTERM:logging.info("Received SIGTERM signal, mark service to unhealthy.")case _:logging.warning(f"Received unexpected signal: {signum}")returnsignal.signal(signal.SIGTERM, partial(_handler_termination_signal, app=app))
signal.signal(signal.SIGINT, partial(_handler_termination_signal, app=app))  # ctrl + c 停止@app.get("/health")
async def health_check(request: Request):if stop_event.is_set():return PlainTextResponse("stopped", status_code=503)return "ok"

gunicorn

gunicorn會管理自己的主進程和worker進程,代碼中使用signal無法捕獲SIG_TERM信號,需要按照它的語法規范去捕獲。

  1. 新建gunicorn_config.py文件
import logging
import signal# 處理 SIGTERM 信號的函數
def handle_sigterm(signum, frame):from main import stop_eventlogging.info("Worker received SIGTERM, setting health to unhealthy...")stop_event.set()# Worker 初始化時設置信號處理器
def post_worker_init(worker):signal.signal(signal.SIGTERM, handle_sigterm)logging.info("Signal handler for SIGTERM set in worker")
  1. gunicorn啟動時設置config類
gunicorn -c gunicorn_config.py main:app
  1. main.py的健康檢查接口使用stop_event
import threading
from flask import Responsestop_event = threading.Event()@app.route("/health")
def health():if stop_event.is_set():return Response(json.dumps({"pid": os.getpid(), "status": "unhealthy"}),status=503,content_type="application/json",)else:return Response(json.dumps({"pid": os.getpid(), "status": "ok"}),status=200,content_type="application/json",)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67020.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67020.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67020.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Linux】華為服務器使用U盤安裝統信操作系統

目錄 一、準備工作 1.1 下載UOS官方系統 &#xff11;.&#xff12;制作啟動U盤 1.3 服務器智能管理系統iBMC 二、iBMC設置U盤啟動 一、準備工作 1.1 下載UOS官方系統 服務器CPU的架構是x86-64還是aarch64&#xff09;,地址&#xff1a;統信UOS生態社區 - 打造操作系統創…

27. 【.NET 8 實戰--孢子記賬--從單體到微服務】--簡易報表--報表服務

報表是每個記賬應用所具備的功能&#xff0c;要實現報表功能就需要把賬本的核心功能&#xff08;記賬&#xff09;完成&#xff0c;因此報表服務作為本專欄第一部分單體應用開發中最后一個要實現的功能&#xff0c;這一篇文章很簡單&#xff0c;我們一起來實現一個簡單的報表服…

基于 Node.js 的天氣查詢系統實現(附源碼)

項目概述 這是一個基于 Node.js 的全棧應用,前端使用原生 JavaScript 和 CSS,后端使用 Express 框架,通過調用第三方天氣 API 實現天氣數據的獲取和展示。 主要功能 默認顯示多個主要城市的天氣信息 支持城市天氣搜索 響應式布局設計 深色主題界面 優雅的加載動畫 技術棧 …

cursor重構谷粒商城04——vagrant技術快速部署虛擬機

前言&#xff1a;這個系列將使用最前沿的cursor作為輔助編程工具&#xff0c;來快速開發一些基礎的編程項目。目的是為了在真實項目中&#xff0c;幫助初級程序員快速進階&#xff0c;以最快的速度&#xff0c;效率&#xff0c;快速進階到中高階程序員。 本項目將基于谷粒商城…

leetcode 面試經典 150 題:簡化路徑

鏈接簡化路徑題序號71題型字符串解法棧難度中等熟練度??? 題目 給你一個字符串 path &#xff0c;表示指向某一文件或目錄的 Unix 風格 絕對路徑 &#xff08;以 ‘/’ 開頭&#xff09;&#xff0c;請你將其轉化為 更加簡潔的規范路徑。 在 Unix 風格的文件系統中規則如下…

如何在gitee/github上面搭建obsidian的圖床

在搭建圖床之前我們需要知道圖床是一個什么東西,圖床顧名思義就是存放圖片的地方&#xff0c;那么我們為什么要搭建圖床呢&#xff1f;因為我們在寫博客的時候&#xff0c;很多同學都是在本地使用typora或者是obsidian進行markdown語法的文章的書寫&#xff0c;文件格式通常都是…

JVM堆空間

JVM&#xff08;Java虛擬機&#xff09;堆空間是Java內存管理的核心區域之一&#xff0c;用于存儲Java對象實例。以下是關于JVM堆空間的詳細介紹&#xff1a; 1. 堆空間的作用 ? 存儲對象實例&#xff1a;幾乎所有的Java對象實例&#xff08;通過new關鍵字創建的對象&#xf…

Redis 的熱 Key(Hot Key)問題及解決方法

Redis 的熱 Key&#xff08;Hot Key&#xff09;問題及解決方法 1. 什么是 Redis 熱 Key&#xff1f; Redis 熱 Key&#xff08;Hot Key&#xff09;指的是訪問頻率極高的 Key&#xff0c;通常會造成以下問題&#xff1a; 單 Key 訪問量過大&#xff1a;熱點 Key 可能被高并…

SSM東理咨詢交流論壇

&#x1f345;點贊收藏關注 → 添加文檔最下方聯系方式咨詢本源代碼、數據庫&#x1f345; 本人在Java畢業設計領域有多年的經驗&#xff0c;陸續會更新更多優質的Java實戰項目希望你能有所收獲&#xff0c;少走一些彎路。&#x1f345;關注我不迷路&#x1f345; 項目視頻 js…

http的請求體各項解析

一、前言 做Java開發的人員都知道&#xff0c;其實我們很多時候不單單在寫Java程序。做的各種各樣的系統&#xff0c;不管是PC的 還是移動端的&#xff0c;還是為別的系統提供接口。其實都離不開http協議或者https 這些東西。Java作為編程語言&#xff0c;再做業務開發時&#…

gradle生命周期鉤子函數

文章目錄 0. 總結表格1. 構建初始階段gradle.settingsEvaluated()gradle.projectsLoaded() 2. 配置階段gradle.beforeProject()gradle.afterProject()gradle.projectEvaluated()gradle.afterEvaluate()gradle.taskGraph.whenReady 3. 執行階段gradle.taskGraph.beforeTaskgradl…

Qt Enter和HoverEnter事件

介紹 做PC開發的過程中或多或少都會接觸到鼠標的懸停事件&#xff0c;Qt中處理鼠標懸停有Enter和HoverEnter兩種事件 相同點 QEvent::Enter對應QEnterEvent&#xff0c;描述的是鼠標進入控件坐標范圍之內的行為&#xff0c;QEnterEvent可以抓取鼠標的位置&#xff1b;QEvent…

【云安全】云原生-Docker(五)容器逃逸之漏洞利用

漏洞利用逃逸 通過漏洞利用實現逃逸&#xff0c;主要分為以下兩種方式&#xff1a; 1、操作系統層面的內核漏洞 這是利用宿主機操作系統內核中的安全漏洞&#xff0c;直接突破容器的隔離機制&#xff0c;獲得宿主機的權限。 攻擊原理&#xff1a;容器本質上是通過 Linux 的…

如何優化深度學習模型來提高錯別字檢測準確率?

為了優化深度學習模型以提高錯別字檢測的準確率,可以從以下幾個方面入手: 1. 數據增強 數據增強是提高模型泛化能力的有效方法。通過在訓練數據中引入噪聲,模型可以學習到更多變的模式,從而提高對未見數據的識別能力。 刪除字符:以一定概率刪除文本中的一個字符。增加字…

二叉搜索樹中的搜索(力扣700)

首先介紹一下什么是二叉搜索樹。 二叉搜索樹是一個有序樹&#xff1a; 若它的左子樹不空&#xff0c;則左子樹上所有結點的值均小于它的根結點的值&#xff1b;若它的右子樹不空&#xff0c;則右子樹上所有結點的值均大于它的根結點的值&#xff1b;它的左、右子樹也分別為二叉…

pytest自動化測試 - 構造“預置條件”的幾種方式

<< 返回目錄 1 pytest自動化測試 - 構造“預置條件”的幾種方式 1.1 使用夾具構造預置條件 在夾具章節中&#xff0c;我們介紹了夾具的作用&#xff0c;其中一項就是構造預置條件。pytest.fixture裝飾器中如果測試數據使用yield返回&#xff0c;則yield前的語句為預置條…

微信小程序date picker的一些說明

微信小程序的picker是一個功能強大的組件&#xff0c;它可以是一個普通選擇器&#xff0c;也可以是多項選擇器&#xff0c;也可以是時間、日期、省市區選擇器。 官方文檔在這里 這里講一下date picker的用法。 <view class"section"><view class"se…

[java] 面向對象進階篇1--黑馬程序員

目錄 static 靜態變量及其訪問 實例變量及其訪問 靜態方法及其訪問 實例方法及其訪問 總結 繼承 作用 定義格式 示例 總結 子類不能繼承的內容 繼承后的特點 成員變量 成員變量不重名 成員變量重名 super訪問父類成員變量 成員方法 成員方法不重名 成員方法…

python3+TensorFlow 2.x 基礎學習(一)

目錄 TensorFlow 2.x基礎 1、安裝 TensorFlow 2.x 2、TensorFlow 2.x 基礎概念 2、1 Eager Execution 2、2 TensorFlow 張量&#xff08;Tensor&#xff09; 3、使用Keras構建神經網絡模型 3、1 構建 Sequential 模型 3、2 編譯模型 1、Optimizer&#xff08;優化器&a…

AI News(1/21/2025):OpenAI 安全疏忽:ChatGPT漏洞引發DDoS風險/OpenAI 代理工具即將發布

1、OpenAI 的安全疏忽&#xff1a;ChatGPT API 漏洞引發DDoS風險 德國安全研究員 Benjamin Flesch 發現了一個嚴重的安全漏洞&#xff1a;攻擊者可以通過向 ChatGPT API 發送一個 HTTP 請求&#xff0c;利用 ChatGPT 的爬蟲對目標網站發起 DDoS 攻擊。該漏洞源于 OpenAI 在處理…