欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

揭秘:如何為Kubernetes實現(xiàn)原地升級

揭秘:如何為 Kubernetes 實現(xiàn)原地升級

作者 | 王思宇(酒祝) 阿里云技術專家

創(chuàng)新互聯(lián)建站-專業(yè)網站定制、快速模板網站建設、高性價比清原網站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式清原網站制作公司更省心,省錢,快速模板網站建設找我們,業(yè)務覆蓋清原地區(qū)。費用合理售后完善,十多年實體公司更值得信賴。

參與阿里巴巴云原生文末留言互動,即有機會獲得贈書福利及作者答疑!

概念介紹

原地升級一詞中,“升級”不難理解,是將應用實例的版本由舊版替換為新版。那么如何結合 Kubernetes 環(huán)境來理解“原地”呢?

我們先來看看 K8s 原生 workload 的發(fā)布方式。這里假設我們需要部署一個應用,包括 foo、bar 兩個容器在 Pod 中。其中,foo 容器第一次部署時用的鏡像版本是 v1,我們需要將其升級為 v2 版本鏡像,該怎么做呢?

  • 如果這個應用使用 Deployment 部署,那么升級過程中 Deployment 會觸發(fā)新版本 ReplicaSet 創(chuàng)建 Pod,并刪除舊版本 Pod。如下圖所示:

揭秘:如何為 Kubernetes 實現(xiàn)原地升級

在本次升級過程中,原 Pod 對象被刪除,一個新 Pod 對象被創(chuàng)建。新 Pod 被調度到另一個 Node 上,分配到一個新的 IP,并把 foo、bar 兩個容器在這個 Node 上重新拉取鏡像、啟動容器。

  • 如果這個應該使用 StatefulSet 部署,那么升級過程中 StatefulSet 會先刪除舊 Pod 對象,等刪除完成后用同樣的名字在創(chuàng)建一個新的 Pod 對象。如下圖所示:

揭秘:如何為 Kubernetes 實現(xiàn)原地升級

值得注意的是,盡管新舊兩個 Pod 名字都叫 pod-0,但其實是兩個完全不同的 Pod 對象(uid也變了)。StatefulSet 等到原先的 pod-0 對象完全從 Kubernetes 集群中被刪除后,才會提交創(chuàng)建一個新的 pod-0 對象。而這個新的 Pod 也會被重新調度、分配IP、拉鏡像、啟動容器。

  • 而所謂原地升級模式,就是在應用升級過程中避免將整個 Pod 對象刪除、新建,而是基于原有的 Pod 對象升級其中某一個或多個容器的鏡像版本:

揭秘:如何為 Kubernetes 實現(xiàn)原地升級

在原地升級的過程中,我們僅僅更新了原 Pod 對象中 foo 容器的 image 字段來觸發(fā) foo 容器升級到新版本。而不管是 Pod 對象,還是 Node、IP 都沒有發(fā)生變化,甚至 foo 容器升級的過程中 bar 容器還一直處于運行狀態(tài)。

總結:這種只更新 Pod 中某一個或多個容器版本、而不影響整個 Pod 對象、其余容器的升級方式,被我們稱為 Kubernetes 中的原地升級。

收益分析

那么,我們?yōu)槭裁匆?Kubernetes 中引入這種原地升級的理念和設計呢?

首先,這種原地升級的模式極大地提升了應用發(fā)布的效率,根據(jù)非完全統(tǒng)計數(shù)據(jù),在阿里環(huán)境下原地升級至少比完全重建升級提升了 80% 以上的發(fā)布速度。這其實很容易理解,原地升級為發(fā)布效率帶來了以下優(yōu)化點:

  1. 節(jié)省了調度的耗時,Pod 的位置、資源都不發(fā)生變化;
  2. 節(jié)省了分配網絡的耗時,Pod 還使用原有的 IP;
  3. 節(jié)省了分配、掛載遠程盤的耗時,Pod 還使用原有的 PV(且都是已經在 Node 上掛載好的);
  4. 節(jié)省了大部分拉取鏡像的耗時,因為 Node 上已經存在了應用的舊鏡像,當拉取新版本鏡像時只需要下載很少的幾層 layer。

其次,當我們升級 Pod 中一些 sidecar 容器(如采集日志、監(jiān)控等)時,其實并不希望干擾到業(yè)務容器的運行。但面對這種場景,Deployment 或 StatefulSet 的升級都會將整個 Pod 重建,勢必會對業(yè)務造成一定的影響。而容器級別的原地升級變動的范圍非常可控,只會將需要升級的容器做重建,其余容器包括網絡、掛載盤都不會受到影響。

最后,原地升級也為我們帶來了集群的穩(wěn)定性和確定性。當一個 Kubernetes 集群中大量應用觸發(fā)重建 Pod 升級時,可能造成大規(guī)模的 Pod 飄移,以及對 Node 上一些低優(yōu)先級的任務 Pod 造成反復的搶占遷移。這些大規(guī)模的 Pod 重建,本身會對 apiserver、scheduler、網絡/磁盤分配等中心組件造成較大的壓力,而這些組件的延遲也會給 Pod 重建帶來惡性循環(huán)。而采用原地升級后,整個升級過程只會涉及到 controller 對 Pod 對象的更新操作和 kubelet 重建對應的容器。

技術背景

在阿里巴巴內部,絕大部分電商應用在云原生環(huán)境都統(tǒng)一用原地升級的方式做發(fā)布,而這套支持原地升級的控制器就位于 OpenKruise 開源項目中。

也就是說,阿里內部的云原生應用都是統(tǒng)一使用 OpenKruise 中的擴展 workload 做部署管理的,而并沒有采用原生 Deployment/StatefulSet 等。


那么 OpenKruise 是如何實現(xiàn)原地升級能力的呢?在介紹原地升級實現(xiàn)原理之前,我們先來看一些原地升級功能所依賴的原生 Kubernetes 功能:

背景 1:Kubelet 針對 Pod 容器的版本管理

每個 Node 上的 Kubelet,會針對本機上所有 Pod.spec.containers 中的每個 container 計算一個 hash 值,并記錄到實際創(chuàng)建的容器中。

如果我們修改了 Pod 中某個 container 的 image 字段,kubelet 會發(fā)現(xiàn) container 的 hash 發(fā)生了變化、與機器上過去創(chuàng)建的容器 hash 不一致,而后 kubelet 就會把舊容器停掉,然后根據(jù)最新 Pod spec 中的 container 來創(chuàng)建新的容器。

這個功能,其實就是針對單個 Pod 的原地升級的核心原理。

背景 2:Pod 更新限制

在原生 kube-apiserver 中,對 Pod 對象的更新請求有嚴格的 validation 校驗邏輯:

// validate updateable fields:
// 1.  spec.containers[*].image
// 2.  spec.initContainers[*].image
// 3.  spec.activeDeadlineSeconds

簡單來說,對于一個已經創(chuàng)建出來的 Pod,在 Pod Spec 中只允許修改 containers/initContainers 中的 image 字段,以及 activeDeadlineSeconds 字段。對 Pod Spec 中所有其他字段的更新,都會被 kube-apiserver 拒絕。

背景 3:containerStatuses 上報

kubelet 會在 pod.status 中上報 containerStatuses,對應 Pod 中所有容器的實際運行狀態(tài):

apiVersion: v1
kind: Pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
status:
  containerStatuses:
  - name: nginx
    image: nginx:mainline
    imageID: docker-pullable://nginx@sha256:2f68b99bc0d6d25d0c56876b924ec20418544ff28e1fb89a4c27679a40da811b

絕大多數(shù)情況下,spec.containers[x].image 與 status.containerStatuses[x].image 兩個鏡像是一致的。

但是也有上述這種情況,kubelet 上報的與 spec 中的 image 不一致(spec 中是 nginx:latest,但 status 中上報的是 nginx:mainline)。

這是因為,kubelet 所上報的 image 其實是從 CRI 接口中拿到的容器對應的鏡像名。而如果 Node 機器上存在多個鏡像對應了一個 imageID,那么上報的可能是其中任意一個:

$ docker images | grep nginx
nginx            latest              2622e6cca7eb        2 days ago          132MB
nginx            mainline            2622e6cca7eb        2 days ago

因此,一個 Pod 中 spec 和 status 的 image 字段不一致,并不意味著宿主機上這個容器運行的鏡像版本和期望的不一致。

背景 4:ReadinessGate 控制 Pod 是否 Ready

在 Kubernetes 1.12 版本之前,一個 Pod 是否處于 Ready 狀態(tài)只是由 kubelet 根據(jù)容器狀態(tài)來判定:如果 Pod 中容器全部 ready,那么 Pod 就處于 Ready 狀態(tài)。

但事實上,很多時候上層 operator 或用戶都需要能控制 Pod 是否 Ready 的能力。因此,Kubernetes 1.12 版本之后提供了一個 readinessGates 功能來滿足這個場景。如下:

apiVersion: v1
kind: Pod
spec:
  readinessGates:
  - conditionType: MyDemo
status:
  conditions:
  - type: MyDemo
    status: "True"
  - type: ContainersReady
    status: "True"
  - type: Ready
    status: "True"

目前 kubelet 判定一個 Pod 是否 Ready 的兩個前提條件:

  1. Pod 中容器全部 Ready(其實對應了 ContainersReady condition 為 True);
  2. 如果 pod.spec.readinessGates 中定義了一個或多個 conditionType,那么需要這些 conditionType 在 pod.status.conditions 中都有對應的 status: “true” 的狀態(tài)。

只有滿足上述兩個前提,kubelet 才會上報 Ready condition 為 True。

實現(xiàn)原理

了解了上面的四個背景之后,接下來分析一下 OpenKruise 是如何在 Kubernetes 中實現(xiàn)原地升級的原理。

1. 單個 Pod 如何原地升級?

由“背景 1”可知,其實我們對一個存量 Pod 的 spec.containers[x] 中字段做修改,kubelet 會感知到這個 container 的 hash 發(fā)生了變化,隨即就會停掉對應的舊容器,并用新的 container 來拉鏡像、創(chuàng)建和啟動新容器。

由“背景 2”可知,當前我們對一個存量 Pod 的 spec.containers[x] 中的修改,僅限于 image 字段。

因此,得出第一個實現(xiàn)原理:**對于一個現(xiàn)有的 Pod 對象,我們能且只能修改其中的 spec.containers[x].image 字段,來觸發(fā) Pod 中對應容器升級到一個新的 image。

2. 如何判斷 Pod 原地升級成功?

接下來的問題是,當我們修改了 Pod 中的 spec.containers[x].image 字段后,如何判斷 kubelet 已經將容器重建成功了呢?

由“背景 3”可知,比較 spec 和 status 中的 image 字段是不靠譜的,因為很有可能 status 中上報的是 Node 上存在的另一個鏡像名(相同 imageID)。

因此,得出第二個實現(xiàn)原理: 判斷 Pod 原地升級是否成功,相對來說比較靠譜的辦法,是在原地升級前先將 status.containerStatuses[x].imageID 記錄下來。在更新了 spec 鏡像之后,如果觀察到 Pod 的 status.containerStatuses[x].imageID 變化了,我們就認為原地升級已經重建了容器。

但這樣一來,我們對原地升級的 image 也有了一個要求: 不能用 image 名字(tag)不同、但實際對應同一個 imageID 的鏡像來做原地升級,否則可能一直都被判斷為沒有升級成功(因為 status 中 imageID 不會變化)。

當然,后續(xù)我們還可以繼續(xù)優(yōu)化。OpenKruise 即將開源鏡像預熱的能力,會通過 DaemonSet 在每個 Node 上部署一個 NodeImage Pod。通過 NodeImage 上報我們可以得知 pod spec 中的 image 所對應的 imageID,然后和 pod status 中的 imageID 比較即可準確判斷原地升級是否成功。

3. 如何確保原地升級過程中流量無損?

在 Kubernetes 中,一個 Pod 是否 Ready 就代表了它是否可以提供服務。因此,像 Service 這類的流量入口都會通過判斷 Pod Ready 來選擇是否能將這個 Pod 加入 endpoints 端點中。

由“背景 4”可知,從 Kubernetes 1.12+ 之后,operator/controller 這些組件也可以通過設置 readinessGates 和更新 pod.status.conditions 中的自定義 type 狀態(tài),來控制 Pod 是否可用。

因此,得出第三個實現(xiàn)原理: 可以在 pod.spec.readinessGates 中定義一個叫 InPlaceUpdateReady 的 conditionType。

在原地升級時:

  1. 先將 pod.status.conditions 中的 InPlaceUpdateReady condition 設為 “False”,這樣就會觸發(fā) kubelet 將 Pod 上報為 NotReady,從而使流量組件(如 endpoint controller)將這個 Pod 從服務端點摘除;
  2. 再更新 pod spec 中的 image 觸發(fā)原地升級。

原地升級結束后,再將 InPlaceUpdateReady condition 設為 “True”,使 Pod 重新回到 Ready 狀態(tài)。

另外在原地升級的兩個步驟中,第一步將 Pod 改為 NotReady 后,流量組件異步 watch 到變化并摘除端點可能是需要一定時間的。因此我們也提供優(yōu)雅原地升級的能力,即通過 gracePeriodSeconds 配置在修改 NotReady 狀態(tài)和真正更新 image 觸發(fā)原地升級兩個步驟之間的靜默期時間。

4. 組合發(fā)布策略

原地升級和 Pod 重建升級一樣,可以配合各種發(fā)布策略來執(zhí)行:

  • partition:如果配置 partition 做灰度,那么只會將 replicas-partition 數(shù)量的 Pod 做原地升級;
  • maxUnavailable:如果配置 maxUnavailable,那么只會將滿足 unavailable 數(shù)量的 Pod 做原地升級;
  • maxSurge:如果配置 maxSurge 做彈性,那么當先擴出來 maxSurge 數(shù)量的 Pod 之后,存量的 Pod 仍然使用原地升級;
  • priority/scatter:如果配置了發(fā)布優(yōu)先級/打散策略,會按照策略順序對 Pod 做原地升級。

總結

如上文所述, OpenKruise 結合 Kubernetes 原生提供的 kubelet 容器版本管理、readinessGates 等功能,實現(xiàn)了針對 Pod 的原地升級能力。

而原地升級也為應用發(fā)布帶來大幅的效率、穩(wěn)定性提升。值得關注的是,隨著集群、應用規(guī)模的增大,這種提升的收益越加明顯。正是這種原地升級能力,在近兩年幫助了阿里巴巴超大規(guī)模的應用容器平穩(wěn)遷移到了基于 Kubernetes 的云原生環(huán)境,而原生 Deployment/StatefulSet 是完全無法在這種體量的環(huán)境下鋪開使用的。(歡迎加入釘釘交流群:23330762)

- 贈書福利 -

揭秘:如何為 Kubernetes 實現(xiàn)原地升級

6 月 19 日 12:00 前在【阿里巴巴云原生公眾號】留言區(qū) 提出你的疑問,精選留言點贊第 1 名將免費獲得此書,屆時我們還會請本文作者針對留言點贊前 5 名的問題進行答疑!

課程推薦

為了更多開發(fā)者能夠享受到 Serverless 帶來的紅利,這一次,我們集結了 10+ 位阿里巴巴 Serverless 領域技術專家,打造出最適合開發(fā)者入門的 Serverless 公開課,讓你即學即用,輕松擁抱云計算的新范式——Serverless。

點擊即可免費觀看課程: https://developer.aliyun.com/learning/roadmap/serverless

“ 阿里巴巴云原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦云原生流行技術趨勢、云原生大規(guī)模的落地實踐,做最懂云原生開發(fā)者的公眾號?!?/p>

文章名稱:揭秘:如何為Kubernetes實現(xiàn)原地升級
分享路徑:http://aaarwkj.com/article6/psodig.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供網站設計公司、網站收錄網站改版、網頁設計公司Google、域名注冊

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

手機網站建設
99久久中文字幕伊人| 蜜臀一二区免费在线视频| 欧美日韩亚洲精品综合网| 国产一区二区精品不卡| 91精品中综合久久久久| 国产偷自一区二区三区| 中文字幕伦理一区二区| 久久精品国产亚洲七七| 久草视频免费福利资源站| 亚洲淫婷婷久久一区二区| 未满18十八禁止观看| 久久久精品免费中文视频| 高清不卡一区二区在线观看| 91欧美日韩在线观看视频| 精品福利视频蜜臀91| 亚洲国产高清第一第二区| 日本人妻中文字幕在线一区| 国产中文字幕精品在线观看| 日韩av高清在线播放| 久久精品国产一区二区三区不卡 | 国语对白视频在线观看| 婷婷av一区二区三区| 人妻少妇精品视频二区| 91久久精品人妻一区二区| 日本福利一区二区三区| 视频一区中文字幕在线| 久久免费欧美日韩亚洲| 亚洲中文波霸中文字幕| 成人欧美一区二区三区av| 激情男女一区二区三区| 日本中文字幕一区二区视频| 亚洲欧美激情国产综合久久| 日韩精品视频一区二区在线观看| 国产产品在线免费看91| 欧美一级特黄大片做受农村 | 91精品国产综合久久麻豆| 国产麻豆剧传媒精品av| 久青青国产综合自拍视频在线观看| 一区二区三区人妻系列| 观看女性真实高潮的合集| 观看亚洲一区二区三区大片|