Kubelet 探針如何選擇 IP:status.PodIP 溯源與“同 Pod 兩個 IP“現象解析

背景與現象

同一個 Pod 的 readiness 和 liveness 探針日志顯示連接的 IP 不一致(例如 10.10.6.10:999910.10.6.32:9999)。本文從 kubelet 源碼入手,解釋探針目標 IP 的來源、為何會出現兩個不同 IP,并給出建議與驗證方法。

在如下探針配置下:

readinessProbe:initialDelaySeconds: 5periodSeconds: 10tcpSocket:port: 9999timeoutSeconds: 1
livenessProbe:initialDelaySeconds: 60periodSeconds: 15tcpSocket:port: 9999timeoutSeconds: 1

結論摘要

  • tcpSocket.host 未顯式設置時,kubelet 探針使用“當下緩存”的 status.PodIP 作為目標主機。

  • readiness 與 liveness 是兩個獨立的 worker,按各自的周期、初始延遲讀取 kubelet 的狀態緩存。如果 Pod 在兩次讀取之間被重建(sandbox 重建、CNI 重新分配 IP),兩者可能各自命中舊/新 IP,因此日志出現兩個不同 IP。

源碼調用鏈(關鍵片段)

  • 探針(TCP)如何選擇主機:若 TCPSocket.Host 為空,使用 status.PodIP

if p.TCPSocket != nil {port, err := extractPort(p.TCPSocket.Port, container)if err != nil {return probe.Unknown, "", err}host := p.TCPSocket.Hostif host == "" {host = status.PodIP}klog.V(4).InfoS("TCP-Probe Host", "host", host, "port", port, "timeout", timeout)return pb.tcp.Probe(host, port, timeout)
}
  • 探針在每次執行前從 status manager 讀取“當下緩存”的 v1.PodStatus

status, ok := w.probeManager.statusManager.GetPodStatus(w.pod.UID)
if !ok {// Either the pod has not been created yet, or it was already deleted.klog.V(3).InfoS("No status for pod", "pod", klog.KObj(w.pod))return true
}
  • status manager 的讀取接口(返回緩存的 v1.PodStatus):

func (m *manager) GetPodStatus(uid types.UID) (v1.PodStatus, bool) {m.podStatusesLock.RLock()defer m.podStatusesLock.RUnlock()status, ok := m.podStatuses[types.UID(m.podManager.TranslatePodUID(uid))]return status.status, ok
}
  • kubelet 如何生成 PodIPs/PodIP 并寫入 v1.PodStatus(先排序,再取首個作為 PodIP):

podIPs = kl.sortPodIPs(podIPs)
for _, ip := range podIPs {apiPodStatus.PodIPs = append(apiPodStatus.PodIPs, v1.PodIP{IP: ip})
}
if len(apiPodStatus.PodIPs) > 0 {apiPodStatus.PodIP = apiPodStatus.PodIPs[0].IP
}
  • Pod 的 IP 列表來自 CRI 報告的 sandbox 網絡狀態:

func (m *kubeGenericRuntimeManager) determinePodSandboxIPs(podNamespace, podName string, podSandbox *runtimeapi.PodSandboxStatus) []string {podIPs := make([]string, 0)if podSandbox.Network == nil {klog.InfoS("Pod Sandbox status doesn't have network information, cannot report IPs", "pod", klog.KRef(podNamespace, podName))return podIPs}if len(podSandbox.Network.Ip) != 0 {if net.ParseIP(podSandbox.Network.Ip) == nil {klog.InfoS("Pod Sandbox reported an unparseable primary IP", "pod", klog.KRef(podNamespace, podName), "IP", podSandbox.Network.Ip)return nil}podIPs = append(podIPs, podSandbox.Network.Ip)}for _, podIP := range podSandbox.Network.AdditionalIps {if nil == net.ParseIP(podIP.Ip) {klog.InfoS("Pod Sandbox reported an unparseable additional IP", "pod", klog.KRef(podNamespace, podName), "IP", podIP.Ip)return nil}podIPs = append(podIPs, podIP.Ip)}return podIPs
}
  • 當 sandbox 變化時,kubelet 會覆蓋當前的 podIPs

if !kubecontainer.IsHostNetworkPod(pod) {// Overwrite the podIPs passed in the pod status, since we just started the pod sandbox.podIPs = m.determinePodSandboxIPs(pod.Namespace, pod.Name, podSandboxStatus)klog.V(4).InfoS("Determined the ip for pod after sandbox changed", "IPs", podIPs, "pod", klog.KObj(pod))
}
  • 僅從“最新且 READY 的” sandbox 讀取 IP:

// Only get pod IP from latest sandbox
if idx == 0 && podSandboxStatus.State == runtimeapi.PodSandboxState_SANDBOX_READY {podIPs = m.determinePodSandboxIPs(namespace, name, podSandboxStatus)
}
  • TCP 探針最終發起連接的位置:

func (pr tcpProber) Probe(host string, port int, timeout time.Duration) (probe.Result, string, error) {return DoTCPProbe(net.JoinHostPort(host, strconv.Itoa(port)), timeout)
}
  • hostNetwork 場景:若 PodIP 為空,用節點 IP 初始化 PodIP/PodIPs

s.HostIP = hostIPs[0].String()
if kubecontainer.IsHostNetworkPod(pod) && s.PodIP == "" {s.PodIP = hostIPs[0].String()s.PodIPs = []v1.PodIP{{IP: s.PodIP}}if utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) && len(hostIPs) == 2 {s.PodIPs = append(s.PodIPs, v1.PodIP{IP: hostIPs[1].String()})}
}

流程圖

為什么會出現兩個不同的 IP

  • readiness 與 liveness 的 worker 獨立運行、定時時間不同;每次探測都“就地讀取”緩存中的 v1.PodStatus

  • 若該 Pod 在兩次讀取之間 sandbox 重建(IP 變化),一個 worker 可能還讀到舊 IP,另一個已經讀到新 IP,于是日志顯示不同地址。

  • 雙棧時,sortPodIPs 會按節點 IP 家族偏好排序,導致 PodIP(主 IP)在不同條件下選擇不同家族的地址,也會引起切換。

  • timeoutSeconds=1 對 TCP 探針較苛刻,網絡抖動時更易出現超時和重試導致的時序差異。

配置與排查建議

  • 合理的時序參數:為 TCP 探針設置更寬松的 timeoutSecondsfailureThreshold,降低瞬時抖動影響。

  • 顯式 host(可選):在明確網絡拓撲的前提下設置 tcpSocket.host,避免依賴 status.PodIP 切換窗口。

  • 關注 hostNetwork 與雙棧:hostNetwork 以節點 IP 為準;雙棧可能改變主 IP 選擇。

  • 對齊重建時間線:結合 CNI/runtime 與 kubelet 日志,確認 IP 切換是否由 sandbox 重建觸發。

FAQ

  • status.PodIP 存在哪里?

    • 在 kubelet 的內存緩存(status manager)中,以 UID -> versionedPodStatus 記錄,探針通過 GetPodStatus 讀取。

  • 探針為什么不使用“同一時刻”的統一狀態?

    • readiness/liveness 分屬不同 goroutine,按各自周期讀取緩存的快照,沒有全局“同一時刻”的合并視圖。

  • 非 hostNetwork Pod 的 PodIP 從何而來?

    • 來自 CRI 的 sandbox 網絡狀態(primary + additional IPs),經 kubelet 排序、選主后寫入。

參考文件清單

官方源碼https://github.com/kubernetes/kubernetes/tree/release-1.22

  • pkg/kubelet/prober/prober.go

  • pkg/kubelet/prober/worker.go

  • pkg/kubelet/status/status_manager.go

  • pkg/kubelet/kubelet_pods.go

  • pkg/kubelet/kuberuntime/kuberuntime_manager.go

  • pkg/kubelet/kuberuntime/kuberuntime_sandbox.go

  • pkg/probe/tcp/tcp.go

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

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

相關文章

Arm Development Studio 安全通告:CVE-2025-7427

安全之安全(security)博客目錄導讀 目錄 一、概述 二、CVE 詳情 三、受影響產品 四、建議 五、致謝 六、版本歷史 一、概述 ARM已知悉一個影響 Arm Development Studio 的安全漏洞,該漏洞可能允許攻擊者執行 DLL 劫持攻擊(DLL hijacking attack&…

C#異步編程雙利器:異步Lambda與BackgroundWorker實戰解析

**摘要:**深入剖析兩種異步編程范式,解決GUI線程阻塞難題 一、異步Lambda表達式:事件處理的輕量化利器 核心價值:簡化事件響應中的異步操作,避免UI線程阻塞 ? 典型應用場景(WPF示例)&#xff1…

yolo world (1): 論文解讀

YOLO 系列檢測器以其高效性和實用性而聞名。然而,它們依賴于預定義和訓練的目標類別,這限制了其在開放場景中的適用性。為了解決這一限制,我們提出了 YOLO-World,這是一種創新的方法,通過視覺-語言建模和大規模數據集預訓練,增強了 YOLO 的開放詞匯檢測能力。具體來說,我…

【JVM】深入解析Java虛擬機

目錄 1. 區分JDK,JRE 和 JVM 1.1 JVM 1.2 JRE 1.3 JDK 1.4 關系總結 2. 跨平臺性 3. JVM中的內存劃分 4. JVM的類加載機制 5. 雙親委派模型 6. 垃圾回收機制(GC) 6.1 識別垃圾 6.1.1 單個引用 6.1.2 多個引用 6.2 釋放垃圾 6.…

98-基于Python的網上廚房美食推薦系統

基于Python的網上廚房美食推薦系統 - 技術分享博客 📋 目錄 項目概述技術棧系統架構核心功能實現數據庫設計推薦算法數據可視化部署與優化項目特色總結與展望 🎯 項目概述 項目背景 隨著生活節奏的加快,越來越多的人開始關注美食制作&…

創建MyBatis-Plus版的后端查詢項目

記得編碼和maven庫的檢測&#xff01;&#xff01;&#xff01; 1、maven庫導入包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupI…

開發板RK3568和stm32的異同:

RK3568 和 STM32 是兩類不同定位的處理器 / 微控制器&#xff0c;在架構、性能、應用場景等方面差異顯著&#xff0c;但也存在部分共性。以下從核心特性、異同點及典型場景進行對比&#xff1a;一、核心差異維度RK3568&#xff08;瑞芯微&#xff09;STM32&#xff08;意法半導…

C# 使用iText獲取PDF的trailer數據

文章目錄C# 使用iText獲取PDF的trailer數據iText 核心概念C# 代碼示例步驟 1: 確保已安裝 iText步驟 2: C# 代碼程序運行效果解讀 Trailer 的輸出總結C# 使用iText獲取PDF的trailer數據 開發程序debug的時候&#xff0c;看到了PDF有個trailer數據&#xff0c;挺有意思&#xf…

京東流量資產基于湖倉架構的落地實踐

在當今數字化商業浪潮中&#xff0c;數據無疑是企業的核心資產&#xff0c;而流量數據更是電商巨頭京東業務運轉的關鍵驅動力。它廣泛應用于搜索推薦、廣告投放等多個核心業務場景&#xff0c;直接影響著用戶體驗和商業效益。但隨著業務規模的不斷膨脹&#xff0c;傳統架構在處…

???????【Datawhale AI夏令營】多模態RAG財報問答挑戰賽:學習筆記與上分思考

一、 初識賽題——從迷茫到清晰剛看到賽題時&#xff0c;坦白說有些不知所措。“多模態”、“RAG”、“圖文混排PDF”&#xff0c;這些詞匯組合在一起&#xff0c;聽起來就像一個龐大而復雜的工程。但當我強迫自己靜下心來&#xff0c;從“終點”&#xff08;提交格式和評審規則…

數據挖掘2.6 Perceptron Modeling 感知器建模

Perceptron Modeling 感知器建模Linear Discriminants 線性判別式Loss Function 損失函數misclassification 誤分類0-1 Loss/Error function 0-1損失函數Hinge Loss Function 鉸鏈損失函數Optimization 優化算法Linear Discriminants 線性判別式 線性判別式公式 f(x;w)w1x(1)w…

使用qemu運行與GDB調試內核

目錄 一、前期準備 二、內核編譯 三、QEMU與GDB 1、QEMU調試參數 2、gdb vmlinux 一、前期準備 內核鏡像&#xff1a;bzimage gdb&#xff1a;x86_64 QEMU&#xff1a;qemu-system-x86_64 前置知識&#xff1a; &#xff08;1&#xff09;內核編譯 &#xff08;2&#x…

歐盟 Radio Equipment Directive (RED)

歐盟 Radio Equipment Directive (RED) ——從 2014/53/EU 原文到 2025-08-01 強制生效的網絡安全新規&#xff0c;一次看懂全部關鍵點。1. 法規身份與適用范圍要素內容指令全稱Directive 2014/53/EU on radio equipment取代指令1999/5/EC (R&TTE)適用產品所有“有意發射/接…

【FastExcel】解決ReadSheet在Map中獲取對象不準確問題(已提交PR并合并到開源社區)

解決問題&#xff1a;源碼ReadSheet在同一個Map中獲取對象不準確問題 PR&#xff1a;Fixed the issue where different ReadSheet objects could not get the correct value when comparing them. 一&#xff1a;問題場景 ReadSheet在同一個Map中獲取對象不準確(如Map<…

【網絡安全入門基礎教程】TCP/IP協議深入解析(非常詳細)零基礎入門到精通,收藏這一篇就夠了

前言 這是小編給粉絲盆友們整理的網絡安全入門到精通系列第三章計算機網絡中TCP/IP協議的解析&#xff0c;喜歡的朋友們&#xff0c;記得給大白點贊支持和收藏一下&#xff0c;關注我&#xff0c;學習黑客技術。TCP/IP協議包含了一系列的協議&#xff0c;也叫TCP/IP協議族&…

Latex中公式部分輸入正體的字母\mathrm{c}

Latex中公式部分輸入正體的字母\mathrm{c}“\mathrm{c}”如何在Word中輸入\mathrm{c}“\mathrm{c}” 在 LaTeX 中&#xff0c;“\mathrm{c}” 用于在數學模式中排版“c”這個字母為羅馬體&#xff08;正體&#xff09;。“\mathrm” 是羅馬字體命令&#xff0c;它告訴LaTeX以羅…

Document Picture-in-Picture API擁抱全新浮窗體驗[參考:window.open]

在前端開發中&#xff0c;我們經常會遇到這樣的需求&#xff1a;彈出一個浮動窗口來顯示一些實時信息、工具欄或視頻內容。過去我們會用 window.open()&#xff0c;后來越來越多的開發者傾向于使用 Modal。但現在&#xff0c;一個更現代的 API 出現了——Document Picture-in-P…

【指南版】網絡與信息安全崗位系列(三):安全運維工程師

一、安全運維工程師到底做什么&#xff1f;—— 用校園場景幫你理解簡單說&#xff0c;安全運維工程師就像 “網絡世界的安保隊長 系統管家”&#xff1a;既要實時監控網絡和系統的 “異常動靜”&#xff08;類似學校保安巡邏查隱患&#xff09;&#xff0c;又要負責日常的安全…

matlab——simulink學習(5向NXP庫中添加新模塊)

向NXP庫中添加新的函數模塊一、環境二、庫添加模塊1.打開文件夾2.創建文件3.添加S-Function三、瀏覽器添加模塊一、環境 Windows10、MATLAB R2022b、安裝NXP的S32K1XX系列工具包 二、庫添加模塊 1.打開文件夾 在文件系統中找到安裝工具包的位置&#xff0c;用文件資源管理器…