日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解Kubelet核心执行框架

發(fā)布時間:2025/3/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解Kubelet核心执行框架 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

Kubernetes已然成為云環(huán)境中大規(guī)模部署容器化應用的事實標準,而Kubelet作為Kubernetes集群中的節(jié)點代理,即節(jié)點的守護者,會具體負責其所在節(jié)點的波德的生命周期管理,切實保證各個容器應用都按照預期的狀態(tài)平穩(wěn)運行。它會首先獲取分配到本節(jié)點的波德的配置信息,再根據(jù)這些配置信息調(diào)用底層的容器運行時,例如多克爾或者PouchContainer,創(chuàng)建具體的波德,并對這些波德進行監(jiān)控,保證節(jié)點上的所有Pod按照預期的狀態(tài)運行。本文將結(jié)合Kubelet源碼,對上述過程進行詳細的分析。

?

本文作者姚增增,花名里奇,Kubernetes社區(qū)的資深貢獻者,阿里集團開源富容器引擎PouchContainer的維護者,主導并推進了PouchContainer容器技術中CRI接口的設計與實現(xiàn)。從事云原生相關的技術領域,關注容器技術,編排技術,操作系統(tǒng)內(nèi)核。當前是浙江大學??SEL?實驗室的在讀研究生,個人推崇開源理念。

1.獲取Pod配置

Kubelet有多種途徑獲取本節(jié)點需要運行的吊艙的配置信息。最重要的自然是API服務器,其次還能通過指定配置文件的目錄以及訪問特定的HTTP端口獲取.Kubelet會定期對它們進行訪問,獲取波德配置的更新并及時調(diào)整位于本節(jié)點的Pod的運行狀態(tài)。

在Kubelet初始化的時候會創(chuàng)建一個PodConfig對象如下所示:

//?kubernetes/pkg/kubelet/config/config.go type?PodConfig?struct?{pods?*podStoragemux??*config.Mux//?the?channel?of?denormalized?changes?passed?to?listenersupdates?chan?kubetypes.PodUpdate... }

PodConfig本質(zhì)上是Pod配置信息的一個復用器。內(nèi)含的mux會對各種Pod配置信息的源(包括apiserver,file以及http)進行監(jiān)聽,定期同步各源當前的Pod配置狀態(tài)。在pods中則緩存了上次同步時各源的Pod配置狀態(tài)。mux將兩者進行對比之后,即可得到配置發(fā)生變化的Pod。接著,它會根據(jù)變化類型對不同的Pod進行分類,每個類型的Pod注入一個PodUpdate結(jié)構(gòu)中:

//?kubernetes/pkg/kubelet/types/pod_update.go type?PodUpdate?struct?{Pods???[]*v1.PodOp?????PodOperationSource?string }

Op字段即定義了上述的Pod變化類型。例如,它的值可以為ADD或REMOVE,表示對Pods中定義的Pod進行相應的增選。最后,各種類型的PodUpdate都會被注入到PodConfig的updates中。因此,我們只要對updates這個頻道進行監(jiān)聽,就能得到所有有關本節(jié)點Pod的更新信息。

2.對Pod進行同步

當Kubelet初始化完成之后,最終會調(diào)用如下所示的syncLoop函數(shù):

//?kubernetes/pkg/kubelet/kubelet.go //?syncLoop?is?the?main?loop?for?processing?changes.?It?watches?for?changes?from //?three?channels?(file,?apiserver,?and?http)?and?creates?a?union?of?them.?For //?any?new?change?seen,?will?run?a?sync?against?desired?state?and?running?state.?If //?no?changes?are?seen?to?the?configuration,?will?synchronize?the?last?known?desired //?state?every?sync-frequency?seconds.?Never?returns. func?(kl?*Kubelet)?syncLoop(updates?<-chan?kubetypes.PodUpdate,?handler?SyncHandler){...for?{if?!kl.syncLoopIteration(...)?{break}????????}... }

正如它的注釋所表明的,syncLoop函數(shù)是Kubelet的主循環(huán)。它會對updates進行監(jiān)聽,獲取吊艙的最新配置,并在當前狀態(tài)(運行狀態(tài))和期望狀態(tài)(所需狀態(tài))之間進行同步,使本節(jié)點的pod都按預期狀態(tài)運行。事實上,syncLoop僅僅對對syncLoopIteration的封裝,每一次具體的同步操作都將交由syncLoopIteration完成。

//?kubernetes/pkg/kubelet/kubelet.go func?(kl?*Kubelet)?syncLoopIteration(configCh?<-chan?kubetypes.PodUpdate?......)?bool?{select?{case?u,?open?:=?<-configCh:switch?u.Op?{case?kubetypes.ADD:handler.HandlePodAdditions(u.Pods)case?kubetypes.UPDATE:handler.HandlePodUpdates(u.Pods)...}case?e?:=?<-plegCh:...handler.HandlePodSyncs([]*v1.Pod{pod})...case?<-syncCh:podsToSync?:=?kl.getPodsToSync()if?len(podsToSync)?==?0?{break}handler.HandlePodSyncs(podsToSync)case?update?:=?<-kl.livenessManager.Updates():if?update.Result?==?proberesults.Failure?{...handler.HandlePodSyncs([]*v1.Pod{pod})}case?<-housekeepingCh:...handler.HandlePodCleanups()...} }

syncLoopIteration函數(shù)的處理邏輯很簡單,它會對多個渠道進行監(jiān)聽,一旦從某個渠道中獲取到了某類事件,就調(diào)用相應的處理函數(shù)對其進行處理。下面,我們對各類事件做一個簡單的敘述:

  • 從configCh中莢電子雜志配置信息的改變,并根據(jù)改變的類型,調(diào)用對應的處理函數(shù)。例如有新的吊艙綁定到本節(jié)點上時,調(diào)用就會HandlePodAdditions在本。節(jié)點上新建這些吊艙。如果某些莢的配置發(fā)生了改變,則會調(diào)用HandlePodUpdates對這些pod進行更新。

  • 若莢中有容器的狀態(tài)發(fā)生了變化,例如有新的容器創(chuàng)建并運行,則會向plegCh這個通道發(fā)送PodlifecycleEvent這樣一個事件,其中包含了事件類型ContainerStarted,該容器的ID,以及它所屬Pod的ID,接著syncLoopIteration會調(diào)用HandlePodSyncs對該pod進行同步。

  • syncCh其實是一個定時器,Kubelet默認每隔一秒它就會觸發(fā)一次,對當前節(jié)點上所有需要同步的pod進行同步。

  • Kubelet在初始化過程中會創(chuàng)建livenessManager,它會對進行了相關配置的吊艙進行健康檢查。一旦檢測到吊艙的運行狀態(tài)出錯,同樣會調(diào)用HandlePodSyncs對相應的吊艙進行同步。關于這部分的內(nèi)容,我們將在下文中詳細描述。

  • houseKeepingCh同樣是一個定時器,Kubelet默認每隔兩秒它就會觸發(fā)一次并調(diào)用處理函數(shù)HandlePodCleanups。簡單地說,這就是一個定時清理的機制,每隔一段時間對那些已經(jīng)結(jié)束運行的pod的相關資源進行回收。


  • 如上圖所示,大多數(shù)處理函數(shù)的執(zhí)行路徑是非常類似的。

    ?

    不管是HandlePodAdditions,HandlePodUpdates還是HandlePodSyncs都會在完成自己特有的一些操作之后調(diào)用dispatchWork函數(shù)。而dispatchWork函數(shù)如果確認了要同步的吊艙處于不Terminated狀態(tài),調(diào)用就會podWokers的Update方法對莢果進行更新。事實上,不管是新建莢,還是對莢的更新,同步,我們都可以將其統(tǒng)一為從當前狀態(tài)(運行狀態(tài))到目標狀態(tài)(所需狀態(tài))過渡的過程。這樣的解釋對于pod的更新和同步是很直觀的。而對于新建pod,則可以認為它的當前狀態(tài)為空,那么我們也能將其納入這個框架中。因此,無論我們是要創(chuàng)建,更新還是同步莢,我們名單最終調(diào)用只要統(tǒng)一的Update函數(shù),就能讓指定的吊艙從當前狀態(tài)轉(zhuǎn)換到目標狀態(tài)。

    podWorkers會在Kubelet初始化的過程中被創(chuàng)建,如下所示:

    //?kubernetes/pkg/kubelet/pod_workers.go type?podWorkers?struct?{...podUpdates?map[types.UID]chan?UpdatePodOptionsisWorking?map[types.UID]boollastUndeliveredWorkUpdate?map[types.UID]UpdatePodOptionsworkQueue?queue.WorkQueuesyncPodFn?syncPodFnTypepodCache?kubecontainer.Cache... }

    當Kubelet每創(chuàng)建一個新的吊艙,都會為其配置一個專有的莢工人。每個莢工人其實就是一個夠程,它會創(chuàng)建一個緩存大小為1,類型為UpdatePodOptions(一個UpdatePodOptions就是一個莢更新事件)的信道,并不斷對其監(jiān)聽來獲取pod的更新事件并調(diào)用podWorkers中syncPodFn字段指定的同步函數(shù)進行具體的同步工作。

    同時,pod worker會將該通道注冊到podWorkers中的podUpdates這個地圖中,從而可以讓外部將指定的更新事件發(fā)送到對應的pod worker,讓它進行處理。

    如果pod worker正在處理某個更新,這時候又來了另外一個更新事件怎么辦?podWorkers會將其中最新的一個緩存到lastUndeliveredWorkUpdate并在pod worker處理完當前更新事件之后馬上對其進行處理。

    最后,pod worker每處理完一次更新,都會將pod加入podWorkers的workQueue隊列,而且會附加一個時延,只有時延消耗完了,才能將pod從隊列中再次取出,進行下一次的同步。在上文中我們提到,每過1秒就會觸發(fā)一次syncCh,收集本節(jié)點上需要進行同步的豆莢調(diào)用再HandlePodSyncs進行同步。事實上,那些莢從正是workQueue中的電子雜志,在當前時間節(jié)點,時延到期的吊艙。由此,整個pod的同步過程,如下所示,形成了一個閉環(huán)。

    ?

    Kubelet在創(chuàng)建podWorkers對象的時候,會用自己的syncPod方法syncPodFn初始化。不過該方法所做的工作也僅僅是真正進行同步前的一些準備工作。例如將pod的最新狀態(tài)上傳給Apiserver,創(chuàng)建pod的專屬目錄,獲取莢的拉動秘密等等。最終,Kubelet調(diào)用會所屬其的containerRuntime的SyncPod方法進行同步工作。containerRuntime是Kubelet對底層容器運行時的一種抽象,定義了各種容器運行時需要滿足的接口。SyncPod方法就是這些接口中的一個。

    Kubelet并不會進行任何具體的容器相關的操作,所謂pod的同步,本質(zhì)上還是對相關容器狀態(tài)的改變,而要做到這一點,最終必然只能調(diào)用例如PouchContainer這樣的底層容器運行時來完成。

    下面,將我們展示進入containerRuntime的SyncPod方法,展示真正的同步工作:

    //?kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go func?(m?*kubeGenericRuntimeManager)?SyncPod(pod?*v1.Pod,?_?v1.PodStatus,?podStatus?*kubecontainer.PodStatus,?pullSecrets?[]v1.Secret,?backOff?*flowcontrol.Backoff)?(result?kubecontainer.PodSyncResult)

    該函數(shù)首先會調(diào)用computePodActions(pod, podStatus),對pod的當前狀態(tài)podStatus和pod的目標狀態(tài)pod進行比較,從而計算出我們要進行哪些具體的同步工作。計算結(jié)束之后,返回一個PodActions對象如下所示:

    //?kubernetes/pkg/kubelet/kuberuntime/kuberuntime_manager.go type?podActions?struct?{KillPod?boolCreateSandbox?boolSandboxID?stringAttempt?uint32ContainersToKill?map[kubecontainer.ContainerID]containerToKillInfoNextInitContainerToStart?*v1.ContainerContainersToStart?[]int }

    事實上,PodActions就是一個操作列表:

  • KillPod和CreateSandbox的值一般情況下是一致的,表示是否殺死當前Pod的Sandbox(若創(chuàng)建一個新Pod,則該操作為空)而創(chuàng)建一個新的

  • SandboxID用于對pod的創(chuàng)建操作進行標識,若它的值為空,表示第一次創(chuàng)建pod,否則表示殺死原有的sandbox而創(chuàng)建一個新的

  • Attempt表示pod重新創(chuàng)建sandbox的次數(shù),第一次創(chuàng)建pod時,該值為0,作用和SandboxID是類似的

  • ContainersToKill指定了我們需要殺死的pod中的一些容器,之所以要刪除它們,可能是因為容器的配置已經(jīng)發(fā)生了變化,或者對它的健康檢查失敗了

  • 如果pod的init容器還沒有全部運行完成或者在運行過程中出現(xiàn)了問題,NextInitContainerToStart表示下一個要創(chuàng)建的init container,創(chuàng)建并啟動它,此次同步結(jié)束

  • 若莢的沙箱已經(jīng)創(chuàng)建完成,init container也都運行完畢,則根據(jù)ContainersToStart啟動pod中還未正常運行的普通容器

  • 有了這樣一份操作列表之后,SyncPod剩下的操作就異常簡單了,無非是根據(jù)配置,按部就班地調(diào)用底層容器運行時的相應接口,進行具體的容器增刪工作,完成同步。

    總的來說,對于pod的同步可以簡單歸結(jié)為:當莢的目標狀態(tài)發(fā)生改變,或者每隔一個同步周期,都會觸發(fā)對相應pod的同步,而同步的具體內(nèi)容就是將容器的目標狀態(tài)和當前狀態(tài)進行比對計算,生成一張容器的啟停清單,根據(jù)該清單調(diào)用底層的容器運行時接口完成相應容器的啟停工作。

    總結(jié)

    如果簡單地將容器類比為一個進程的話,那么Kubelet本質(zhì)上就是一個面向容器的進程監(jiān)視器。它的任務就是不斷地促成本節(jié)點pod的運行狀態(tài)向目標狀態(tài)轉(zhuǎn)換。轉(zhuǎn)換的方式也非常簡單粗暴,如果有不符合要求的容器就直接刪除,再根據(jù)新的配置重建一個,并不存在對一個已有容器反復修改啟停的情況。到此為止,Kubelet核心的處理邏輯闡述完畢。

    注:

  • 文中源碼對應的Kubernetes版本為v1.9.4,commit:bee2d1505c4fe820744d26d41ecd3fdd4a3d6546

  • Kubernetes詳細的源碼注釋參加我的github

  • 參考文獻

    • Kubernetes源碼

      https://github.com/YaoZengzeng/kubernetes

    • 什么甚至是一個kubelet?

      http://kamalmarhubi.com/blog/2015/08/27/what-even-is-a-kubelet/

    ?

    阿里百萬級規(guī)模開源容器PouchContainer GA版本已發(fā)布。此版本延續(xù)以往的節(jié)奏,繼續(xù)在Cloud Native(Kubernetes)生態(tài)的支持,以及容器安全隔離等方面做了持續(xù)性增強,同時開始孵化PouchContainer的插件機制,使得生態(tài)用戶可以更加友好便捷地通過自研插件實現(xiàn)容器功能的擴展。

    ?

    PouchContainer發(fā)布GA版本之前,已在阿里巴巴數(shù)據(jù)中心得到大規(guī)模的驗證; GA版本發(fā)布之后,相信其一系列的突出特性同樣可以服務于行業(yè),作為一種開箱即用的系統(tǒng)軟件技術,幫助行業(yè)服務在推進云原生架構(gòu)轉(zhuǎn)型上占得先機。

    為了分享并促進社區(qū)的進步,邀請大家參加2018年9月9日(周日)上海PouchContainer Meetup,掃描上圖二維碼直接報名。掃掃密碼描上圖二維碼或描上圖二維碼或者點擊閱讀原文立即報名

    《新程序員》:云原生和全面數(shù)字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的深入理解Kubelet核心执行框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 日本视频在线观看 | 麻豆国产尤物av尤物在线观看 | 亚洲大胆人体 | 老子影院午夜伦不卡大全 | 蜜桃视频色 | 欧美久久久久久又粗又大 | 一级女性全黄久久生活片免费 | 男人天堂va | 热玖玖| 国产卡一卡二卡三 | 色香色香欲天天天影视综合网 | 老司机福利院 | 91xxxxx| 久久99精品久久久久久三级 | 国内精品卡一卡二卡三 | 99网站 | 午夜第一页| 少妇15p| 青青草原国产 | 日本大乳奶做爰 | 在线va| 天天干狠狠爱 | 激情小视频在线观看 | 一区二区三区免费观看视频 | 午夜久久 | 香蕉视频性 | 用我的手指扰乱你 | a亚洲天堂 | 日产精品一区 | 99色网站 | 在线观看av大片 | 中字幕一区二区三区乱码 | 国产91丝袜在线播放0 | 久久久久久久综合 | 黄色网址www | 日剧再来一次第十集 | 国产欧美日韩精品一区 | 欧美精品四区 | 国产高清不卡视频 | 999av视频 | 天天干,夜夜爽 | 久久久久亚洲AV成人网人人小说 | wwwwxxxx欧美 | av不卡一区二区三区 | 欧美日韩一区精品 | 床戏高潮做进去大尺度视频 | 人妻一区二区三区四区五区 | 欧美粗大猛烈老熟妇 | 久久成人福利 | 国产一级二级在线 | 奇米久久久 | 国产激情四射 | 日本韩国视频 | 色诱av| 国产激情一区二区三区 | 伊人中文字幕在线观看 | 免费色片网站 | 国产精品女教师 | 男人扒女人添高潮视频 | 亚洲黄色网址大全 | 久久成人精品一区二区 | 日韩一区二区不卡视频 | 欧美激情亚洲综合 | 成人免费毛片高清视频 | 色婷婷亚洲一区二区三区 | 欧美丝袜一区二区三区 | 亚洲爱爱图 | 97神马影院| 日本五十路| 欧美影院一区二区 | 人妖干美女| 韩日三级视频 | 亚洲免费av在线 | 久久婷婷影视 | 在线欧美日韩国产 | 亚洲第一字幕 | 欧美剧场| 亚洲男人第一天堂 | 成人在线视频免费看 | 女性向小h片资源在线观看 日本天天操 | 亚洲专区一区二区三区 | 深夜成人在线 | 国产一区二区福利 | 日韩在线一卡二卡 | 久草午夜 | 免费黄色小视频网站 | 亚洲AV无码片久久精品 | 久久久久久9| 超碰在线免费 | 欧美aaa在线观看 | 无码人妻精品丰满熟人区 | 波多野结衣在线播放 | 国产伦精品一区二区三区视频女 | 亚洲一区网 | 人禽高h交| 粗大的内捧猛烈进出在线视频 | www日韩| 九九热视频免费观看 | 风韵丰满熟妇啪啪区老熟熟女 |