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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Kubernetes—Pod

發(fā)布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Kubernetes—Pod 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

文章目錄

    • 目錄
    • 為什么需要 Pod
      • 真實操作系統(tǒng)里的例子
      • 進(jìn)程組概念
      • Pod = “進(jìn)程組”
    • 為什么 Pod 必須是原子調(diào)度單位?
    • Pod要解決的問題
      • 共享網(wǎng)絡(luò)
      • 共享存儲

為什么需要 Pod

真實操作系統(tǒng)里的例子

如果說 Kubernetes 就是操作系統(tǒng)的話,那么我們不妨看一下真實的操作系統(tǒng)的例子。

?例如,一個程序叫做 Helloworld,這個 Helloworld 程序?qū)嶋H上是由一組進(jìn)程組成的,需要注意一下,這里說的進(jìn)程實際上等同于 Linux 中的線程。

因為 Linux 中的線程是輕量級進(jìn)程,所以如果從 Linux 系統(tǒng)中去查看 Helloworld 中的 pstree,將會看到這個 Helloworld 實際上是由四個線程組成的,分別是 {api、main、log、compute}。也就是說,四個這樣的線程共同協(xié)作,共享 Helloworld 程序的資源,組成了 Helloworld 程序的真實工作情況。

?這是操作系統(tǒng)里面進(jìn)程組或者線程組中一個非常真實的例子,以上就是進(jìn)程組的一個概念。

?在真實的操作系統(tǒng)里面,一個程序往往是根據(jù)進(jìn)程組來進(jìn)行管理的。Kubernetes 把它類比為一個操作系統(tǒng),比如說 Linux。針對于容器我們可以類比為進(jìn)程,就是前面的 Linux 線程。那么 Pod 又是什么呢?實際上 Pod 就是我們剛剛提到的進(jìn)程組,也就是 Linux 里的線程組。

進(jìn)程組概念

?還是前面那個例子:Helloworld 程序由四個進(jìn)程組成,這些進(jìn)程之間會共享一些資源和文件。那么現(xiàn)在有一個問題:假如說現(xiàn)在把 Helloworld 程序用容器跑起來,你會怎么去做?

?當(dāng)然,最自然的一個解法就是,我現(xiàn)在就啟動一個 Docker 容器,里面運行四個進(jìn)程。可是這樣會有一個問題,這種情況下容器里面 PID=1 的進(jìn)程該是誰? 比如說,它應(yīng)該是我的 main 進(jìn)程,那么問題來了,誰又負(fù)責(zé)去管理剩余的 3 個進(jìn)程呢?

?這個核心問題在于,容器的設(shè)計本身是一種“單進(jìn)程”模型,不是說容器里只能起一個進(jìn)程,由于容器的應(yīng)用等于進(jìn)程,所以只能去管理 PID=1 的這個進(jìn)程,其他再起來的進(jìn)程其實是一個托管狀態(tài)。 所以說服務(wù)應(yīng)用進(jìn)程本身就具有“進(jìn)程管理”的能力。

?比如說 Helloworld 的程序有 system 的能力,或者直接把容器里 PID=1 的進(jìn)程直接改成 systemd,否則這個應(yīng)用,或者是容器是沒有辦法去管理很多個進(jìn)程的。因為 PID=1 進(jìn)程是應(yīng)用本身,如果現(xiàn)在把這個 PID=1 的進(jìn)程給 kill 了,或者它自己運行過程中死掉了,那么剩下三個進(jìn)程的資源就沒有人回收了,這個是非常非常嚴(yán)重的一個問題。

?而反過來真的把這個應(yīng)用本身改成了 systemd,或者在容器里面運行了一個 systemd,將會導(dǎo)致另外一個問題:使得管理容器,不再是管理應(yīng)用本身了,而等于是管理 systemd,這里的問題就非常明顯了。比如說我這個容器里面 run 的程序或者進(jìn)程是 systemd,那么接下來,這個應(yīng)用是不是退出了?是不是 fail 了?是不是出現(xiàn)異常失敗了?實際上是沒辦法直接知道的,因為容器管理的是 systemd。這就是為什么在容器里面運行一個復(fù)雜程序往往比較困難的一個原因。

?由于容器實際上是一個“單進(jìn)程”模型,所以如果你在容器里啟動多個進(jìn)程,只有一個可以作為 PID=1 的進(jìn)程,而這時候,如果這個 PID=1 的進(jìn)程掛了,或者說失敗退出了,那么其他三個進(jìn)程就會自然而然的成為孤兒,沒有人能夠管理它們,沒有人能夠回收它們的資源,這是一個非常不好的情況。

注意:Linux 容器的“單進(jìn)程”模型,指的是容器的生命周期等同于 PID=1 的進(jìn)程(容器應(yīng)用進(jìn)程)的生命周期,而不是說容器里不能創(chuàng)建多進(jìn)程。當(dāng)然,一般情況下,容器應(yīng)用進(jìn)程并不具備進(jìn)程管理能力,所以你通過 exec 或者 ssh 在容器里創(chuàng)建的其他進(jìn)程,一旦異常退出(比如 ssh 終止)是很容易變成孤兒進(jìn)程的。

?反過來,其實可以在容器里面 run 一個 systemd,用它來管理其他所有的進(jìn)程。這樣會產(chǎn)生第二個問題:實際上沒辦法直接管理我的應(yīng)用了,因為我的應(yīng)用被 systemd 給接管了,那么這個時候應(yīng)用狀態(tài)的生命周期就不等于容器生命周期。這個管理模型實際上是非常非常復(fù)雜的。

Pod = “進(jìn)程組”

?在 kubernetes 里面,Pod 實際上正是 kubernetes 項目為你抽象出來的一個可以類比為進(jìn)程組的概念。

?前面提到的,由四個進(jìn)程共同組成的一個應(yīng)用 Helloworld,在 Kubernetes 里面,實際上會被定義為一個擁有四個容器的 Pod,這個概念大家一定要非常仔細(xì)的理解。

?就是說現(xiàn)在有四個職責(zé)不同、相互協(xié)作的進(jìn)程,需要放在容器里去運行,在 Kubernetes 里面并不會把它們放到一個容器里,因為這里會遇到兩個問題。那么在 Kubernetes 里會怎么去做呢?它會把四個獨立的進(jìn)程分別用四個獨立的容器啟動起來,然后把它們定義在一個 Pod 里面。

?所以當(dāng) Kubernetes 把 Helloworld 給拉起來的時候,你實際上會看到四個容器,它們共享了某些資源,這些資源都屬于 Pod,所以我們說 Pod 在 Kubernetes 里面只有一個邏輯單位,沒有一個真實的東西對應(yīng)說這個就是 Pod,不會有的。真正起來在物理上存在的東西,就是四個容器。這四個容器,或者說是多個容器的組合就叫做 Pod。并且還有一個概念一定要非常明確,Pod 是 Kubernetes 分配資源的一個單位,因為里面的容器要共享某些資源,所以 Pod 也是 Kubernetes 的原子調(diào)度單位。

?上面提到的 Pod 設(shè)計,也不是 Kubernetes 項目自己想出來的, 而是早在 Google 研發(fā) Borg 的時候,就已經(jīng)發(fā)現(xiàn)了這樣一個問題。這個在 Borg paper 里面有非常非常明確的描述。簡單來說 Google 工程師發(fā)現(xiàn)在 Borg 下面部署應(yīng)用時,很多場景下都存在著類似于“進(jìn)程與進(jìn)程組”的關(guān)系。更具體的是,這些應(yīng)用之前往往有著密切的協(xié)作關(guān)系,使得它們必須部署在同一臺機(jī)器上并且共享某些信息。

為什么 Pod 必須是原子調(diào)度單位?

我們通過一個例子來解釋。

?假如現(xiàn)在有兩個容器,它們是緊密協(xié)作的,所以它們應(yīng)該被部署在一個 Pod 里面。具體來說,第一個容器叫做 App,就是業(yè)務(wù)容器,它會寫日志文件;第二個容器叫做 LogCollector,它會把剛剛 App 容器寫的日志文件轉(zhuǎn)發(fā)到后端的 ElasticSearch 中。

?兩個容器的資源需求是這樣的:App 容器需要 1G 內(nèi)存,LogCollector 需要 0.5G 內(nèi)存,而當(dāng)前集群環(huán)境的可用內(nèi)存是這樣一個情況:Node_A:1.25G 內(nèi)存,Node_B:2G 內(nèi)存。

?假如說現(xiàn)在沒有 Pod 概念,就只有兩個容器,這兩個容器要緊密協(xié)作、運行在一臺機(jī)器上。可是,如果調(diào)度器先把 App 調(diào)度到了 Node_A 上面,接下來會怎么樣呢?這時你會發(fā)現(xiàn):LogCollector 實際上是沒辦法調(diào)度到 Node_A 上的,因為資源不夠。其實此時整個應(yīng)用本身就已經(jīng)出問題了,調(diào)度已經(jīng)失敗了,必須去重新調(diào)度。

?以上就是一個非常典型的成組調(diào)度失敗的例子。英文叫做:Task co-scheduling 問題,這個問題不是說不能解,在很多項目里面,這樣的問題都有解法。

?比如說在 Mesos 里面,它會做一個事情,叫做資源囤積(resource hoarding):即當(dāng)所有設(shè)置了 Affinity 約束的任務(wù)都達(dá)到時,才開始統(tǒng)一調(diào)度,這是一個非常典型的成組調(diào)度的解法。

?所以上面提到的“App”和“LogCollector”這兩個容器,在 Mesos 里面,他們不會說立刻調(diào)度,而是等兩個容器都提交完成,才開始統(tǒng)一調(diào)度。這樣也會帶來新的問題,首先調(diào)度效率會損失,因為需要等待。由于需要等還會有外一個情況會出現(xiàn),就是產(chǎn)生死鎖,就是互相等待的一個情況。這些機(jī)制在 Mesos 里都是需要解決的,也帶來了額外的復(fù)雜度。

?另一種解法是 Google 的解法。它在 Omega 系統(tǒng)(就是 Borg 下一代)里面,做了一個非常復(fù)雜且非常厲害的解法,叫做樂觀調(diào)度。比如說:不管這些沖突的異常情況,先調(diào)度,同時設(shè)置一個非常精妙的回滾機(jī)制,這樣經(jīng)過沖突后,通過回滾來解決問題。這個方式相對來說要更加優(yōu)雅,也更加高效,但是它的實現(xiàn)機(jī)制是非常復(fù)雜的。這個有很多人也能理解,就是悲觀鎖的設(shè)置一定比樂觀鎖要簡單。

?而像這樣的一個 Task co-scheduling 問題,在 Kubernetes 里,就直接通過 Pod 這樣一個概念去解決了。因為在 Kubernetes 里,這樣的一個 App 容器和 LogCollector 容器一定是屬于一個 Pod 的,它們在調(diào)度時必然是以一個 Pod 為單位進(jìn)行調(diào)度,所以這個問題是根本不存在的。

Pod要解決的問題

?因為容器之間原本是被 Linux Namespace 和 cgroups 隔開的,所以現(xiàn)在實際要解決的是怎么去打破這個隔離,然后共享某些事情和某些信息。這就是 Pod 的設(shè)計要解決的核心問題所在。

?所以說具體的解法分為兩個部分:網(wǎng)絡(luò)和存儲。

共享網(wǎng)絡(luò)

在一個Pod中,一個容器 A 和一個容器 B需要共享Network Namespace,Kubernetes會在Pod中額外起一個Infra container小容器來共享整個Pod的Network Namespace。

Infra container 是一個非常小的鏡像,大概 100~200KB 左右,是一個匯編語言寫的、永遠(yuǎn)處于“暫停”狀態(tài)的容器。由于有了這樣一個 Infra container 之后,其他所有容器都會通過 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。

在 Pod 里面,一定有一個 IP 地址,是這個 Pod 的 Network Namespace 對應(yīng)的地址,也是這個 Infra container 的 IP 地址。所以大家看到的都是一份,而其他所有網(wǎng)絡(luò)資源,都是一個 Pod 一份,并且被 Pod 中的所有容器共享。這就是 Pod 的網(wǎng)絡(luò)實現(xiàn)方式。

共享存儲

一個 Pod 可以設(shè)置一組共享的存儲卷。 Pod 中的所有容器都可以訪問該共享卷,從而允許這些容器共享數(shù)據(jù)。卷的存在時間會超出 Pod 中運行的所有容器,并且在容器重新啟動時數(shù)據(jù)也會得到保留。 當(dāng) Pod 不再存在時,卷也將不再存在。

總結(jié)

以上是生活随笔為你收集整理的Kubernetes—Pod的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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