YAML 基礎
如果你正在做的事與很多軟件領域相關,那麼將很難不涉及到YAML,特別是Kubernetes,SDN,和OpenStack。YAML,它代表着另一種標誌語言,或者YAML不是標誌語言(取決於你問誰)而是特定配置類型基於人類可讀的文本格式的信息,例如,在本文中,我們將會分開說說明YAML定義創建Pod和使用Kubernetes創建一個Depolyment。
使用YAML用於k8s的定義將給你一些好處,包括:
便捷性:你將不再需要添加大量的參數到命令行中執行命令
可維護性:YAML文件可以通過源頭控制,可以跟蹤每次的操作
靈活性:通過YAML你將可以創建比命令行更加複雜的結構
YAML是一個JSON的超集,意味着任何有效JSON文件也都是一個有效的YAML文件。所以一方面,如果你知道JSON,你只是要去寫自己的YAML(而不是閱讀別人的)也就可以了。另一方面,不太可能,不幸的是,儘管你嘗試去網上找到例子,但是他們通常都不是JSON,所以我們可能需要去習慣它。不過,有JSON的情況下可能會更方便,這樣你將會很開心你懂得JSON。
幸運的是,YAML只有兩種結構類型你需要知道:
Lists
Maps
那就是說,將有可能存在lists的maps和maps的lists,等等,但是,你只要掌握了這兩種結構也就可以了。這並不是說你不能做更加複雜的事,但是通常,這些也就夠了。
YAML Maps
我們先開始看YAML maps。Maps讓你將鍵值組合,你就可以更加方便的去設置配置信息。例如,你可能有以下這樣一個配置信息:
apiVersion: v1
kind: Pod
第一行是分隔符,並且是可選的,除非你試圖在單個文件中定義多個結構。從這裏你可以看到,我們有兩個值,V1和Pod,對應他們的鍵是apiVersion和kind。
這種比較簡單,當然你也可以將之轉換爲json格式,如下:
{
"apiVersion": "v1",
"kind": "Pod"
}
注意,在我們的YAML版本中,引號是可選的,處理器可以知道你正在查看基於格式化的字符串。
你也可以指定一個複雜的結構,創建一個key其對應的值不是字符串而是一個maps如下所示:
apiVersion: v1
kind: Pod
metadata:
name: rss-site
labels:
app: web
這種情況下,我們有metadata這個key對應的值中又有兩個key分別爲name和labels。labels 這個key的值又是一個map。你可以根據場景進行多層嵌套。
YAML處理器可以根據行縮進來知道內容之間的關聯。在這個例子中我用了兩個空格使之可讀,但是空格的數量不重要,但是至少要求一個,並且所有縮進都保持一致的空格數。例如,name和labels是相同縮進級別,因此YAML處理器知道他們屬於同一map;它知道app是lables的值因爲app的縮進更大。
注意:在YAML文件中絕對不要使用tab鍵
因此,如果我們將上述內容翻譯成JSON,它看起來結果如下所示:
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "rss-site",
"labels": {
"app": "web"
}
}
}
現在讓我們來看看lists。
YAML lists
YAML lists 簡直是一個序列的對象,例如:
args
- sleep
- "1000"
- message
- "Bring back Firefly!"
正如你可以看到,你可以有任何數量的項在列表中,項的定義以破折號(-)開頭,並且與父元素之間存在縮進。在JSON格式中,它將表示如下:
{
"args": ["sleep", "1000", "message", "Bring back Firefly!"]
}
當然,list的子項也可以是maps,maps的子項也可以是list如下所示:
apiVersion: v1
kind: Pod
metadata:
name: rss-site
labels:
app: web
spec:
containers:
- name: front-end
image: nginx
ports:- containerPort: 80
- name: rss-reader
image: nickchase/rss-php-nginx:v1
ports:- containerPort: 88
正如你所看到的,我們有一個叫container的list對象,每個子項都由name、image、ports組成,每個ports都由一個key爲containerPort map組成
- containerPort: 88
如下所示,是上述內容的JSON格式:
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "rss-site",
"labels": {
"app": "web"
}
},
"spec": {
"containers": [{
"name": "front-end",
"image": "nginx",
"ports": [{
"containerPort": "80"
}]
},
{
"name": "rss-reader",
"image": "nickchase/rss-php-nginx:v1",
"ports": [{
"containerPort": "88"
}]
}]
}
}
正如你所看到的,我們寫的內容開始變的複雜,甚至我們還沒有進入任何特別複雜!難怪YAML代替JSON如此之快。
現在然我們複習一下,我們有:
maps,鍵值對
lists,單獨的項
maps的maps
maps的lists
lists的lists
lists的maps
基本上,無論你想要什麼樣結構,你都可以通過這兩個結構去組合實現。