注意:本教程是中級教程。 假定你對狀態系統和編寫salt公式已經有一些基本的瞭解。
您也可以參考在Github上維護的這一份技術資料:Understanding State Compiler Ordering
Salt的狀態系統旨在不犧牲簡單性的前提下提供配置管理系統的所有功能。 本教程旨在幫助用戶詳細瞭解Salt如何定義狀態執行的順序。
編寫本教程是爲了說明自0.17.0版本起Salt的行爲。
Compiler Basics - 編譯器的基礎知識
要深入瞭解狀態編譯的順序,有關狀態編譯器的一些非常基礎的知識非常有幫助。
High Data and Low Data - 高級數據與低級數據
在YAML中定義Salt公式時,編譯器將要表示的數據稱爲“High Data - 高級數據”。 最初將數據加載到編譯器時,它是一個大型python字典,可以通過運行以下命令查看該字典:
salt '*' state.show_highstate
然後,將這種“High Data - 高級數據”結構編譯爲“Low Data - 低級數據”。 低級數據相當於是在Salt的配置管理系統中創建單個執行動作,是要執行的單狀態調用的有序列表。 一旦低級數據被編譯,就可以看到評估順序的結果了。
執行以下命令查看低級數據:
salt '*' state.show_lowstate
注意:狀態執行模塊包含許多用於評估狀態系統的函數,非常值得一讀! 這些例程在調試狀態或幫助加深人們對Salt狀態系統的理解時非常有用。
例如,一個這樣寫的狀態:
apache:
pkg.installed:
- name: httpd
service.running:
- name: httpd
- watch:
- file: apache_conf
- pkg: apache
apache_conf:
file.managed:
- name: /etc/httpd/conf.d/httpd.conf
- source: salt://apache/httpd.conf
上面的狀態配置將會產生像下面這樣的 json 格式的High Data數據:
{
"apache": {
"pkg": [
{
"name": "httpd"
},
"installed",
{
"order": 10000
}
],
"service": [
{
"name": "httpd"
},
{
"watch": [
{
"file": "apache_conf"
},
{
"pkg": "apache"
}
]
},
"running",
{
"order": 10001
}
],
"__sls__": "blah",
"__env__": "base"
},
"apache_conf": {
"file": [
{
"name": "/etc/httpd/conf.d/httpd.conf"
},
{
"source": "salt://apache/httpd.conf"
},
"managed",
{
"order": 10002
}
],
"__sls__": "blah",
"__env__": "base"
}
}
隨後的Low Data數據看起來像這樣:
[
{
"name": "httpd",
"state": "pkg",
"__id__": "apache",
"fun": "installed",
"__env__": "base",
"__sls__": "blah",
"order": 10000
},
{
"name": "httpd",
"watch": [
{
"file": "apache_conf"
},
{
"pkg": "apache"
}
],
"state": "service",
"__id__": "apache",
"fun": "running",
"__env__": "base",
"__sls__": "blah",
"order": 10001
},
{
"name": "/etc/httpd/conf.d/httpd.conf",
"source": "salt://apache/httpd.conf",
"state": "file",
"__id__": "apache_conf",
"fun": "managed",
"__env__": "base",
"__sls__": "blah",
"order": 10002
}
]
這個教程討論了Low Data數據評估和state狀態運行時。
Ordering Layers - 定義執行順序的層次
Salt定義了2個在狀態運行時中評估命令執行順序的接口,並通過多次傳遞來最終定義這個執行順序。
Definition Order - 定義順序的功能系統
注意:通過將Master配置文件中的
state_auto_order
選項設置爲False
,可以禁用“定義順序”的系統功能。
排序的最高層次是“定義順序”系統。 定義順序系統功能是在Salt公式中定義狀態的執行順序。 在不包含include
語句或top
文件的基本狀態上,這非常簡單明瞭,因爲狀態只是從文件的頂部開始排序的,但是include系統開始爲定義順序引入更多的一些規則。
回顧上面顯示的"Low Data" 和 “High Data” ,"order"鍵已透明地添加到數據中以啓用“定義順序”的功能。
The Include Statement - Include語句
基本上,如果公式中包含一個include語句,則被包含的公式將在包含它們的公式的內容之前運行。 另外,include語句的值是一個列表,因此將按照包含它們的順序依次加載它們。
在下面的例子中:
foo.sls
include:
- bar
- baz
bar.sls
include:
- quo
baz.sls
include:
- qux
在上述情況下,如果調用了state.apply foo,則將按以下順序加載公式:
- quo
- bar
- qux
- baz
- foo
The order Flag - Order關鍵字標誌
"定義順序"的功能系統是在後臺透明地執行,但是還可以使用狀態中的order
標誌顯式地覆蓋該順序:
apache:
pkg.installed:
- name: httpd
- order: 1
該"order"標誌將超越"definition order"系統,這使得創建總是首先得到執行。指定在最後執行或在特定階段執行的狀態變得非常簡單,一個很好的例子是定義了許多必須在任何其他操作之前設置的軟件包存儲庫, 或需要使用order:last
或order:-1
在狀態運行結束時運行的最終檢查操作。
當顯式設置了order標誌時,"definition order"系統將省略爲該狀態設置執行順序,而直接使用定義的order標誌。
Lexicographical Fall-back - 回退至字典順序
Salt狀態將始終以相同順序執行。 在版本0.17.0中引入“定義順序”功能之前,是先根據狀態名稱按字典順序對所有內容進行排序,然後對函數進行排序,然後按id排序。
這是Salt確保狀態始終以相同順序運行的方式,無論它們部署在何處,附加的定義順序方法使這種順序更易於遵循。
字典順序仍然適用,但是僅在兩個順序語句發生衝突時纔有效。 這意味着,如果爲多個狀態分配了相同的順序號,它們將退回到字典順序,以確保每次執行時仍按有限順序進行。
注意:如果啓用了
state_auto_order:False
,則order
鍵不會自動設置,而字典順序則可以從其他鍵派生。
Requisite Ordering - 依賴性順序
Salt狀態是完全聲明性的,它們被編寫來聲明系統應處於的狀態。 這意味着組件可能要求其他組件已成功設置。 與其他管理系統不同,Salt中的Requisite系統是在運行時進行評估。
還爲此建立了一個requisite系統,以確保執行順序不會改變,對於給定的狀態集始終是相同的。 這是通過使用以完全可預測的順序處理狀態的運行時而不是像其他聲明性配置管理系統那樣使用基於事件循環的系統來完成的。
Runtime Requisite Evaluation - 運行時依賴性的評估
找到組件後,將評估Requisite系統,並且始終以相同順序評估Requisite條件。 該解釋之後將舉一個示例,原始解釋起初可能有點令人頭暈,因爲它創建了線性相關性評估序列。
“Low Data數據”是一個有序列表或字典,狀態運行時會按照字典在列表中的排列順序評估每個字典。 在評估單個字典時,將檢查必備條件,並按順序對必備條件進行評估,先進行requir
e ,然後是 watch
,最後做 prereq
檢查。
注意:如果在require_in和watch_in之類的語句中使用Required,則將在運行時評估之前將其編譯爲require和watch語句。
每個條件都包含一個有序的條件列表,這些條件在字典列表中查找然後執行。 一旦評估並執行了所有需求,就可以安全地運行需求的狀態(如果未滿足需求,則不運行)。
這意味着必須始終以相同的順序評估需求,這再次確保了Salt狀態系統的核心設計原則之一,以確保執行結果始終是有限的。
Simple Runtime Evaluation Example - 簡單的狀態執行順序評估分析示例
給定上述“低數據”後,將按以下順序評估狀態:
- 執行pkg.installed以確保已安裝apache軟件包,該軟件包不包含任何必需項,因此是要執行的第一個定義狀態。
- 評估service.running狀態但未執行,發現了監視條件,因此按順序讀取它們,運行時首先檢查文件,查看其尚未執行,然後調用要評估的文件狀態。
- 文件狀態是評估並執行了的,因爲它像pkg狀態一樣不包含任何必要條件。
- 繼續評估服務狀態,然後檢查pkg必要條件,並確定滿足該條件,並且滿足所有條件,現在執行服務狀態。
Best Practice - 最佳實踐
Salt的最佳實踐是選擇一種方法並堅持下去,因爲所有條件都創建了清晰,可追溯的依賴關係並適用於大多數可移植的公式,所以使用所有關聯的條件編寫正式的states狀態。 爲了完成與經典命令式系統運行類似的操作,可以省略所有的必要性條件,然後在master配置中將failhard
選項設置爲True
,這將在發生第一次故障時停止所有狀態的運行。
最後,使用Requisite必要條件將創建非常緊密且細粒度的狀態,不使用必要條件將使完整序列運行且編寫起來稍微容易一些,並且對執行的控制要少得多。