現今 Kubernetes 的發行版非常多(e.g. K0s、K3s、Rancher 等),以及雲端服務也有人提供 Kubernetes(e.g. GKE、AKS、EKS 等),但有沒有想過,為什麼這些社群或雲端供應商聲稱可以提供 K8s 呢?我只要自稱能提供 K8s 也可以嗎?
答案是,你必須要通過 Kubernetes 的一致性測試(Conformance Test)!
Kubernetes Conformance 在檢查 Kubernetes 發行版是否符合規範,確保不同系統間的相容性,包含 API、網路、儲存、資源調度和安全等功能。能夠通過所有測試,才是受認證的 Kubernetes(Certified Kubernetes)。
成為 Certified Kubernetes 有什麼好處?根據 CNCF 官網介紹:
一致性:使用者希望跟任何 Kubernetes 版本操作時能保持一致。
即時更新:為了維持認證,供應商需要每年或更頻繁地提供最新版本的 Kubernetes,這樣才能確保你能始終對社群一直在努力提供最新功能。
可確認性:任何終端使用者都可以透過執行用於認證的相同開源一致性應用程式(e.g. Sonobuoy)來確認其發行版或平台仍然符合標準。
任何人都可以申請認證不用收費嗎? 非營利組織和 CNCF 會員不會收取認證費用。
如果公司不想加入 CNCF 會員但想要認證,則需要繳交加入 CNCF 會員的費用。
另外,非營利組織要認證前,必須填寫認證協議包含專案聯絡人等資訊。
詳情資訊可以查看 CNCF 官網關於 Kubernetes Conformance 的介紹:https://cncf.io/ck
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.gitcd 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 vagrantcat > ./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 串接方式。
建立完成後,用 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 nodeNAME STATUS ROLES AGE VERSIONkube -1 Ready control-plane 19 h v1.30 .4 kube -2 Ready control-plane 19 h v1.30 .4 kube -3 Ready <none> 19 h 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.57export 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.
結果跑完後就會跳出這訊息:
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.log
和 junit_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 自行 fork 出 cncf/k8s-conformance ,選定驗證版本。
筆者提醒,一次 pull request(PR)只能傳一個認證版本 ,如果有多個版本認證,就要開多個 PR。
Kubespray v2.26.0 對應到 Kubernetes v1.30 版本,就自己在 v1.30/kubespray
開資料夾,附上前面取得的 e2e.log
和 junit_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 等),如果要改其他編譯器,就要自己注意轉換後的問題。
參考資料
Certified Kubernetes Software Conformance - CNCF
cncf/k8s-conformance - GitHub
Spotlight on SIG Architecture: Conformance - Kubernetes
The Kubernetes End-To-End Testing Plugin - Sonobuoy
vmware-tanzu/sonobuoy - GitHub
Kubespray v2.26.0 - GitHub