YAML學習筆記
在運維日常工作中又很多遇到yaml,例如寫ansible的playbook,利用yaml來定義創建各應用及服務。
1.1 概念
YAML(發音 /?j?m?l/)是一個類似 XML、JSON 的數據序列化語言,YAML是專門用來寫配置文件的語言,非常簡潔和強大,使用比json更方便。它實質上是一種通用的數據串行化格式。其強調以數據為中心,旨在方便人類使用;並且適用於日常常見任務的現代編程語言。因而 YAML 本身的定義比較簡單,號稱“一種人性化的數據格式語言”。
1.2 優點
- 便捷性:不必添加大量參數到命令行中執行命令
- 可維護性:yaml文件可以通過控制源頭,跟蹤每次操作
- 靈活性:yaml可創建比命令行更加復雜的結構
- 簡易:易使用
1.3 語法規則
- 大小寫敏感
- 使用縮進表示層級關系
- 縮進不允許使用Tab鍵,只允許空格
- 縮進空格數目不重要,只要相同層級的元素左側對齊
- #表示註釋
1.4 組織結構
文檔間使用“---”(三個橫線)在每文檔開始作為分隔符。同時,文檔也可以使用“...”(三個點號)作為結束符(可選)二、結構類型
2.1 Maps類型
Map為字典,一對key:value鍵值對,例如
---
apiVersion: v1
kind: Pod
第一行的---是分隔符,是可選的,在單一文件中,可用連續三個連字號---區分多個文件。這裏我們可以看到,我們有兩個鍵:kind 和 apiVersion,他們對應的值分別是:v1和Pod。上面的 YAML 文件轉換成 JSON 格式的話,你肯定就容易明白了:
{
"apiVersion": "v1",
"kind": "pod"
}
上面的 YAML 文件,metadata 這個 KEY 對應的值就是一個Maps了,而且嵌套的 labels 這個 KEY 的值又是一個Map,你可以根據你自己的情況進行多層嵌套。
上面我們也提到了 YAML 文件的語法規則,YAML 處理器是根據行縮進來知道內容之間的嗯關聯性的。比如我們上面的 YAML 文件,我用了兩個空格作為縮進,空格的數量並不重要,但是你得保持一致,並且至少要求一個空格(什麽意思?就是你別一會縮進兩個空格,一會縮進4個空格)。我們可以看到 name 和 labels 是相同級別的縮進,所以 YAML 處理器就知道了他們屬於同一個 MAP,而 app 是 labels 的值是因為 app 的縮進更大。
同樣的,我們可以將上面的 YAML 文件轉換成 JSON 文件:
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "kube100-site",
"labels": {
"app": "web"
}
}
}
2.2 Lists類型
List為數組
args
- Cat
- Dog
- Fish
你可以有任何數量的項在列表中,每個項的定義以破折號(-)開頭的,與父元素直接可以縮進一個空格。對應的 JSON 格式如下:
{
"args": [ ‘Cat‘, ‘Dog‘, ‘Fish‘ ]
}
2.3 混合類型
---
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: 8080
如上述文件所示,定義一個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"
}]
}, {
"name": "flaskapp-demo",
"image": "jcdemo/flaskapp",
"ports": [{
"containerPort": "5000"
}]
}]
}
}
對上面的yaml文件進行解釋:
- apiVersion:此處值是v1,這個版本號需要根據安裝的Kubernetes版本和資源類型進行變化
- kind:此處創建的是Pod,根據實際情況,此處資源類型可以是Deployment、Job、Ingress、Service等
- metadata:包含了我們定義的 Pod 的一些 meta 信息,比如name、namespace、lebal等等信息。
- spec:包括一些 containers,storage,volumes,或者其他Kubernetes需要知道的參數,以及諸如是否在容器失敗時重新啟動容器的屬性。你可以在特定Kubernetes API找到完整的Kubernetes Pod的屬性。
containers 可設置的屬性:
name
image
command
args
workingDir
ports
env
resources
volumeMounts
livenessProbe
readinessProbe
livecycle
terminationMessagePath
imagePullPolicy
securityContext
stdin
stdinOnce
tty
三、yaml文件實例
-
k8s
apiVersion: v1 #指定api版本,此值必須在kubectl apiversion中 kind: Pod #指定創建資源的角色/類型 metadata: #資源的元數據/屬性 name: web04-pod #資源的名字,在同一個namespace中必須唯一 labels: #設定資源的標簽,詳情請見http://blog.csdn.net/liyingke112/article/details/77482384 k8s-app: apache version: v1 kubernetes.io/cluster-service: "true" annotations: #自定義註解列表 - name: String #自定義註解名字 spec:#specification of the resource content 指定該資源的內容 restartPolicy: Always #表明該容器一直運行,默認k8s的策略,在此容器退出後,會立即創建一個相同的容器 nodeSelector: #節點選擇,先給主機打標簽kubectl label nodes kube-node1 zone=node1 zone: node1 containers: - name: web04-pod #容器的名字 image: web:apache #容器使用的鏡像地址 imagePullPolicy: Never #三個選擇Always、Never、IfNotPresent,每次啟動時檢查和更新(從registery)images的策略, # Always,每次都檢查 # Never,每次都不檢查(不管本地是否有) # IfNotPresent,如果本地有就不檢查,如果沒有就拉取 command: [‘sh‘] #啟動容器的運行命令,將覆蓋容器中的Entrypoint,對應Dockefile中的ENTRYPOINT args: ["$(str)"] #啟動容器的命令參數,對應Dockerfile中CMD參數 env: #指定容器中的環境變量 - name: str #變量的名字 value: "/etc/run.sh" #變量的值 resources: #資源管理,請求請見http://blog.csdn.net/liyingke112/article/details/77452630 requests: #容器運行時,最低資源需求,也就是說最少需要多少資源容器才能正常運行 cpu: 0.1 #CPU資源(核數),兩種方式,浮點數或者是整數+m,0.1=100m,最少值為0.001核(1m) memory: 32Mi #內存使用量 limits: #資源限制 cpu: 0.5 memory: 32Mi ports: - containerPort: 80 #容器開發對外的端口 name: httpd #名稱 protocol: TCP livenessProbe: #pod內容器健康檢查的設置,詳情請見http://blog.csdn.net/liyingke112/article/details/77531584 httpGet: #通過httpget檢查健康,返回200-399之間,則認為容器正常 path: / #URI地址 port: 80 #host: 127.0.0.1 #主機地址 scheme: HTTP initialDelaySeconds: 180 #表明第一次檢測在容器啟動後多長時間後開始 timeoutSeconds: 5 #檢測的超時時間 periodSeconds: 15 #檢查間隔時間 #也可以用這種方法 #exec: 執行命令的方法進行監測,如果其退出碼不為0,則認為容器正常 # command: # - cat # - /tmp/health #也可以用這種方法 #tcpSocket: //通過tcpSocket檢查健康 # port: number lifecycle: #生命周期管理 postStart: #容器運行之前運行的任務 exec: command: - ‘sh‘ - ‘yum upgrade -y‘ preStop: #容器關閉之前運行的任務 exec: command: [‘service httpd stop‘] volumeMounts: #詳情請見http://blog.csdn.net/liyingke112/article/details/76577520 - name: volume #掛載設備的名字,與volumes[*].name 需要對應 mountPath: /data #掛載到容器的某個路徑下 readOnly: True volumes: #定義一組掛載設備 - name: volume #定義一個掛載設備的名字 #meptyDir: {} hostPath: path: /opt #掛載設備類型為hostPath,路徑為宿主機下的/opt,這裏設備類型支持很多種
對應的json格式
{ ‘kind‘: ‘Pod‘, ‘spec‘: { ‘restartPolicy‘: ‘Always‘, ‘containers‘: [ { ‘livenessProbe‘: { ‘initialDelaySeconds‘: 180, ‘httpGet‘: { ‘path‘: ‘/‘, ‘scheme‘: ‘HTTP‘, ‘port‘: 80 }, ‘timeoutSeconds‘: 5, ‘periodSeconds‘: 15 }, ‘name‘: ‘web04-pod‘, ‘image‘: ‘web:apache‘, ‘args‘: [ ‘$(str)‘ ], ‘volumeMounts‘: [ { ‘readOnly‘: True, ‘mountPath‘: ‘/data‘, ‘name‘: ‘volume‘ } ], ‘ports‘: [ { ‘protocol‘: ‘TCP‘, ‘containerPort‘: 80, ‘name‘: ‘httpd‘ } ], ‘command‘: [ ‘sh‘ ], ‘env‘: [ { ‘name‘: ‘str‘, ‘value‘: ‘/etc/run.sh‘ } ], ‘imagePullPolicy‘: ‘Never‘, ‘lifecycle‘: { ‘preStop‘: { ‘exec‘: { ‘command‘: [ ‘service httpd stop‘ ] } }, ‘postStart‘: { ‘exec‘: { ‘command‘: [ ‘sh‘, ‘yum upgrade -y‘ ] } } }, ‘resources‘: { ‘requests‘: { ‘cpu‘: 0.1, ‘memory‘: ‘32Mi‘ }, ‘limits‘: { ‘cpu‘: 0.5, ‘memory‘: ‘32Mi‘ } } } ], ‘volumes‘: [ { ‘hostPath‘: { ‘path‘: ‘/opt‘ }, ‘name‘: ‘volume‘ } ], ‘nodeSelector‘: { ‘zone‘: ‘node1‘ } }, ‘apiVersion‘: ‘v1‘, ‘metadata‘: { ‘labels‘: { ‘k8s-app‘: ‘apache‘, ‘version‘: ‘v1‘, ‘kubernetes.io/cluster-service‘: ‘true‘ }, ‘name‘: ‘web04-pod‘, ‘annotations‘: [ { ‘name‘: ‘String‘ } ] } }
- ansible
---
- hosts: agent # 定義主機
remote_user: root # 定義執行此playbook的用戶
tasks: # 任務
- name: install mysql-server #自定義名稱
yum: name=mysql-server state=present # yum模塊安裝mysql-server
- name: start mysql-server
service: name=mysqld state=started # service模塊啟動mysql服務
- name: check mysql service
shell: ps -ef |grep mysqld # shell模塊查看mysql進程
對應的json格式
{
‘tasks‘: [
{
‘yum‘: ‘name=mysql-server state=present‘,
‘name‘: ‘install mysql-server‘
},
{
‘name‘: ‘start mysql-server‘,
‘service‘: ‘name=mysqld state=started‘
},
{
‘shell‘: ‘ps -ef |grep mysqld‘,
‘name‘: ‘check mysql service‘
}
],
‘hosts‘: ‘agent‘,
‘remote_user‘: ‘root‘
}]
- 利用python講yaml格式轉換為json
pip install pyyaml # 安裝pyyaml模塊
import yaml
with open(‘config.yaml‘,‘r‘) as f:
content = yaml.load(f)
print(content)
YAML學習筆記