91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

K8s中如何進行優雅停機和零宕機部署

發布時間:2021-12-15 19:08:34 來源:億速云 閱讀:210 作者:柒染 欄目:云計算

這期內容當中小編將會給大家帶來有關K8s中如何進行優雅停機和零宕機部署,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

創建、刪除 Pod 是 K8s 中最常見的任務之一。下面介紹了 Pod 在響應創建、刪除請求時發生的內部流程,還討論了如何在 Pod 啟動或關閉時防止斷開連接,以及如何正常關閉長時間運行的任務。

在 Kubernetes 中,創建、刪除 Pod 可以說是最常見的任務之一。當我們進行滾動更新、擴展部署等等,都會創建 Pod。另外,在我們將節點標記為不可調度時,Pod 被驅逐后也會被刪除并重新創建。          
這些 Pod 的生命周期非常短暫,如果 Pod 還在響應請求的過程中,就被關閉了會怎么樣?          
  • 關閉前的請求是否已完成?
  • 接下來的請求又如何呢?
在討論刪除 Pod 時會發生什么之前,我們需要知道在創建 Pod 時會發生什么。假設我們在集群中創建了以下 Pod:          

K8s中如何進行優雅停機和零宕機部署

我們將Pod YAML 定義提交給集群:          

K8s中如何進行優雅停機和零宕機部署

在輸入命令后,kubectl 就會將 Pod 定義提交給 Kubernetes API。

K8sMeetup          

在數據庫中保存集群狀態

API 接收并檢查 Pod 定義,然后將其存儲在 etcd 數據庫中。另外,Pod 將被添加到調度程序的隊列中。

調度程序會檢查 Pod 定義,再收集有關工作負載的詳細信息,例如 CPU 和內存請求,然后確定哪個節點最適合運行它。在調度程序結束后:          
  • 在 etcd 中的 Pod 會被標記為 Scheduled。
  • Pod 被分配到一個節點。
  • Pod 的狀態會存儲在 etcd 中。
但是 Pod 此時仍然是不存在的,因為之前的任務都發生在控制平面中,Pod 狀態僅存儲在數據庫中。那么我們要如何在節點中創建 Pod?          
K8sMeetup          

Kubelet

kubelet 的工作是輪詢控制平面以獲取更新。kubelet 不會自行創建 Pod,而是將工作交給其他三個組件:

  • 容器運行時接口(CRI)             :為 Pod 創建容器的組件。
  • 容器網絡接口(CNI)             :將容器連接到集群網絡并分配 IP 地址的組件。
  • 容器存儲接口(CSI)             :在容器中裝載卷的組件。
在大多數情況下,容器運行時接口(CRI)的工作類似于:          

K8s中如何進行優雅停機和零宕機部署

容器網絡接口(CNI)負責:          
  • 為 Pod 生成有效的 IP 地址。
  • 將容器連接到網絡。
我們有多種方法可以將容器連接到網絡并分配有效的 IP 地址,我們可以在 IPv4 或 IPv6 之間進行選擇,也可以分配多個 IP 地址。當容器網絡接口完成其工作時,Pod 也連接到網絡,并分配了有效的IP地址。          
這里會出現一個問題,Kubelet 知道 IP 地址,因為它調用了容器網絡接口,但是控制平面不知道。主節點也不知道該 Pod 已經被分配了 IP 地址,并準備接收流量。單純從控制平面的角度來看,現在仍在創建 Pod 階段 。          
kubelet 的工作是收集 Pod 的所有詳細信息,例如 IP 地址,并將其報告回控制平面。我們檢查 etcd 不僅可以顯示 Pod 的運行位置,還可以顯示其 IP 地址。          

如果 Pod 不是任何 Service 的一部分,那到這里就結束了,因為 Pod 已經創建完畢并可以使用,但如果 Pod 是 Service 的一部分,那還有幾個步驟需要執行。

K8sMeetup          

Pod 和 Service

在創建 Service 時,我們需要注意兩點信息:

  • selector             :指定接收流量的 Pod。
  • targetPort             :通過 Pod 端口接收流量。
Service 的 YAML 定義如下:          

K8s中如何進行優雅停機和零宕機部署

我們使用            kubectl apply            將 Service 提交給集群時,Kubernetes 會找到所有和選擇器(name: app)有著相同標簽的 Pod,并收集其 IP 地址,當然它們需要先通過 Readiness 探針,然后再將每個 IP 地址都和端口連接在一起。          
如果 IP 地址是            10.0.0.3           ,           targetPort            是 3000,Kubernetes 會將這兩個值連接起來稱為 endpoint。          

K8s中如何進行優雅停機和零宕機部署

endpoint 會存儲在 etcd 的一個名為 Endpoint 的對象中。這里有點要注意:          
  • endpoint(e 小寫)=IP 地址 + 端口(10.0.0.3:3000)。
  • Endpoint(E 大寫)是 endpiont 的集合。
Endpoint 對象是 Kubernetes 中的真實對象,對于每個 Service,Kubernetes 都會自動創建一個 Endpoint 對象。我們可以使用以下方法進行驗證:          

K8s中如何進行優雅停機和零宕機部署

Endpoint 對象會從 Pod 中收集所有的 IP 地址和端口,而且不僅一次。在以下情況中,Endpoint 對象將更新一個 endpiont 新列表:          
  • Pod 創建時。
  • Pod 刪除時。
  • 在 Pod 上修改標簽時。
因此,每次在創建 Pod 并在 kubelet 將其 IP 地址發送到主節點后,Kubernetes 都會更新所有 endpoint:          

K8s中如何進行優雅停機和零宕機部署

endpoint 存儲在控制平面中,Endpoint 對象也會更新。

K8sMeetup          

在 Kubernetes 中使用 endpoint

endpoint 被 Kubernetes 中的多個組件所使用。Kube-proxy 使用 endpoint 在節點上設置 iptables 規則。因此,每次對 Endpoint 對象進行更改時,kube-proxy 都會檢索 IP 地址和 endpiont 新列表,以編寫新的 iptables 規則。

Ingress 控制器           也使用相同的 endpiont 列表。Ingress 控制器是集群中將外部流量路由到集群中的組件。在設置 Ingress 列表時,我們通常將 Service 指定為目標:          

K8s中如何進行優雅停機和零宕機部署

實際上,流量不會路由到 Service,Ingress 控制器設置了 subscription,每次該 Service 的 endpoint 更改時都將收到通知,所以,Ingress 會將流量直接路由到 Pod,從而跳過 Service。          
可以想象,每次更改 Endpoint 對象時,Ingress 都會檢索 IP 地址和 endpoint 新列表,并將控制器重新配置。現在我們快速回顧一下創建 Pod 時發生的過程:          
1.Pod 先存儲在 etcd 中。          
2.調度程序會分配一個節點,再將節點寫入 etcd。          
3.向 kubelet 通知有個新 Pod。          
4.kubelet 將創建容器的任務給CRI。          
5.kubelet 將容器附加到 CNI。          
6.kubelet 將容器中的卷委派給 CSI。          
7.CNI 分配 IP 地址。          
8.Kubelet 將 IP 地址通知給控制平面。          
9.IP 地址存儲在 etcd 中。          
如果我們的 Pod 屬于 Service:          
1.Kubelet 等待 Readiness 探針成功。          
2.對所有相關的 Endpoint 對象更改進行通知。          
3.Endpoint 將新 endpoint(IP 地址 + 端口)添加到列表中。          
4.Kube-proxy 被通知 Endpoint 更改,然后 Kube-proxy 會更新每個節點上的 iptables 規則。          
5.Ingress 控制器被通知 Endpoint 變化,然后控制器會將流量路由到新的 IP 地址。          
6.CoreDNS 被通知 Endpoint 更改。如果服務的類型為 Headless,DNS 會進行更新。          
7.云提供商被通知 Endpoint 更改。如果 Service 是 type: LoadBalancer,新的 endpoint 配置會是負載均衡池的一部分。          
8.集群中安裝的所有服務網格也會被通知 Endpoint 更改。          
9.訂閱 Endpoint 更改的其他運營商也會收到通知。          
雖然列表很長,實際上這就是一項常見任務:創建一個 Pod。Pod 已經成功運行了,下面我們討論刪除時會發生什么。          
K8sMeetup          

刪除 Pod

刪除 Pod 時,我們要遵循上文相同的步驟,不過是相反的。首先,我們從 Endpoint 對象中刪除 endpiont,但這次“readiness”探針會被忽略,endpiont 會立即從控制平面中移除,然后再依次觸發所有事件到 kube-proxy,Ingress 控制器、DNS、服務網格等。這些組件將更新其內部狀態,并停止將流量路由到 IP 地址。

由于組件可能忙于執行其他操作,因此無法保證從其內部狀態中刪除 IP 地址將花費多長時間。有時候這可能不到一秒鐘,但有時候可能需要更多時間。同時,etcd 中 Pod 的狀態會更改為 Termination。kubelet 會被通知此次更改:          
1.連接 CSI 的卷將從容器中卸載。          
2.從網絡上分離容器并將 IP 地址釋放到 CNI。          
3.將容器銷毀到 CRI。          
換句話說,此時 Kubernetes 會遵循與創建 Pod 完全相同但反向的步驟。實際上,這存在著細微的差異。當我們終止 Pod 時,將同時刪除 endpoint 和發送到 kubelet 的信號。          

創建 Pod 時,Kubernetes 會等待 kubelet 報告 IP 地址,然后進行 endpoint 廣播,但刪除 Pod 時,這些事件是并行開始的。這可能會導致一些條件競爭。如果在 endpoint 廣播之前刪除Pod怎么辦?

K8sMeetup          

優雅停機

當 Pod 在 kube-proxy 或 Ingress 控制器刪除之前終止,我們可能會遇到停機時間。此時,Kubernetes 仍將流量路由到 IP 地址,但 Pod 已經不存在了。Ingress 控制器、kube-proxy、CoreDNS 等也沒有足夠的時間從其內部狀態中刪除 IP地址。

理想情況下,在刪除 Pod 之前,Kubernetes 應該等待集群中的所有組件更新了 endpoint 列表,但是 Kubernetes 不是那樣工作的。          
Kubernetes 提供了原語來分發 endpoint           (即 Endpoint 對象和更高級的抽象,例如 Endpoint Slices),所以 Kubernetes 不會驗證訂閱 endpoint 更改的組件是否是最新的集群狀態信息。          
那么,如何避免這種競爭情況并確保在 endpoint 廣播之后刪除 Pod?我們需要等待,當 Pod 即將被刪除時,它會收到 SIGTERM 信號。我們的應用程序可以捕獲該信號并開始關閉。由于 endpoint 不會立即從 Kubernetes 的所有組件中刪除,所以我們可以:          
1.請稍等片刻,然后退出。          
2.即便有 SIGTERM 信號,但仍然可以處理傳入流量。          
3.最后,關閉現有的長期連接。          
4.關閉該進程。          
那么我們應該等多久?           默認情況下,Kubernetes 將發送 SIGTERM 信號并等待 30 秒,然后強制終止該進程。因此,我們可以使用前 15 秒繼續操作。該間隔應足以將 endpoint 刪除信息傳播到 kube-proxy、Ingress 控制器、CoreDNS 等,然后,到達 Pod 的流量會越來越少,直到停止。15 秒后,我們就可以安全地關閉與數據庫的連接并終止該過程。          
如果我們認為需要更多時間,那么可以在 20 或 25 秒時停止該過程。這里有一點要注意,Kubernetes 將在 30 秒后強行終止該進程(除非我們更改 Pod 定義中的            terminationGracePeriodSeconds           )。如果我們無法更改代碼以獲得更長的等待時間要怎么辦?我們可以調用腳本以獲得固定的等待時間,然后退出應用程序。          
在調用 SIGTERM 之前,Kubernetes 會在 Pod 中公開一個            preStop            hook。我們可以將            preStop            hook 設置為等待 15 秒。下面是一個例子:          

K8s中如何進行優雅停機和零宕機部署

preStop hook 是 Pod LifeCycle hook 之一。

K8sMeetup          

寬限期和滾動更新

優雅停機適用于要刪除的 Pod,但如果我們不刪除 Pod,會怎么樣?其實即使我們不做,Kubernetes 也會刪除 Pod。在每次部署較新版本的應用程序時,Kubernetes 都會創建、刪除 Pod。

在 Deployment 中更改鏡像像時,Kubernetes 會逐步進行更改。          

K8s中如何進行優雅停機和零宕機部署

如果我們有三個副本,并提交新的 YAML 資源,Kubernetes 會:          
         

1.用新的容器鏡像創建一個 Pod。

2.銷毀現有的 Pod。

3.等待 Pod 準備就緒。

它會不斷重復上述步驟,直到將所有 Pod 遷移到較新的版本。Kubernetes 在新 Pod 準備接收流量之后會重復每個周期。另外,Kubernetes 不會在轉移 Pod 前等待 Pod 被刪除。如果我們有 10 個 Pod,并且 Pod 需要 2 秒鐘的準備時間和 20 秒的關閉時間,就會發生以下情況:

1.創建一個 Pod,終止前一個 Pod。

2.Kubernetes 創建一個新的 Pod 后,需要 2 秒鐘的準備時間。

3.同時,被終止的 Pod 會有 20 秒的停止時間。

20 秒后,所有新 Pod 均已啟用,之前的 10 個 Pod 都將終止。這樣,我們在短時間內將 Pod 的數量增加了一倍(運行 10 次,終止 10 次)。           寬限期越長,同時具有“運行”和“終止”的 Pod 也就越多。          
K8sMeetup          

終止長時間運行的任務

如果我們要對大型視頻進行轉碼,是否有任何方法可以延遲停止 Pod?

假設我們有一個包含三個副本的 Deployment。每個副本都分配了一個視頻轉碼任務,該任務可能需要幾個小時才能完成。當我們觸發滾動更新時,Pod 會在 30 秒內完成任務,然后將其殺死。          
如何避免延遲關閉 Pod?我們可以將其            terminationGracePeriodSeconds            增加到幾個小時,但這樣 Pod 的 endpoint 將 unreachable。如果我們公開指標以監控 Pod,instrumentation 將無法訪問 Pod。Prometheus 之類的工具依賴于 Endpoints 在集群中 scrape Pod。一旦刪除 Pod,endpoint 刪除信息就會在集群中傳播,甚至傳播到 Prometheus。          
我們應該為每個新版本創建一個新的 Deployment,而不是增加寬限期。當我們創建全新的 Deployment 時,現有的 Deployment 將保持不變。長時間運行的作業可以照常繼續處理視頻,在完成后,我們可以手動刪除。          

如果想自動刪除,那我們可以需要設置一個自動伸縮器,當它們完成任務時,可以將 Deployment 擴展到零個副本。

K8sMeetup            

我們應該注意 Pod 從集群中刪除后,它們的 IP 地址可能仍用于路由流量。相比立即關閉 Pod,我們不如在應用程序中等待一下或設置一個 preStop hook。在 endpoint 傳播到集群中,并且 Pod 從 kube-proxy、Ingress 控制器、CoreDNS 等中刪除后,Pod 才算被移除。

如果我們的 Pod 運行諸如視頻轉碼之類的長期任務,可以考慮使用 Rainbow 部署。在 Rainbow 部署中,我們會為每個發行版創建一個新的 Deployment,并在任務完成后刪除上一個發行版。

上述就是小編為大家分享的K8s中如何進行優雅停機和零宕機部署了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

金溪县| 巴塘县| 无棣县| 深圳市| 长武县| 鲁山县| 永和县| 眉山市| 永修县| 理塘县| 开化县| 河北省| 红河县| 正镶白旗| 宜州市| 新营市| 岫岩| 开化县| 哈密市| 高邮市| 布尔津县| 锡林郭勒盟| 龙州县| 淳化县| 天祝| 庆城县| 哈巴河县| 锡林郭勒盟| 那坡县| 大埔县| 易门县| 灵武市| 陆川县| 全椒县| 木兰县| 华亭县| 许昌市| 麦盖提县| 慈利县| 满城县| 富源县|