Kubernetes 一致性測試 - Sonobuoy

現今 Kubernetes 的發行版非常多(e.g. K0s、K3s、Rancher 等),以及雲端服務也有人提供 Kubernetes(e.g. GKE、AKS、EKS 等),但有沒有想過,為什麼這些社群或雲端供應商聲稱可以提供 K8s 呢?我只要自稱能提供 K8s 也可以嗎?

答案是,你必須要通過 Kubernetes 的一致性測試(Conformance Test)!

Kubernetes Conformance 是什麼?

Kubernetes Conformance 在檢查 Kubernetes 發行版是否符合規範,確保不同系統間的相容性,包含 API、網路、儲存、資源調度和安全等功能。能夠通過所有測試,才是受認證的 Kubernetes(Certified Kubernetes)。

成為 Certified Kubernetes 有什麼好處?根據 CNCF 官網介紹:

  1. 一致性:使用者希望跟任何 Kubernetes 版本操作時能保持一致。
  2. 即時更新:為了維持認證,供應商需要每年或更頻繁地提供最新版本的 Kubernetes,這樣才能確保你能始終對社群一直在努力提供最新功能。
  3. 可確認性:任何終端使用者都可以透過執行用於認證的相同開源一致性應用程式(e.g. Sonobuoy)來確認其發行版或平台仍然符合標準。

任何人都可以申請認證不用收費嗎?

非營利組織和 CNCF 會員不會收取認證費用。

如果公司不想加入 CNCF 會員但想要認證,則需要繳交加入 CNCF 會員的費用。

另外,非營利組織要認證前,必須填寫認證協議包含專案聯絡人等資訊。

詳情資訊可以查看 CNCF 官網關於 Kubernetes Conformance 的介紹:https://cncf.io/ck

Sonobuoy 介紹

Sonobuoy

Sonobuoy 是一個診斷工具,它透過執行擴充功能(包括 Kubernetes 一致性測試),以一種易於理解且無破壞性的方式,幫助你了解 Kubernetes 叢集的狀態。它是一種可自訂、可擴充且與叢集無關的方式(cluster-agnostic way)產生具有豐富資訊且清晰的叢集報告。

Sonobuoy 對 Kubernetes 資源物件和叢集節點的選擇性資料轉存,可支援下列使用案例:

  • 整合的端到端(e2e)一致性測試
  • 工作負載偵錯
  • 透過可擴充元件進行自訂資料收集

專案網站:https://sonobuoy.io/
GitHub:https://github.com/vmware-tanzu/sonobuoy

接下來我們可以借用 Sonobuoy 的擴充功能「E2E & Conformance」來對我們 Kubernetes 叢集做一致性測試吧!

Sonobuoy 使用:以 Kubespray v2.26.0 為例

2024.09.06 正好 Kubespray 釋出 v2.26.0 版本,對應 Kubernetes v1.30.4 版本,我們就使用這版本做示範,並把結果上傳到 cncf/k8s-conformance 吧!

Demo 環境

筆者使用 MacBook Pro M2 Max 作為示範,後面下載程式或映像檔都要改成 arm64,如果是 Intel 架構請自行修改為 amd64 即可。

  • MacBook Pro 16” 2023 (M2 Max)
  • Host OS: macOS Sonoma 14.6.1
  • Guest OS: Ubuntu 24.04
  • Python 3.12.5 (Virtualenv)
  • Parallels Desktop Pro 19.4.1 (54985)
  • Vagrant 2.4.1

如果想要隔離 Python 環境,推薦使用 Virtualenv。

建立環境

首先,下載 Kubespray v2.26.0 版本:

1
2
3
git clone https://github.com/kubernetes-sigs/kubespray.git
cd kubespray
git checkout v2.26.0

這裡假設你們已經設定好 Python,接下來就是安裝 Kubespray 的相依性套件:

1
pip install -r requirements.txt

Kubespray 有提供 Vagrant 作為測試,根據 Kubespray 文件寫上設定資訊:

1
2
3
4
5
6
7
8
9
10
11
12
mkdir -p vagrant
cat > ./vagrant/config.rb <<__EOF__
$instance_name_prefix = "kube"
$vm_cpus = 4
$vm_memory = 4096
$num_instances = 3
$os = "ubuntu2404"
$subnet = "10.2.20"
$inventory = "inventory/k8s-conformance"
$network_plugin = "calico"
__EOF__
mkdir -p inventory/k8s-conformance

接下來只要下 vagrant up 就可以啟動機器,並利用 Kubespray 安裝 K8s。

筆者這裡省略 Vagrant Provider 設定,請參考網路上關於 Vagrant Provider 串接方式。

1
vagrant up

建立完成後,用 vagrant 進入 kube-1 機器後,切換到 root 使用者:

1
2
vagrant ssh kube-1
sudo -i

kubectl get node 測試是否能使用:

1
2
3
4
5
root@kube-1:~# kubectl get node
NAME STATUS ROLES AGE VERSION
kube-1 Ready control-plane 19h v1.30.4
kube-2 Ready control-plane 19h v1.30.4
kube-3 Ready <none> 19h v1.30.4

看起來沒問題了,接下來就安裝 Sonobuoy 開始測試。

安裝 Sonobuoy 執行測試

下載 Sonobuoy 套件 Arm 版本,並且解壓縮:

1
2
curl -sfL -O https://github.com/vmware-tanzu/sonobuoy/releases/download/v0.57.2/sonobuoy_0.57.2_linux_arm64.tar.gz
tar -xzvf sonobuoy_0.57.2_linux_arm64.tar.gz

確認沒問題,就可以用 sonobuoy run 開始測試,--mode 設定為 certified-conformance 用於一致性驗證。

如果是 Intel 版本,--systemd-logs-image 要改成 sonobuoy/systemd-logs(結尾不帶架構字串)。

1
2
3
4
5
6
export SONOBUOY_IMAGE_VERSION=v0.57
export SONOBUOY_LOGS_IMAGE_VERSION=v0.4
./sonobuoy run --mode=certified-conformance \
--sonobuoy-image=sonobuoy/sonobuoy:$SONOBUOY_IMAGE_VERSION \
--systemd-logs-image=sonobuoy/systemd-logs-arm64:$SONOBUOY_LOGS_IMAGE_VERSION \
--wait

接下來就進入漫長等待,之前借用 CNTUG Infra Labs 開 16 vCPUs 和 16G RAM + VirtualBox 大約跑了 2 小時,可以考慮先睡一覺再起來看結果。

等待過程你也可以開另一個視窗用 sudo kubectl get pod -A -w 看看正在測試什麼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
vagrant@kube-1:~$ sudo kubectl get pod -A -w
NAMESPACE NAME READY STATUS RESTARTS AGE
cronjob-5525 concurrent-28764978-rddh8 1/1 Running 0 35s
kube-system calico-kube-controllers-b5f8f6849-5lb4z 1/1 Running 0 20m
kube-system calico-node-bxmn5 1/1 Running 0 20m
kube-system calico-node-dj4gm 1/1 Running 0 20m
kube-system calico-node-vlpkl 1/1 Running 0 20m
kube-system coredns-776bb9db5d-jdwqm 1/1 Running 0 20m
kube-system coredns-776bb9db5d-n7jp5 1/1 Running 0 20m
kube-system dns-autoscaler-6ffb84bd6-gwwpb 1/1 Running 0 20m
kube-system kube-apiserver-kube-1 1/1 Running 0 21m
kube-system kube-apiserver-kube-2 1/1 Running 0 21m
kube-system kube-controller-manager-kube-1 1/1 Running 1 21m
kube-system kube-controller-manager-kube-2 1/1 Running 1 21m
kube-system kube-proxy-2mprz 1/1 Running 0 21m
kube-system kube-proxy-7h4c6 1/1 Running 0 21m
kube-system kube-proxy-8mdcd 1/1 Running 0 21m
kube-system kube-scheduler-kube-1 1/1 Running 1 21m
kube-system kube-scheduler-kube-2 1/1 Running 1 21m
kube-system nginx-proxy-kube-3 1/1 Running 0 20m
kube-system nodelocaldns-9mkb8 1/1 Running 0 20m
kube-system nodelocaldns-hh8tw 1/1 Running 0 20m
kube-system nodelocaldns-wf9m4 1/1 Running 0 20m
sonobuoy sonobuoy 1/1 Running 0 10m
sonobuoy sonobuoy-e2e-job-7653863eaff14dfe 2/2 Running 0 10m
sonobuoy sonobuoy-systemd-logs-daemon-set-22d198ef6e024c5d-2fbhr 2/2 Running 0 10m
sonobuoy sonobuoy-systemd-logs-daemon-set-22d198ef6e024c5d-nf5sq 2/2 Running 0 10m
sonobuoy sonobuoy-systemd-logs-daemon-set-22d198ef6e024c5d-sbdcw 2/2 Running 0 10m
cronjob-5525 concurrent-28764979-bkt42 0/1 Pending 0 0s
cronjob-5525 concurrent-28764979-bkt42 0/1 Pending 0 0s
cronjob-5525 concurrent-28764979-bkt42 0/1 ContainerCreating 0 0s
cronjob-5525 concurrent-28764979-bkt42 0/1 ContainerCreating 0 0s
cronjob-5525 concurrent-28764978-rddh8 1/1 Terminating 0 60s
cronjob-5525 concurrent-28764979-bkt42 0/1 Terminating 0 0s
cronjob-5525 concurrent-28764978-rddh8 1/1 Terminating 0 60s
var-expansion-681 var-expansion-bb921fe1-aac4-4040-9659-f0c893bfb41d 0/1 Pending 0 0s
var-expansion-681 var-expansion-bb921fe1-aac4-4040-9659-f0c893bfb41d 0/1 Pending 0 0s
var-expansion-681 var-expansion-bb921fe1-aac4-4040-9659-f0c893bfb41d 0/1 ContainerCreating 0 0s
cronjob-5525 concurrent-28764979-bkt42 0/1 Terminating 0 0s
var-expansion-681 var-expansion-bb921fe1-aac4-4040-9659-f0c893bfb41d 0/1 ContainerCreating 0 0s
cronjob-5525 concurrent-28764979-bkt42 1/1 Terminating 0 1s
var-expansion-681 var-expansion-bb921fe1-aac4-4040-9659-f0c893bfb41d 0/1 CreateContainerConfigError 0 1s
var-expansion-681 var-expansion-bb921fe1-aac4-4040-9659-f0c893bfb41d 0/1 Terminating 0 2s
var-expansion-681 var-expansion-bb921fe1-aac4-4040-9659-f0c893bfb41d 0/1 Terminating 0 3s
var-expansion-681 var-expansion-bb921fe1-aac4-4040-9659-f0c893bfb41d 0/1 Terminating 0 3s

或者可以用 sonobuoy status 看執行狀態。但筆者的進度條似乎是爛的,不過不影響。

1
2
3
4
5
6
root@kube-1:~# ./sonobuoy status
PLUGIN STATUS RESULT COUNT PROGRESS
e2e running 1 Passed: 0, Failed: 0, Remaining:402
systemd-logs complete 3

Sonobuoy is still running. Runs can take 60 minutes or more depending on cluster and plugin configuration.

2000 年以後......

結果跑完後就會跳出這訊息:

1
2
14:10:07 Sonobuoy has completed. Use `sonobuoy retrieve` to get results.
root@kube-1:~#

取得 Sonobuoy 測試結果

接下來就用 sonobuoy retrieve 拿取結果:

1
2
root@kube-1:~# ./sonobuoy retrieve
202409091608_sonobuoy_f07c551b-1479-42b0-8290-8bb54e8516cb.tar.gz

結果變成 tar.gz 後,複製到一般使用者資料夾,並更換擁有者權限,確保後續實體機器傳檔案成功:

1
2
3
4
5
6
root@kube-1:~# cp 202409091608_sonobuoy_f07c551b-1479-42b0-8290-8bb54e8516cb.tar.gz /home/vagrant/result.tar.gz
root@kube-1:~# exit
logout
vagrant@kube-1:~$ sudo chown vagrant:vagrant result.tar.gz
vagrant@kube-1:~$ exit
logout

回到實體機器上,把虛擬機器 kube-1 的測試結果取出來:

1
vagrant scp kube-1:result.tar.gz .

result.tar.gz 解壓縮後,資料夾 plugins/e2e/results/global/e2e.logjunit_01.xml 就是我們需要上傳的結果啦!

可以先看一下 e2e.log 倒數幾行的內容,有沒有 Failed 情形出現,內容會大概像這樣:

1
2
3
4
5
6
Ran 402 of 7199 Specs in 6126.157 seconds
SUCCESS! -- 402 Passed | 0 Failed | 0 Pending | 6797 Skipped
PASS

Ginkgo ran 1 suite in 1h42m6.592562066s
Test Suite Passed

如果像上面這樣沒有問題,就可以準備上傳結果囉!

上傳結果到 GitHub

自行 forkcncf/k8s-conformance,選定驗證版本。

筆者提醒,一次 pull request(PR)只能傳一個認證版本,如果有多個版本認證,就要開多個 PR。

Kubespray v2.26.0 對應到 Kubernetes v1.30 版本,就自己在 v1.30/kubespray 開資料夾,附上前面取得的 e2e.logjunit_01.xml,因為 Kubespray 已經不是第一次上傳,只要更新 PRODUCT.yaml 版本和 README.md 敘述就好。

寫上 commit 訊息:Conformance results for v1.30/kubespray

接下來就可以開 PR 給 CNCF 了,確認 Pre-submission checklist 沒問題,按下送出吧!

Kubespray - Kuberbetes v1.30 的認證 PR 連結:https://github.com/cncf/k8s-conformance/pull/3373

等待 kubernetes-conformance-bot 來驗證,大約 1 ~ 2 小時就會看到機器人回覆。

機器人通過驗證後,就等待 CNCF 官方人員審核,時間大約 1 ~ 2 週。

結語

讀完關於 Conformance 的 blog,看得出來 SIG Architecture 小組花了不少心力維持。

這認證就像是 K8s 規格書,通過認證就可以說是 K8s 發行版,代表至少在 K8s 官方文件的內容可以在任意 K8s 發行版中使用。
同時部分發行版會有自己的獨有、延伸功能,使用者如果要轉換發行版,就要自行注意轉換問題。

以 C++ 編譯器例子來說,每個人都可以自行實作 C++ 編譯器,只要按照 C++ 的規格書實作,就是一個合格的 C++ 編譯器。
但同時 GNU GCC 會自己加入延伸功能(e.g. 引入所有標頭檔、PBDS 等),如果要改其他編譯器,就要自己注意轉換後的問題。

參考資料

  1. Certified Kubernetes Software Conformance - CNCF
  2. cncf/k8s-conformance - GitHub
  3. Spotlight on SIG Architecture: Conformance - Kubernetes
  4. The Kubernetes End-To-End Testing Plugin - Sonobuoy
  5. vmware-tanzu/sonobuoy - GitHub
  6. Kubespray v2.26.0 - GitHub

Kubernetes 一致性測試 - Sonobuoy
https://blog.yangjerry.tw/k8s-conformance-sonobuoy/
作者
Jerry Yang
發布於
2024年9月11日
許可協議