nginx request body讀取流程詳解

K8s中的批處理任務模塊主要是由Job控制器完成,今天我們就來關注下其底層的關鍵設計,包括完成狀態、並行模式、並行策略等關鍵機制

1. 基礎概念

在聊k8s的任務模塊的實現的時候,我們先看一下傳統的任務系統的設計與實現,然後聊下基於k8s的基礎的概念

1.1 傳統的任務系統設計

nginx request body讀取流程詳解

傳統的任務系統設計主要可以分為master(任務分配/故障感知/負載均衡)、Worker(任務執行/任務監控/任務管理)、分佈式協調(etcd等存儲元數據)、任務倉庫(存儲任務的實現比如類或者接口)等幾部分, 從大的部分又可以切分為兩個部分管控端(分佈式協調/master/倉庫)、執行端(Worker),傳統的任務系統大概就是這樣

通常複雜的就是如何在master如何做任務的負載均衡、任務的快速完成、依賴等管控功能,其次就是如何在worker端實現一個牛x的引擎,可以支持各種不同任務的執行環境和類型的執行

1.2 基於Pod的任務載體

nginx request body讀取流程詳解

k8s中的最小單元調度是Pod,同樣的job控制器調度的最小單元也是Pod, Pod裡面包含容器,以容器為載體k8s屏蔽了傳統worker模塊的任務執行環境與實現兩個部分,只需要添加一些配置數據,對應的Pod就可以完成對應的任務的執行

1.3 簡化的調度層

在k8s中Pod通常被定義為一個不穩定的單元,即k8s並不保證你的pod在被調度到某一臺機器後就會一直的穩定運行,直到這臺機器下線,這與傳統的系統都不太一樣,基於該特點,Job調度器的調度層其實也是一種面向於終態的設計。

大概就先介紹這些,接下來我們去分析k8s中job的核心實現機制

2. 核心實現

Job控制器的核心實現有幾個關鍵點:並行粒度、完成狀態、並行策略、並行模式、刪除策略,記住這些關鍵點,我們來一一剖析

2.1 並行粒度

並行的粒度是指的針對同一任務可以同時有多少個並行的Pod即同時運行的Pod,Job控制器會根據用戶設定的並行粒度確定需要同時運行的Pod

2.2 完成狀態

在一些批處理調度的系統裡面可能會通過數據分片後,等待所有分片的任務都完成後,來確定任務的完成狀態,但是在k8s中Job控制器是一個通用的實現, 而且調度層本身也並不關注調度任務的具體數據

nginx request body讀取流程詳解

所以在k8s中裡面其實是通過Completion的和backoffLimit來完成狀態轉移的,即通過Completion來確定需要等待的Pod的完成的數量,而通過backoffLimit確定到底可以允許失敗重試的次數,確定重試多少次就認為任務失敗了

2.3 並行模式

在k8s的job控制器模式介紹中提到四種併發模式, 那實現上是不是真的有四種模式呢,答案是否定的。可以說k8s的job控制器根本也就不關注是那種模式,模式是應用層自己的設計,而job控制器只負責並行粒度、當前狀態、完成狀態

這裡我們主要分析下Parallel JOb with a fix completion count和Parallel Job with a work queue的實現來聊聊Job控制器是如何實現的,兩者很大的一個區別就是後者不能設置Completions,即不需要設置需要等待多少個Pod完成,為什麼一個參數的設定就可以實現兩者模式呢?

nginx request body讀取流程詳解

答案就是期望的完成數量不同,如果Completions不設定,則實際上Job控制器發現有任一一個Pod成功並且當前活躍的Pod的數量為0,則表示當前任務完成, 該模式主要適用於單次的批任務,即本次批任務的所有Pod任務都完成,通常也意味著本次批任務是有限的集合

而Completions設定為數量則意味著只需要完成指定數量的批任務,即任務可能類似於流處理模式,本次只期望完成一部分即可,即Completions設定數量的任務

2.4 並行策略

並行策略主要是指的如果我們指定的Parallelism的數量過大,為了避免單個任務同時創建大量的Job任務對集群帶來的影響則採用分批逐次遞增的策略,逐步完成並行所需要的Pod的更新

2.5 期望計數

nginx request body讀取流程詳解

期望計數是k8s中控制器常見的機制,即當控制器進行Pod操作完成後,會設定當前期望的Pod的增加或者刪除的計數,通過期望計數的統計來確定當前是否需要繼續更新對應的pod, 期望的滿足主要來源於兩個地方:informer和當前控制流,informer通過監聽apiserver來感知事件,而當前控制流則主要是在操作Pod失敗的時候,直接更新期望,因為這些操作失敗的Pod並不會從後續的informer中感知到

2.6 刪除策略

我們提到過期望計數來決定是否更新狀態,但這個並不保證一致性,很有可能因為事件的延遲導致控制器創建了大量的Pod此時就需要基於終態的繼續調整,即需要根據當前的數量來刪除部分的Pod, 刪除策略主要是包含六點:1)未分配優先 2)未運行優先 3)未就緒優先 4)運行時間最短優先 5)重啟次數多優先 6)創建時間較短優先

3. 總結

nginx request body讀取流程詳解

Job控制器的實現設計上還是很好玩的,主要是是面向常見的批處理場景,但本身並沒有考慮優先級、關係、效率、分片等功能,只是一個通用的基礎的任務調度的實現, 當前k8s中還有很多針對不同場景的專用任務調度實現,但基於k8s的任務系統設計本身就給我們降低了很多的複雜度,這也就是雲原生帶來的好處,今天就到這裡,謝謝大家


分享到:


相關文章: