附錄:YAML 技巧
本指南的大部分內容都集中在編寫範本語言上。在這裡,我們將探討 YAML 格式。YAML 有一些實用的功能,我們作為範本作者,可以利用這些功能使我們的範本更不容易出錯且更易於閱讀。
純量和集合
根據 YAML 規格,有兩種类型的集合和許多純量类型。
這兩種类型的集合是映射和序列
map:
one: 1
two: 2
three: 3
sequence:
- one
- two
- three
純量值是單個值(而不是集合)
YAML 中的純量类型
在 Helm 的 YAML 方言中,值的純量資料类型由一組複雜的規則決定,包括資源定義的 Kubernetes 綱要。但在推斷类型時,以下規則往往適用。
如果整數或浮點數是不帶引號的純文字,則通常將其視為數值类型
count: 1
size: 2.34
但如果它們帶有引號,則將其視為字串
count: "1" # <-- string, not int
size: '2.34' # <-- string, not float
布林值也是如此
isGood: true # bool
answer: "true" # string
空值的字詞是 null
(而不是 nil
)。
請注意,port: "80"
是有效的 YAML,並且可以通過範本引擎和 YAML 解析器,但如果 Kubernetes 預期 port
是整數,則會失敗。
在某些情況下,您可以使用 YAML 節點標籤強制執行特定类型推斷
coffee: "yes, please"
age: !!str 21
port: !!int "80"
在上面,!!str
告訴解析器 age
是字串,即使它看起來像整數。而 port
被視為整數,即使它帶有引號。
YAML 中的字串
我們放置在 YAML 文件中的大部分資料都是字串。YAML 有多種表示字串的方法。本節說明這些方法,並演示如何使用其中的一些方法。
有三種「內嵌」宣告字串的方法
way1: bare words
way2: "double-quoted strings"
way3: 'single-quoted strings'
所有內嵌樣式都必須在一行上。
- 純文字是不帶引號的,並且沒有跳脫。因此,您必須小心使用的字元。
- 雙引號字串可以使用
\
跳脫特定字元。例如"\"Hello\", she said"
。您可以使用\n
跳脫換行符。 - 單引號字串是「字面量」字串,不使用
\
跳脫字元。唯一的跳脫序列是''
,它被解碼為單個'
。
除了單行字串之外,您還可以宣告多行字串
coffee: |
Latte
Cappuccino
Espresso
以上將把 coffee
的值視為等同於 Latte\nCappuccino\nEspresso\n
的單個字串。
請注意,|
之後的第一行必須正確縮排。因此,我們可以通過執行以下操作來破壞上面的範例
coffee: |
Latte
Cappuccino
Espresso
因為 Latte
縮排不正確,我們會收到如下錯誤
Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key
在範本中,有時將虛假的「第一行」內容放入多行文件中更安全,只是為了防止出現上述錯誤
coffee: |
# Commented first line
Latte
Cappuccino
Espresso
請注意,無論第一行是什麼,它都將保留在字串的輸出中。因此,例如,如果您使用此技術將檔案的內容注入 ConfigMap,則註釋應為讀取該條目的任何內容所期望的类型。
控制多行字串中的空格
在上面的範例中,我們使用 |
來表示多行字串。但請注意,我們的字串內容後面跟著一個尾隨的 \n
。如果我們希望 YAML 處理器去除尾隨的換行符,我們可以在 |
之後添加一個 -
coffee: |-
Latte
Cappuccino
Espresso
現在 coffee
的值將是:Latte\nCappuccino\nEspresso
(沒有尾隨的 \n
)。
其他時候,我們可能希望保留所有尾隨空格。我們可以使用 |+
符號來做到這一點
coffee: |+
Latte
Cappuccino
Espresso
another: value
現在 coffee
的值將是 Latte\nCappuccino\nEspresso\n\n\n
。
文字區塊內的縮排將被保留,並且也會導致換行符被保留
coffee: |-
Latte
12 oz
16 oz
Cappuccino
Espresso
在上面的情況下,coffee
將是 Latte\n 12 oz\n 16 oz\nCappuccino\nEspresso
。
縮排和範本
在編寫範本時,您可能會發現自己希望將檔案的內容注入範本中。正如我們在前面的章節中看到的,有兩種方法可以做到這一點
- 使用
{{ .Files.Get "FILENAME" }}
獲取圖表中檔案的內容。 - 使用
{{ include "TEMPLATE" . }}
渲染範本,然後將其內容放置到圖表中。
將檔案插入 YAML 時,最好了解上面的多行規則。通常,插入靜態檔案的最簡單方法是執行以下操作
myfile: |
{{ .Files.Get "myfile.txt" | indent 2 }}
請注意我們如何進行上述縮排:indent 2
告訴範本引擎將「myfile.txt」中的每一行縮排兩個空格。請注意,我們沒有縮排該範本行。這是因為如果我們這樣做了,第一行的檔案內容將會縮排兩次。
摺疊多行字串
有時您希望在 YAML 中用多行表示字串,但在解釋時希望將其視為一行長字串。這稱為「摺疊」。要宣告摺疊區塊,請使用 >
而不是 |
coffee: >
Latte
Cappuccino
Espresso
上面的 coffee
的值將是 Latte Cappuccino Espresso\n
。請注意,除了最後一個換行符之外,所有換行符都將轉換為空格。您可以將空格控制與摺疊文字標記結合使用,因此 >-
將替換或修剪所有換行符。
請注意,在摺疊語法中,縮排文字將導致保留行。
coffee: >-
Latte
12 oz
16 oz
Cappuccino
Espresso
以上將產生 Latte\n 12 oz\n 16 oz\nCappuccino Espresso
。請注意,空格和換行符仍然存在。
在一個檔案中嵌入多個文件
可以將多個 YAML 文件放置到單個檔案中。這是通過在新文件前面加上 ---
並在文件結尾加上 ...
來完成的
---
document:1
...
---
document: 2
...
在許多情況下,可以省略 ---
或 ...
。
Helm 中的某些檔案不能包含多個文件。例如,如果在 values.yaml
檔案中提供了多個文件,則只會使用第一個文件。
但是,範本檔案可能包含多個文件。發生這種情況時,在範本渲染期間,檔案(及其所有文件)將被視為一個物件。但在將生成的 YAML 送入 Kubernetes 之前,它會被分割成多個文件。
我們建議僅在絕對必要時才在每個檔案中使用多個文件。在檔案中包含多個文件可能難以除錯。
YAML 是 JSON 的超集
因為 YAML 是 JSON 的超集,所以任何有效的 JSON 文件應該都是有效的 YAML。
{
"coffee": "yes, please",
"coffees": [
"Latte", "Cappuccino", "Espresso"
]
}
以上是表示此內容的另一種方法
coffee: yes, please
coffees:
- Latte
- Cappuccino
- Espresso
並且可以將兩者混合使用(小心)
coffee: "yes, please"
coffees: [ "Latte", "Cappuccino", "Espresso"]
這三者都應解析為相同的內部表示形式。
雖然這表示諸如 values.yaml
之類的檔案可能包含 JSON 資料,但 Helm 不會將檔案擴展名 .json
視為有效的後綴。
YAML 定位點
YAML 規格提供了一種儲存對值的參考的方法,並稍後通過參考引用該值。YAML 將此稱為「定位」
coffee: "yes, please"
favorite: &favoriteCoffee "Cappuccino"
coffees:
- Latte
- *favoriteCoffee
- Espresso
在上面,&favoriteCoffee
設定了對 Cappuccino
的參考。稍後,該參考將用作 *favoriteCoffee
。因此 coffees
變為 Latte, Cappuccino, Espresso
。
雖然在某些情況下定位點很有用,但它們的一個方面可能會導致細微的錯誤:第一次使用 YAML 時,參考會被展開然後丟棄。
因此,如果我們要解碼然後重新編碼上面的範例,則生成的 YAML 將是
coffee: yes, please
favorite: Cappuccino
coffees:
- Latte
- Cappuccino
- Espresso
因為 Helm 和 Kubernetes 經常讀取、修改然後重寫 YAML 檔案,所以定位點將會丟失。