# Partition and Queue 配置 queue 基礎配置在[其他官方文檔](https://yunikorn.apache.org/docs/design/scheduler_configuration/)講到 在此部分將提及一些通用的 queue 的配置,這會需要[Access Control Lists](https://yunikorn.apache.org/docs/user_guide/acls/) 與 [Placement rules](https://yunikorn.apache.org/docs/user_guide/placement_rules/) 的知識 除此之外,這裡解釋了如何創建 partition 及 queue 配置該怎麼修改,以符合 schedler 有關 scheduler 是如何取得 user 或 group 的資訊的,請參考[其他文檔筆記](/@ntcu-k8s/Hki5A6lMR) ## 配置 在這邊提及的 scheduler 配置文件只著重描述 partition 及 queue 的配置 預設值為 `queue.yaml` ,此部分可以在 ConfigMap 的 `service.policyGroup` 中更改 `queue.yaml` 預設值可參考[github 原始碼](https://github.com/apache/yunikorn-core/blob/master/config/queues.yaml) ## Partitions Partitions 是 scheduler 配置裡最高層級的屬性,可同時存在多個 partition 的配置 配置的基本架構如下: ```yaml partitions: - name: <name of the 1st partition> - name: <name of the 2nd partition> ``` 預設的 partition 名稱為 `default`, partition 內的定義包含了「每一部份 shim 的 scheduler」所需的所有配置 partition 至少需要以下兩個屬性: - name - queue queue 的配置將在之後提及 對於以下的屬性則非必須: - placementrules - limits - nodesortpolicy - preemption 上兩個屬性在之後會提及 對於 `nodesortpolicy` 則可參考 [官方文檔](https://yunikorn.apache.org/docs/user_guide/sorting_policies/#node-sorting) 而 `preemption` 是在設定「在此 partition 上,是否允許 preemption 的動作」,此預設值為 `true` 以下為一個 `nodesortpolicy` 為 *fair* 且不允許 preemption 的 partition 配置範例 ```yaml partitions: - name: <name of the partition> nodesortpolicy: fair preemption: enabled: false ``` :::danger 注意: 目前 k8s 唯一的 shim 不支援 `default` 以外的任何其他 partition [參考](https://issues.apache.org/jira/browse/YUNIKORN-22) ::: ## Queue Yunikorn 以 resource queue 來管理資源, resource queue 有以下的特性: - queue 有階層式的架構 - queue 可預設**最小**需要的資源及**最大**會使用資源上限 - task 只能在 leaf queue 上執行 - queue 有**靜態**(配置文件)及**動態**(Yunikorn 內部管理)兩種狀態 - queue 層級的資源公平性由 scheduler 強制執行(is enforced by the scheduler) - job 只能在特定 queue 下執行 > INFO: > Yunikorn queue 與 k8s namespace 的差別: > - k8s NS 的資源被其以下的 object 使用 > - queue 的資源基於內部 jobs 的資源使用 > > 這使得 Yunikron queue 擁有更細顆粒的資源管理 ### 配置架構 queues 是主要的配置屬性,它可以定義一個階層式的架構給 queues 對於 `root` 的 queue 配置是選擇性的,但為了確保一致性, Yunikorn 會在以下情況插入 `root` 的 queue: - 在最高層級有多於一個的 queue 定義 - 最高層級的那個 queue name 不是 `root` 在插入 `root` queue 後,文件定義的 queue 會變為 `root` 的 child queue 基本的架構式 `queues` 範例為: ```yaml queues: - name: <name of the queue> queues: - name: <name of the queue> ``` ### queue 概念 對於 `queues` 屬性,有以下子屬性: - name - parent - queues - maxapplications - properties - adminacl - submitacl - resources - limits 每個 queue 的 name 在其階層應為單一的,因為在解析時, Yunikorn 將會把 queue 的關係以 "." 相連,如 ```yaml queues: - name: root queues: - name: testqueue queues: - name: parent queues: - name: testqueue ``` 會有 `root.testqueue` 及 `root.parent.testqueue` 這兩種解析,因此如果定義在同一階層不是獨特的, Yunikorn 將會駁回定義 而也因為是以 "." 分割,所以 queue 的 name 不能有 "." queue 有兩種 type: - parent (有其他 sub-queue) - leaf (沒有其他 sub-queue,且 `parent` 屬性不為 `true`) 而 application 只能被分配給 *leaf queue*,Trying to override a *parent queue* type in the configuration will cause a parsing error of the configuration. `maxapplications` 屬性是一個大於等於 1 的整數值,設為 0 則不允許任何 application 的 allocation child queue 的 `maxapplication` 小於等於 parent queue 的 `maxapplication` `properties` 包含簡單的 key/value,這用於進一步隊列自訂功能,例如[應用程式排序](https://yunikorn.apache.org/docs/user_guide/sorting_policies/#application-sorting)和優先調度,在[之後](#Properties)會再提及 對於管理動作的存取權為 `adminacl` ,而提交 application 則為 `submitacl`,ACLs 的概念請參考[官方文檔](https://yunikorn.apache.org/docs/user_guide/acls/) queue 的資源限制為 `resources` 屬性管理, user/group limits 則是 `limits`,這兩個會在之後提及 以下是 `root.namespaces` 作為 *parent queue* 且擁有 `limits` 的範例: ```yaml partitions: - name: default queues: - name: namespaces parent: true maxapplications: 12 resources: guaranteed: {memory: 1G, vcore: 10} max: {memory: 10G, vcore: 100} queues: - name: level1 maxapplications: 8 resources: guaranteed: {memory: 500M, vcore: 5} max: {memory: 5G, vcore: 50} ``` ## Placement rules 對於 placement rules 的配置文件請參考[官方文檔](https://yunikorn.apache.org/docs/user_guide/placement_rules/) 每個 partition 只會定義一組 placement rule,如果沒有 placement rule 被定義,那所有 application 都應該被設定一個 queue 來提交 ## Limits ### 配置架構 定義了一組 `limit` 給單一一個 queue ,架構如下: ```yaml limits: - limit: <description> - limit: <description> ``` `limit` 是一個複雜的配置屬性,它定義了一個 user 或一組 group 的 limit 不在定義範圍內的 user / group 不會被 limit 的定義限制,詳細架構如下: ```yaml limits: - limit: <description> users: - <user name or "*"> - <user name> groups: - <group name or "*"> - <group name> maxapplications: <1..maxint> maxresources: <resource name 1>: <0..maxint>[suffix] <resource name 2>: <0..maxint>[suffix] ``` ### limits 概念 定義的 limit 會遞迴地應用在每個 child queue,也就是說 `root` 的 `limits` 會被用於所有 queue,同時,`root` 的 `limits` 等同於 `partition` 的 `limits` `limits` 有以下子屬性: - limit - users - groups - maxapplications - maxresources `limit` 是個可選的敘述,單純用於理解及可讀性 `user` / `group` 有以下兩種情況: - 萬用字元 "\*" - users / groups 的 list 多於 1 個 user / group 的配置將被視為第二種情況,且重複的 user / group 將會被忽略 不允許在其他 list 旁使用 "\*" ,使用 "\*" 給 group 時,[必須配置至少一個命名組的 limit](https://yunikorn.apache.org/docs/design/user_group_resource_usage_enforcement/#group) `maxapplications` 是一個無號整數,**不可**被設為 0,其定義了對於 user / group 的可執行 applications 的數量 `maxresources` 定義了一個或多個資源的上限,不在 list 內的資源用量則不受限定,其語法在[之後](#Resources)提及 上限可被設定為 0 ,用於禁止 user / group 使用特定資源,但整體資源量不可為 0 如果 queue 上的資源不可用,則應使用 queue 定義上的最大資源。 不允許資源為 0 、`maxresources` 也為 0 的配置文件 `limit` 是針對每個 user / group 的,而不是他們的組合限制,也就是說: ```yaml limit: "example entry" maxapplications: 10 users: - sue - bob ``` 在這個範例中, user `sue` 與 user `bob` 都可以執行 10 個 applications ## Properties 用於表明 queue 額外的屬性,有下面幾種: | 名稱 | 描述 | |-----|------| | `application.sort.policy` | queue 裡排序 application 的方法 | | `application.sort.priority` | 在 queue 裡排序時,是否參考 priority | | `priority.policy` | 設定 queue 間的排序 priority | | `priority.offset` | 設定 queue 在同層級的 priority | | `preemption.policy` | 是否允許 preemption | | `preemption.delay` | preemption 的延遲時間 | ### application.sort.policy 此設定對 *parent queue* 沒有效用 可修改值:`fifo` 、 `fair` 、 `stateware` 預設值:`fifo` > `stateware` 已在 1.5 被棄用了,其將在 1.6 版本移除,在之後 `stateware` 將被視為 `fifo` 可參考[官方文檔](https://yunikorn.apache.org/docs/user_guide/sorting_policies/#application-sorting)以獲得更多資訊 ### application.sort.priority 此設定可被 *child queue* 繼承 可修改值:`enabled` 、 `disabled` 預設值:`enabled` > 1.2 以前的 Yunikorn 是沒有這一屬性的 ### priority.policy 此設定不會被 *child queue* 繼承 可修改值:`default` 、 `fence` 預設值: `default` 使用 `default` 的話,priority 則會應用於每個 queue 使用 `fence` 的話,priority 則對於每個 queue 都不同 參考[官方文檔](https://yunikorn.apache.org/docs/user_guide/priorities/)以獲得更多資訊 ### priority.offset 此設定不會被 *child queue* 繼承 可修改值:32位元的有號數字 預設值: 0 使用 `default` 的話,priority 會對於此值調整 使用 `fence` 的話,priority 則是被設定為此值,也就是說,在 queue 裡的 tasks 的 priority 將被忽略 參考[官方文檔](https://yunikorn.apache.org/docs/user_guide/priorities/)以獲得更多資訊 ### preemption.policy 可修改值:`default` 、 `fence` 、 `disabled` 預設值:`default` 使用 `fence` 時,此 queue 及其以下的 queue 內的 tasks 不能 preemption 其他 queue 的 tasks,也就是說,preemption 只會發生在當前 queue 及以下 參考[官方文檔](https://yunikorn.apache.org/docs/design/preemption/#preemption-fence)以獲得更多資訊 ### preemption.delay 此設定只能在 *leaf queue* 上使用 可修改值:參考[Golang 文檔](https://pkg.go.dev/time#ParseDuration) 預設值:`30s` ## Resources `resources` 有 `guaranteed` 跟 `max` 兩種子屬性 資源限制是遞迴式地往下檢查 資源用量分為兩種情況: - leaf queue: 被指定的資源量總和 - parent queue: 其下所有 queue 的資源量總和 基本上來說 *root queue* 的資源上限就是整個 cluster 的資源上限,若指定 root 的資源上限可能會出錯,它也沒有 `guaranteed` 的子屬性 `max` 的值會在 allocation 時給出硬性限制,其值可被設定為 `0`,這在[上面](#limits-概念)有提及過 `guaranteed` 會被用於計算其在 queue 裡的份額,因此它也被作為 allocation 的輸入, preemption 也會參考這個數值 基本架構如下: ```yaml resources: guaranteed: <resource name 1>: <0..maxint>[suffix] <resource name 2>: <0..maxint>[suffix] max: <resource name 1>: <0..maxint>[suffix] <resource name 2>: <0..maxint>[suffix] ``` 上面提到的 suffix 有以下情況: - 記憶體 - 可以是 `k` 、 `M` 、 `G` 、 `T` 、 `P` 跟 `E` - 也可以是 `ki` 、 `Mi` 、 `Gi` 、 `Ti` 、 `Pi` 跟 `Ei` - 或者 bytes - vcore - `m` 對於 millicores ## *child queue* 模板 *parent queue* 可以定義模板給**動態**的 *leaf queue*,可在任一階層定義給 *parent queue* 當一個 *parent queue* 沒有模板時,它會往上找到一個模板來使用(如果有的話) 可給定的屬性有以下幾種: - application sort policy - max resources - guaranteed resources - max applications 以下是範例: ```yaml partitions: - name: default placementrules: - name: provided create: true queues: - name: root submitacl: '*' childtemplate: maxapplications: 10 properties: application.sort.policy: fifo resources: guaranteed: vcore: 1 memory: 1G max: vcore: 20 memory: 600G queues: - name: parent parent: true childtemplate: resources: max: vcore: 21 memory: 610G - name: notemplate parent: true ``` 在這裡,`root.parent.sales` 會直接使用 `root.parent` 定義的 child template 作為對比,`root.noteplate.sales` 會使用 `root` 的 child template,因為它的 *parent queue* 沒有 child template ,而從 `root` 那邊繼承而來 --- [官方文檔連結](https://yunikorn.apache.org/docs/user_guide/queue_config)