剛剛寫kubernetes的YAML文件時比較迷糊。
本文參考https://blog.qikqiak.com/post/use-yaml-create-kubernetes-deployment/
YAML 基礎
YAML 是專門用來寫配置文件的語言,非常簡潔和強大,遠比JSON格式方便。YAML語言(發音 /ˈjæməl/)的設計目標,就是方便人類讀寫。它實質上是一種通用的數據串行化格式。
它的基本語法規則如下:
- 大小寫敏感
- 使用縮進表示層級關系
- 縮進時不允許使用Tab鍵,只允許使用空格。
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
#表示注釋,從這個字符一直到行尾,都會被解析器忽略。
在我們的kubernetes中,你只需要兩種結構類型就行了:
- Lists
- Maps
也就是說,你可能會遇到Lists的Maps和Maps的Lists,等等。不過不用擔心,你只要掌握了這兩種結構也就可以了,其他更加復雜的我們暫不討論。
Maps
首先我們來看看Maps,我們都知道Map是字典,就是一個key:value的鍵值對,Maps可以讓我們更加方便的去書寫配置信息,例如:
--- apiVersion: v1 kind: Pod
第一行的---是分隔符,是可選的,在單一文件中,可用連續三個連字號---區分多個文件。這里我們可以看到,我們有兩個鍵:kind 和 apiVersion,他們對應的值分別是:v1和Pod。上面的 YAML 文件轉換成 JSON 格式的話,你肯定就容易明白了:
{ "apiVersion": "v1", "kind": "pod" }
我們在創建一個相對復雜一點的 YAML 文件,創建一個 KEY 對應的值不是字符串而是一個 Maps:
--- apiVersion: v1 kind: Pod metadata: name: kube100-site labels: app: web
上面的 YAML 文件,metadata 這個 KEY 對應的值就是一個Maps了,而且嵌套的 labels 這個 KEY 的值又是一個Map,你可以根據你自己的情況進行多層嵌套。
上面我們也提到了 YAML 文件的語法規則,YAML 處理器是根據行縮進來知道內容之間的嗯關聯性的。比如我們上面的 YAML 文件,我用了兩個空格作為縮進,空格的數量並不重要,但是你得保持一致,並且至少要求一個空格(什么意思?就是你別一會縮進兩個空格,一會縮進4個空格)。我們可以看到 name 和 labels 是相同級別的縮進,所以 YAML 處理器就知道了他們屬於同一個 MAP,而 app 是 labels 的值是因為 app 的縮進更大。
注意:在 YAML 文件中絕對不要使用 tab 鍵。
同樣的,我們可以將上面的 YAML 文件轉換成 JSON 文件:
{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "kube100-site", "labels": { "app": "web" } } }
或許你對上面的 JSON 文件更熟悉,但是你不得不承認 YAML 文件的語義化程度更高吧?
Lists
Lists就是列表,說白了就是數組,在 YAML 文件中我們可以這樣定義:
args - Cat - Dog - Fish
你可以有任何數量的項在列表中,每個項的定義以破折號(-)開頭的,與父元素直接可以縮進一個空格。對應的 JSON 格式如下:
{ "args": [ 'Cat', 'Dog', 'Fish' ] }
當然,list 的子項也可以是 Maps,Maps 的子項也可以是list如下所示:
--- apiVersion: v1 kind: Pod metadata: name: kube100-site labels: app: web spec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: flaskapp-demo image: jcdemo/flaskapp ports: - containerPort: 5000
比如這個 YAML 文件,我們定義了一個叫 containers 的 List 對象,每個子項都由 name、image、ports 組成,每個 ports 都有一個 key 為 containerPort 的 Map 組成,同樣的,我們可以轉成如下 JSON 格式文件:
{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "kube100-site", "labels": { "app": web" } }, "spec": { "containers": [{ "name": "front-end", "image": "nginx", "ports": [{ "containerPort": "80" 