---
# System prepended metadata

title: Scheduler 配置
tags: [筆記, Yunikorn]

---

# Scheduler 配置

Yunikorn 的 scheduler 配置可以分為兩個部分，一個是它本身的 scheduler service 或像 web service 指定的 port 號等等，另一個則是 queue 的配置
為了區分這兩個部分，有以下兩點可以討論：
- 動態或靜態
- 責任的分配

對於第一點， scheduler 在執行過程中沒有需要去變更 web 的 port 號或者改變 sort policy，因此它被歸類在**靜態**
而 queue 的配置就可以在 scheduler 執行過程中變動，所以它是**動態**的

至於第二點，我們應該讓有管理權限的 user 可以更動 scheduler queues ，而不是修改 scheduler 的配置文件
而我們再在無法預測哪個或哪些 shim 會與哪個 scheduler core 做配對的情況下，我們應把 shim 的配置與 scheduler 的配置拆分開來

## scheduler 配置
scheduler 的配置包含了所有 scheduler 所需要及依賴的 services ，且其由鍵值對組成
開始 scheduler 所需要的配置一定要被包含在裡面，但 queue 的配置應被排除

目前確定的 scheduler 配置：
- Bind host
- Service port
- Web bind host
- Web service port 
- SSL config
- Shims Configured
- SchedulerACL

要考慮的配置：
- 一次指定多個 container ，以 bin packing 來說，別將 applications 分布在大量 node 上，其需要變成可配置的
- 與「預清空」(Pre-emption)有關的配置：
    - threshold: 如果 cluster 低於 threshold ，則不做 queue 的「預清空」(pre-empt)
    - Interval: 在「預清空」的檢查間暫停

## queue 配置
### queue 定義
在初始化 service 後， scheduler 將提供的配置文件內的 queue 配置載入進去，如果沒有提供配置文件，則會使用預設的配置文件

配置將以 configMap 定義，而不是 [CRD](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#should-i-use-a-configmap-or-a-custom-resource)

如同上面所說的， queue 的配置文件屬於**動態**，它可以被 GO based API 、 REST based API 或直接修改文件來更新配置內容，其中屬於 API 的更改方法會有延遲，但更新後會被保存下來

對於 queue 的階層、 `root` 的資源限制、 *leaf queue* 或 *parent queue* 等等的概念請參考[其他文檔筆記](/@ntcu-k8s/ryswDKzfC#queue-概念)，此外，對於配置內的名稱命名這裡額外提到了：在 `placement Rule` 中，我們允許 user / group 的名字包含 "."，它會被解析為 "`_dot_`" ，但對於 queue name 一樣不允許

在文件中定義的 queue (也就是 *manager queue*) 會被指名一個 `queue type` ，它可以是被用階層式表達出來的(隱式)，也可以是直接定義的(顯式)
`queue type` 會被重寫的情況只有 *leaf queue* 變為 *parent queue* 的情況(會在[之後](#placement-rules-定義)提及)，會出現這情況也代表了正在定義一個 *unmanaged queue* 的 *parent queue*

Access control lists(ACLs) 提供了提交權限及管理權限，提交權限顧名思義就是允許指定的 user / group 提交 application 到 queue 上，而管理權限則多了管理功能，但管理功能目前只有將 application kill 掉，或者將其移到別的 queue 裡

ACLs 會遞迴地由下往上搜尋是否具有權限，也就是說從 *leaf queue* 往上檢查到 `root`

#### queue 配置屬性
除了 `root` ，對於每個 queue 會有以下的屬性被設定：
- QueueType:
    - Parent(boolean)
- Resource settings:
    - Guaranteed (resource)
    - Maximum (resource)
- Running Application limit:
    - Maximum (integer)
- Queue Premissions:
    - SubmitACL (ACL)
    - AdminACL (ACL)
- Pre emption setting:
    - PreEmptionAllowed (boolean)
- Application sort algorithm:
    - ApplicationSortPolicy (enumeration: fair, fifo)

對於 `root` queue，則只有以下屬性可以被設定
- Running Application limit:
    - Maximum (integer)
- Queue permissions:
    - SubmitACL (ACL)
    - AdminACL (ACL)
- Application sort algorithm:
    - ApplicationSortpolicy (enumeration: fair, fifo)

### user 定義
user 的 application 可以在多個 queue 中執行，queue 中有 resource limit 來限制資源的用量，但其並不代表 user 的資源限制

對於 scheduler 來說，提交 application 的是 service 還是 person 並不重要，可以簡單將他們視為 user ，因此，在管理層面來看，不管是多租戶的資源分配，還是資源不當使用的問題，user 的資源限制都有其必要性

#### user 配置屬性
- Running Application limit:
    - Maximum (integer)
- Resource setting:
    - Maximum (integer)

### placement rules 定義
scheduler 在放 application 時，會動態地將其放在 queue 上，也就是說，在提交 application 時並不用指名 queue

placement rule 是一個紀錄 application 該放到哪個 queue 上的資訊
對於每次判斷都會回傳一個合法名稱的 queue 或者 `fail` ，如果是 `fail` 則代表需要再往下搜尋，直到找到第一個符合的 rule 為止

placement rule 可以回傳不在文件定義裡的 queue ，只要他被設定成可以創建新的 queue
在創建新的 queue 時，為了表達階層，可以使用 "." ，但會被解析為 "`_dot_`"

placement rule 創建出來的 *unmanaged queue* 不受管理者管理，管理者無法干擾 *unmanaged queue* ，它只在 scheduler 需要時被創建，並且在不再被使用後自動刪除

placement rule 會回傳一個合法的 queue ，也就是說，不給他一個完整的 *parent queue* 的名字的話，他會自己創建中間的 queue，而預設值是被設定為 `root` 下面的 *child queue*

下面是個範例，*user1* 屬於 *user1* 及 *companyA* 這兩個 group ，並且提交了一個 application
```yaml
Rule name: UserName
    Parent: root.fixedparent
Result: root.fixedparent.user1

Rule name: UserName
    Parent: SecondaryGroup
	Filter:
        Type: allow
	    Groups: company.*
Result: root.companyA.user1

Rule name: UserName
Filter:
    Users: user2,user3
Result: denied placement
```

將 application 放入 queue 的預設行為（與使用提交期間提供的 queue 的作用相同）是採用所提供的 queue 並將創建標誌設為 `false` 的 rule

ACLs 會是規則評估裡的一部分，對於 *manage queue* 來說，它會檢查 queue 它自己的 ACLs，但對於 *unmanaged queue* 來說，他則是會檢查 *parent queue* 的 ACLs

#### placement ruld 配置屬性
以下四個是必要的：
- Name:
    - Name (string)
- Parent:
    - Parent (string)
- Create Flag:
    - Create (boolean)
- Filter:
    - 一個用於應用在 rule 上的正規表達式

接下來是 Filter 的屬性：
- Type: 
    - Type (string) 可以是 ` ` 、`allow` 或 `deny`
- Users:
    - 0 或多個名字的 list ，也可以是正規表達式
- Groups:
    - 0 或多個名字的 list，也可以是正規表達式

對於放置 application 的屬性有：
- Provided: 回傳一個 queue
- UserName: 回傳一個 user name
- PrimaryGroupName: 回傳 user 的主要 group
- SecondaryGroupName: 回傳第二個符合 user 的 group
- Fixed: 回傳在 rule 裡配置的 queue name
- ApplicationType: 回傳 application 的 type(如果可以的話)

對於 *unmanged queue* ，無法提供 queue 的屬性，但應該考慮將以下屬性從 *manage parent* 傳到 *unmanaged child* ：
- Dynamic Resource settings:
    - Guaranteed (resource)
    - Maximum (resource)
- Dynamic Running Application limit:
    - Maximum (integer)

### 配置更新
更新會像是：新增、刪除等等動作，更新完後，新的 queue 將會使用新的配置，但使用更新之前的配置的 queue 將保持原樣，隨著時間流逝它會漸漸趨向新的配置

*managed queue* 只會在「從配置文檔中移除後」才會被移除，但在移除之前，還要確定它是空的，不然就要將其標記為 `drain` ，大致步驟如下：
1. queue 在配置文件中被移除了
2. 將 queue 標記為 `drain`
3. 將空的且被標記為 `drain` 的 *managed queue* 移除

在刪除 *managed queue* 時，應妥善處理長時間運行的 application ， scheduler 應該追蹤並暴露 queue 在較長時間內都處於 `draining` 的狀態
在最佳情況下，配置更新應通知到 application ，使其可以釋放資源
在所有情況下，配置更新應通知到管理員，已完成搬移 queue 的動作(目前仍是手動)

至於 *unmanaged queue* ，它有獨立於配置設定的生命週期，當它內部為空時會被自動移除，等到需要時在創建一個新的

刪除 queue (不管是 *managed* 還是 *unmanaged*) 的程式碼必須獨立於配置更新或者 scheduler 運行

總而言之，配置可能隨時間改變，但基本要點是：
- 更新後的配置不應該影響到正在執行的 application
- 該移除的 queue 應被處理

### ACLs(ccess control lists)
scheduler 的 ACLs 獨立於 queue 的 ACLs ，預設情況是 scheduler 的管理員不被允許提交 application 或者管理系統內的 queue

所有的 ACLs 應該使用相同的 pattern，同時也該考慮到基於系統環境的域說明符

預設配置將允許存取控制，但拒絕存取，唯一特例是 core scheduler 會自動的新增 system user (也就是 scheduler 的 process owner)進 scheduler ACL ，這樣他就能以 API 來使用管理功能了

ACLs 列出了誰可以存取，而不是誰不能存取，其配置定義如下：
```yaml
ACL ::= “*” |  userlist [ “ “ grouplist ]
userlist ::= “” | user { “,” user }
grouplist ::= “” | group { “,” group }
```

萬用字員 "\*" 代表所有 user / group ，要拒絕所有 user / group 有以下方法：
- 空的 ACLs
- 單一空格

如果沒有配置 ACLs 則將使用預設配置

## Shim 配置
shim 的配置高度仰賴 shim 的實作

k8s shim 與 yarn shim 不同
目前 k8s shim 是通過 cmd 進行配置，但我們應避免依賴它

### k8s shim
全部的配置還在開發

### yarn shim
全部的配置還在開發

---
[官方文檔連結](https://yunikorn.apache.org/docs/design/scheduler_configuration/#access-control-lists)