今天我們來探討到底在 CI 過程中,我們可以對 Kubernetes 應用做哪些測試?
我認為這個測試包含了
- 應用程式是否於 Kuberentes 內運作如預期
- 使用 Yaml 的話,則 Yaml 本身格式是否正確
- 使用 Helm 的話,則 Helm 要求的內容與格式是否正確
而今天這篇文章主要會針對 (2),(3) 兩個部分來進行研究。
題外話,(2)(3) 這些格式檢查的部分不一定要 CI 階段才檢查,甚至可以跟 Git 整合, Pre-commit 階段就進行檢查,確保所有開發者提交的 Commit 都已經通過這些測試
Yaml 測試
接下來探討一下 Yaml 這格式本身的驗證,這部分有兩個概念
Yaml 格式的正確性
Yaml 內容的合理性
(1) 因為確認的是格式的正確性,會針對 Yaml 的格式檢查,譬如縮排,雙引號,單引號等進行檢查,這部分可以透過 lint 等工具幫忙檢查,同時也可以確保團隊內的人擁有一致撰寫 Yaml 的習慣與格式。 基本上任何 Yaml 都可以進行這方面檢查,不論是 Kubernetes Yaml, Helm 或是其他的內容,譬如給 pipeline 系統的 yaml, 放設定檔案的 Yaml 都可以這麼做。
(2) 因為確認的是合理性,所以其實會需要有前後文的概念,舉例來說,今天要部署 Kubernetes Yaml,我們就可以針對 Yaml 的內容去確認是否符合 Kubernetes 的用法。
舉例來說,下列是一個合法的 Yaml 檔案,但是並不是一個合法的 Kubernetes Yaml。
1 | kind: Cluster |
所以我們需要一些方法來幫我們驗證所有的 Yaml 是否可以滿足 (1) 與 (2) 兩種情況,因此接下來我們列出幾個可能使用的工具,看看這些工具怎麼使用,以及使用上的效果
Yamllint
yamllint 官網介紹如下
A linter for YAML files.
yamllint does not only check for syntax validity, but for weirdnesses like key repetition and cosmetic problems such as lines length, trailing spaces, indentation, etc.
這個工具就是幫忙檢查一些寫法,但是並沒有語意的檢查,不過會針對一些 key 重複的問題也指證出來,以下有一些範例
這邊是一個完整沒錯誤的 Yaml 檔案
1 | kind: Cluster |
接下來我們對其修改,譬如加入一個重複的 Key, 然後讓底下的縮排格式不一致,長這樣
1 | kind: Cluster |
這種情狂下我們使用 yamllint 針對這個檔案檢查
1 | $ yamllint kind.yaml |
第一行主要是警告,提醒要有文件的描述,但是不影響運行。
後面兩行則是不同的錯誤,分別是因為 第六行的縮排有問題,以及第七行產生一個重複 key 而導致的錯誤。
此外譬如字串雙引號/單引號沒有成雙等類型錯誤也都可以找到,有興趣的人可以去玩玩看這個工具
Kubeeval
kubeval 官方介紹如下
kubeval
is a tool for validating a Kubernetes YAML or JSON configuration file. It does so using schemas generated from the Kubernetes OpenAPI specification, and therefore can validate schemas for multiple versions of Kubernetes.
下列一個合法的 Kubernetes Yaml 檔案
1 | apiVersion: v1 |
我們可以先用 kubeeval 跑看看,接下來我們在修改這個檔案來試試看會有什麼樣的錯誤
1 | $ ./kubeval pod.yaml |
接下來我們修改 Yaml 檔案,來進行一些修改讓他不合格,譬如少給一些欄位,或是多給一些欄位
1 | apiVersion: v1 |
以上就是一個不合格的 Pod Yaml, 首先多一個 ithome
的欄位,同時又少了 containers
這個資訊
首先我們透過 kubeeval
去跑一次,發現有得到一個警告,告知我們 containers
這個欄位是必須的,但是卻沒有給。
但是多出來的 ithome 卻沒有警告?
1 | $ ./kubeval pod.yaml |
從上面可以觀察到我們需要加入 --strict
這個參數,才會去檢查多出來不存在原本 schema 內的欄位,因此我們再跑一次看看
1 | $ ./kubeval --strict pod.yaml |
這時候就可以順利的看到兩個錯誤都被抓出來了!
Conftest
conftest 的官網說明如下
Conftest is a utility to help you write tests against structured configuration data. For instance you could write tests for your Kubernetes configurations, or Tekton pipeline definitions, Terraform code, Serverless configs or any other structured data.
Conftest 這個工具可以幫助開發者去測試來驗證不同類型的設定檔案,譬如 Kubernetes, Tekton 甚至是 Terraform 的設定。
不過使用上必須要先撰寫相關的 Policy 去描述自己期望的規則,最後會幫你的設定檔案與相關的 Policy 去比對看看你的設定檔案是否破壞你的 Policy。
相對於前面的工具去針對 yaml 格式, kubernetes 資源的 schema 的比較, contest 更像是針對 policy 去比對,舉例來說,我們有一下列一個 pod yaml.
1 | apiVersion: v1 |
然後團隊今天有個要求,所有 Pod
的 Yaml 都必須要符合兩個規範
- restartPolicy 只能是 Never
- runAsNonRoot 這個欄位必須要設定是 True,希望可以以非 root 執行
只要有符合任何一個條件,我們希望 conftest 能夠找出來,並且告知錯誤,於是我們準備了下列檔案
1 | $ cat policy/pod.rego |
我們使用了 deny
去描述兩個 policy, 只要符合這些 policy 的都會判錯
接下來我們用 conftest 去執行看看
1 | $ conftest test pod.yaml -p policy/ |
可以發現 conftest 認為系統中有兩個測試要跑,而這兩個測試都失敗
接下來我們修改檔案讓他符合我們的規則後再跑一次
1 | $ cat pod.yaml |
這時候就可以發現已經通過測試了,所以如果團隊中有這些需求的人可以考慮導入這個工具看看
Helm 測試
Helm 的測試分成幾個面向,分別是
- Helm Chart 的撰寫內容是否正確
- Helm Chart 搭配 Config 後是否安裝會失敗
其中(2)這點不是什麼大問題,因為我們可以先透過 helm template
的方式讓它渲染出最後產生的 Kubernetes Yaml 檔案,而因為現在
是原生的 Kubernetes yaml 檔案了,所以就可以使用上述的三個工具來進行測試。
而 (1) 的部分主要會牽扯到 Helm 本身的資料夾跟架構,這邊我們可以使用原生的工具 helm lint
來進行或是透過 helm install --dry-run
的方式來嘗試裝裝看,一個簡單的範例如下
1 | $ helm create nginx |
我們透過 helm 指令創建了一個基本範例的結構,這時候用 helm lint 是沒有任何問題的,然後我們嘗試修改 template 裡面的內容,譬如 針對 go template 的格式進行一些修改,讓其錯誤。
1 | $ echo "{}" >> templates/deployment.yaml |
上述只是一個範例,有興趣的都可以到 Helm 官網去看更多關於 Helm lint 的討論與用法。
結論
本篇介紹了很多關於 Yaml 相關的工具,每個工具都會有自己的極限,沒有一個工具可以檢查出所有問題,這部分就是需要花時間去評估看看每個工具,看看哪些工具適合自己團隊,是否方便導入以及功能是否滿足
除了上述之外還有很多工具,譬如 kube-score, config-lint..等,有興趣的人都可以搜尋來玩耍看看
個人資訊
我目前於 Hiskio 平台上面有開設 Kubernetes 相關課程,歡迎有興趣的人參考並分享,裡面有我從底層到實戰中對於 Kubernetes 的各種想法
組合包
https://hiskio.com/packages/7ey2vdnyN
疑難雜症除錯篇
https://hiskio.com/courses/440/about?promo_code=LG28Q5G
單堂(CI/CD)
https://hiskio.com/courses/385?promo_code=13K49YE&p=blog1
基礎概念
https://hiskio.com/courses/349?promo_code=13LY5RE
另外,歡迎按讚加入我個人的粉絲專頁,裡面會定期分享各式各樣的文章,有的是翻譯文章,也有部分是原創文章,主要會聚焦於 CNCF 領域
https://www.facebook.com/technologynoteniu
如果有使用 Telegram 的也可以訂閱下列頻道來,裡面我會定期推播通知各類文章
https://t.me/technologynote
你的捐款將給予我文章成長的動力