YAML 新手教學 | 5 分鐘掌握 YAML 10 大實用技巧


Deprecated: Return type of TagFilterNodeIterator::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/naomindc/public_html/stylengineer/wp-content/plugins/easy-table-of-contents/includes/vendor/ultimate-web-scraper/tag_filter.php on line 1149

Deprecated: Return type of TagFilterNodeIterator::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/naomindc/public_html/stylengineer/wp-content/plugins/easy-table-of-contents/includes/vendor/ultimate-web-scraper/tag_filter.php on line 1159

Deprecated: Return type of TagFilterNodeIterator::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/naomindc/public_html/stylengineer/wp-content/plugins/easy-table-of-contents/includes/vendor/ultimate-web-scraper/tag_filter.php on line 1154

Deprecated: Return type of TagFilterNodeIterator::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/naomindc/public_html/stylengineer/wp-content/plugins/easy-table-of-contents/includes/vendor/ultimate-web-scraper/tag_filter.php on line 1144

Deprecated: Return type of TagFilterNodeIterator::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/naomindc/public_html/stylengineer/wp-content/plugins/easy-table-of-contents/includes/vendor/ultimate-web-scraper/tag_filter.php on line 1139

Deprecated: Return type of TagFilterNodeIterator::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home2/naomindc/public_html/stylengineer/wp-content/plugins/easy-table-of-contents/includes/vendor/ultimate-web-scraper/tag_filter.php on line 1164

YAML 全名為 YAML Ain’t Markup Language, 它是標記式程式語言, 用於把資料包裝成結構化訊息, 是資料傳遞的通用標準格式

YAML 如同 XML、JSON 都是標記式程式語言, 過往都是 XML、JSON 較為普及, 然而 YAML 其良好閱讀性和乾淨簡潔的表達方式, 讓他成為了近期流行工具如 Ansible 、Kubernetes 指定使用的語法, 使它一躍成為時下最炙手可熱的 Mark Langauge

▲ YAML 可讀性與標達簡潔度相較 XML、JSON 更勝一籌

現在就介紹給各位身為初心者必須要知道的 10 大實用技巧, 只要花 5 分鐘仔細讀完這篇文章, 就可以清楚掌握 YAML 的核心觀念, 馬上加入同事間的 YAML 討論, 不想被排擠的話就趕快看下去吧 !

鍵值對 (Key-Value Pair)

語法: key: value

YAML 的內容是由一連串的鍵值對所組成, 舉例: app: application。 其中, key = app, value = application, key 與 value 之間由 : + 空格串接注意: 在 YAML的世界中是 whitesppace sensitive, 意指空白鍵都是有意義的, 故不可以省略

app: application
port: 9090
version: 1.0

註解 (Comments)

語法: # commen here

在程式碼的開頭加上 # 符號, 系統就會認得這一行程式碼是註解, 電腦就會忽略不去轉譯這一句

# comment here
app: application
port: 9090
version: 1.0

單引號、雙引號、不使用引號 (Quotations)


YAML 中的引號在表示字符串時有不同的含義:

  1. 不使用引號:
    • 在 YAML 中,如果一個字符串沒有被單引號或雙引號包圍,它被視為純粹的標量值。YAML 解析器會盡量將其解釋為合適的數據類型,如字符串或數字。
  2. 單引號:
    • 如果一個字符串被單引號包圍,它將被視為純粹的字符串,不進行任何轉義操作。這意味著你可以在單引號內使用特殊字符而不必擔心它們被解釋。
  3. 雙引號:
    • 如果一個字符串被雙引號包圍,它允許使用轉義字符,並支持更多的特殊字符。雙引號內的特殊字符會被解釋,並按照相應的規則進行處理。

在實際使用中,選擇使用單引號或雙引號通常取決於你希望如何處理字符串內的特殊字符。如果你希望字符串保持原樣,使用單引號;如果你希望進行變量替換或轉義字符解釋,使用雙引號。不使用引號則程式會自動根據內容轉換成 Boolean、Interger 等型態

# need to quote?
# if a string include space or other special character, you must quote, for example: Meal: "Vegetable Lasagna"

app: "user-authiertication \n test"
port: 9090
version: 1.7

物件 (Objects)

如下創建一個名叫 microservice 的物件 (object), 物件底下有三個屬性 (attribute) app、port、version。注意: 物鍵底下的每一個屬性都必須要留白鍵做縮排, 且屬性之間縮排必須對齊。因為在 YAML的世界中是 whitesppace sensitive, 空白鍵與空白間的格數都是有意義的。

錯誤示範: example-2 , version 屬性沒有對齊 app port

# example-1
microservice:
  app: application
  port: 9090
  version: 1.0

---
# example-2
microservice:
  app: application
  port: 9090
    version: 1.0

清單 (Lists)

語法:

當你使用 創建清單的時候, 電腦會知道這是清單, 這時候有沒有空白鍵縮排都無所謂 (只有這時候通融)

# create list with -
# create list of objests with -
# yaml can recognize list item with -, with or whthout indention is ok if it's a list 
microservices:
  - app: app1
    port: 9090
    version: 1.0
  - app: app2
    port: 8080
    version: 
      - 1.9
      - 2.0
      - 2.1

list 也有第二種表示方式[ … ], 舉例: [A, B, C]

# express list object in different way [A, B, C]
microservices2:
  - app: app1
    port: 9090
    version: 1.0
  - app: app2
    port: 8080
    version: [1.9, 2.0, 2.1]

---
#advanced example:
appVersion: v1
kind: Pod
metadata: 
  name: nginx
  labels:
    app: nginx
  spec:
    continaaters:
    - name: nginx-container
      image: nginx
      ports:
      -  containerPort: 80
      volumeMounts:
      - name: nginx-vol
        mountPath: /usr/nginx/html
    - name: sidecar-container
      image: some-image
      command: ["/bin/sh"]
      args: ["-c", "echo hello from the sidecar container"]

布林值 (Boolean)

語法: key: true, key: false

microservices:
  - app: app1
    port: 9090
    version: 1.0
    deployed: true
  - app: app2
    port: 8080
    version: [1.9, 2.0, 2.1]
    deployed: false

多行字串、單行字串 (Multiline Strings、Singlieline Strings)

多行字串語法: key: | …

單行字串語法: key: > …

#multiline string:
# make yaml file readable

#multiline example: (|)
multilineString: |
  this is a multiline string
  and this is the next line
  next linee

# singleline exmple: (>)
singlelineString: >
  this is a singlie string,
  that should be all on one line.
  some other stuff

#advanced exmple:
command:
  - sh
  - -c
  # it is a shell script
  - |
    http () {
      local path="${1}"
      set -- -XGET -s --fail
      curl -k "$@" "http://...."
    }

環境變數 Env Variables

語法: key: ${env variables}

# env variables
# use dollar sign ($) to call env variables in kubernetes
command2:
  - /bin/sh
  - -ec
  - >-
    mysql -h 127.0.0.0 root -p$MYSQL_ROOT_PASSWORD -e 'SELECT 1'

佔位符 Placeholders

語法: key: {{ … }}

placeholders
# syntax: {{ ... }}
appVersion2: v1
kind2: Service
metadata2:
  name: {{ .Values.service.name}}
spec2:
  selector:
    app: {{ .Values.service.app}}
  ports:
    - protocal: TCP
      port: {{ .Value.service.port}}
      targetPort: {{ .Values.service.targetPort}}

多個獨立 YAML 檔案 Multiple YAML Documents

語法:

# multiple yaml documents
# syntax: ---

---
appVersion: v1
kind: Pod
metadata: 
  name: nginx
  labels:
    app: nginx
---
appVersion: v1
kind: Pod
metadata: 
  name: nginx
  labels:
    app: nginx