本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

MIPS 上的 Kubernetes

背景

MIPS(無互鎖流水線級微處理器)是一種精簡指令集計算機 (RISC) 指令集架構 (ISA),於 1981 年出現並由 MIPS Technologies 開發。現在 MIPS 架構廣泛應用於許多電子產品中。

Kubernetes 已官方支援多種 CPU 架構,如 x86、arm/arm64、ppc64le、s390x。然而,遺憾的是 Kubernetes 不支援 MIPS。隨著雲原生技術的廣泛應用,MIPS 架構下的使用者也迫切需要 MIPS 上的 Kubernetes。

成就

多年來,為了豐富開源社群的生態,我們一直致力於調整 MIPS 架構以適應 Kubernetes 的使用場景。隨著持續的迭代最佳化和 MIPS CPU 效能的提升,我們在 mips64el 平臺上取得了一些突破性進展。

多年來,我們積極參與 Kubernetes 社群,在 Kubernetes 技術的使用和最佳化方面積累了豐富的經驗。最近,我們嘗試將 MIPS 架構平臺適配 Kubernetes,並在這一旅程中取得了新的階段。團隊已經完成了 Kubernetes 及相關元件的遷移和適配,不僅構建了一個穩定且高可用的 MIPS 叢集,還完成了 Kubernetes v1.16.2 的一致性測試。

Kubernetes on MIPS

圖 1 MIPS 上的 Kubernetes

K8S-MIPS 元件構建

幾乎所有與 Kubernetes 相關的雲原生元件都沒有提供 MIPS 版本的安裝包或映象。在 MIPS 平臺上部署 Kubernetes 的先決條件是在 mips64el 平臺上編譯和構建所有必需的元件。這些元件包括:

  • golang
  • docker-ce
  • hyperkube
  • pause
  • etcd
  • calico
  • coredns
  • metrics-server

得益於 Golang 的出色設計及其對 MIPS 平臺的良好支援,上述雲原生元件的編譯過程大大簡化。首先,我們在 mips64el 平臺上編譯了最新穩定版的 Golang,然後我們使用原始碼編譯了大部分上述元件。

在編譯過程中,我們不可避免地遇到了許多平臺相容性問題,例如 Golang 系統呼叫相容性問題 (syscall)、syscall.Stat_t 從 uint32 到 uint64 的型別轉換、EpollEvent 的補丁等等。

為了構建 K8S-MIPS 元件,我們使用了交叉編譯技術。我們的過程涉及整合 QEMU 工具來翻譯 MIPS CPU 指令,並修改 Kubernetes 的構建指令碼以及 Kubernetes、Hyperkube 和 E2E 測試映象在 MIPS 架構上的 E2E 映象指令碼。

成功構建上述元件後,我們使用 kubespray 和 kubeadm 等工具完成 kubernetes 叢集的構建。

名稱版本MIPS 倉庫
MIPS 上的 golang1.12.5-
MIPS 上的 docker-ce18.09.8-
CKE 在 MIPS 上的 metrics-server0.3.2registry.inspurcloud.cn/library/cke/kubernetes/metrics-server-mips64el:v0.3.2
CKE 在 MIPS 上的 etcd3.2.26registry.inspurcloud.cn/library/cke/etcd/etcd-mips64el:v3.2.26
CKE 在 MIPS 上的 pause3.1registry.inspurcloud.cn/library/cke/kubernetes/pause-mips64el:3.1
CKE 在 MIPS 上的 hyperkube1.14.3registry.inspurcloud.cn/library/cke/kubernetes/hyperkube-mips64el:v1.14.3
CKE 在 MIPS 上的 coredns1.6.5registry.inspurcloud.cn/library/cke/kubernetes/coredns-mips64el:v1.6.5
CKE 在 MIPS 上的 calico3.8.0registry.inspurcloud.cn/library/cke/calico/cni-mips64el:v3.8.0 registry.inspurcloud.cn/library/cke/calico/ctl-mips64el:v3.8.0 registry.inspurcloud.cn/library/cke/calico/node-mips64el:v3.8.0 registry.inspurcloud.cn/library/cke/calico/kube-controllers-mips64el:v3.8.0

注意:CKE 是浪潮推出的一款基於 Kubernetes 的雲容器引擎

K8S-MIPS Cluster Components

圖 2 K8S-MIPS 叢集元件

CPU Architecture

圖 3 CPU 架構

Cluster Node Information

圖 4 叢集節點資訊

執行 K8S 一致性測試

驗證 K8S-MIPS 叢集穩定性和可用性的最直接方法是執行 Kubernetes 一致性測試

一致性測試是一個獨立的容器,用於啟動 Kubernetes 端到端測試以進行一致性測試。

一旦測試啟動,它會啟動多個 Pod 來進行各種端到端測試。這些 Pod 使用的映象原始碼主要來自 kubernetes/test/images,構建好的映象位於 gcr.io/kubernetes-e2e-test-images。由於倉庫中沒有 MIPS 映象,我們必須首先構建所有必需的映象才能執行測試。

構建測試所需映象

第一步是找到測試所需的所有映象。我們可以執行 sonobuoy images-p e2e 命令來列出所有映象,或者我們可以在 /test/utils/image/manifest.go 中找到這些映象。儘管 Kubernetes 官方提供了完整的 Makefile 和 shell 指令碼來構建測試映象,但仍然存在一些與架構相關的問題尚未解決,例如基礎映象和依賴項的不相容性。因此,我們無法透過直接執行這些命令來構建 mips64el 架構映象。

大多數測試映象都是用 golang 編寫的,然後編譯成二進位制檔案並基於相應的 Dockerfile 構建成 Docker 映象。這些映象很容易構建。但請注意,大多數映象都使用 alpine 作為其基礎映象,目前 alpine 官方不支援 mips64el 架構。目前,我們無法制作 mips64el 版本的 alpine,因此我們必須將 alpine 替換為現有的 MIPS 映象,例如 Debian-stretch、fedora、ubuntu。替換基礎映象還需要替換安裝依賴項的命令,甚至這些依賴項的版本。

有些映象不在 kubernetes/test/images 中,例如 gcr.io/google-samples/gb-frontend:v6。雖然我們在倉庫 github.com/GoogleCloudPlatform/kubernetes-engine-samples 中找到了原始碼,但沒有明確的文件說明這些映象的本地位置。我們很快遇到了新問題:要構建這些 Google 示例映象,我們必須構建它所使用的基礎映象,甚至基礎映象的基礎映象,例如 php:5-apacheredisperl

經過漫長的映象構建過程,我們最終完成了大約四十個映象,包括測試 Pod 使用的映象和基礎映象。在執行測試之前的最後一步是將所有這些映象放置在叢集中的每個節點上,並確保 Pod 映象拉取策略為 imagePullPolicy: ifNotPresent

以下是我們構建的一些映象:

  • docker.io/library/busybox:1.29
  • docker.io/library/nginx:1.14-alpine
  • docker.io/library/nginx:1.15-alpine
  • docker.io/library/perl:5.26
  • docker.io/library/httpd:2.4.38-alpine
  • docker.io/library/redis:5.0.5-alpine
  • gcr.io/google-containers/conformance:v1.16.2
  • gcr.io/google-containers/hyperkube:v1.16.2
  • gcr.io/google-samples/gb-frontend:v6
  • gcr.io/kubernetes-e2e-test-images/agnhost:2.6
  • gcr.io/kubernetes-e2e-test-images/apparmor-loader:1.0
  • gcr.io/kubernetes-e2e-test-images/dnsutils:1.1
  • gcr.io/kubernetes-e2e-test-images/echoserver:2.2
  • gcr.io/kubernetes-e2e-test-images/ipc-utils:1.0
  • gcr.io/kubernetes-e2e-test-images/jessie-dnsutils:1.0
  • gcr.io/kubernetes-e2e-test-images/kitten:1.0
  • gcr.io/kubernetes-e2e-test-images/metadata-concealment:1.2
  • gcr.io/kubernetes-e2e-test-images/mounttest-user:1.0
  • gcr.io/kubernetes-e2e-test-images/mounttest:1.0
  • gcr.io/kubernetes-e2e-test-images/nautilus:1.0
  • gcr.io/kubernetes-e2e-test-images/nonewprivs:1.0
  • gcr.io/kubernetes-e2e-test-images/nonroot:1.0
  • gcr.io/kubernetes-e2e-test-images/resource-consumer-controller:1.0
  • gcr.io/kubernetes-e2e-test-images/resource-consumer:1.5
  • gcr.io/kubernetes-e2e-test-images/sample-apiserver:1.10
  • gcr.io/kubernetes-e2e-test-images/test-webserver:1.0
  • gcr.io/kubernetes-e2e-test-images/volume/gluster:1.0
  • gcr.io/kubernetes-e2e-test-images/volume/iscsi:2.0
  • gcr.io/kubernetes-e2e-test-images/volume/nfs:1.0
  • gcr.io/kubernetes-e2e-test-images/volume/rbd:1.0.1
  • registry.k8s.io/etcd:3.3.15(釋出後鏡像已更改 - 之前使用登錄檔 "k8s.gcr.io")
  • registry.k8s.io/pause:3.1(釋出後鏡像已更改 - 之前使用登錄檔 "k8s.gcr.io")

最後,我們運行了測試並獲得了測試結果,包括 e2e.log,其中顯示所有測試用例均透過。此外,我們還將測試結果作為 拉取請求 提交到 k8s-conformance

Pull request for conformance test results

圖 5 一致性測試結果的拉取請求

接下來

我們手動構建了 kubernetes-MIPS 元件並完成了符合性測試,這驗證了 Kubernetes 在 MIPS 平臺上的可行性,並大大增強了我們推動 Kubernetes 支援 MIPS 架構的信心。

未來,我們計劃積極向社群貢獻我們的經驗和成果,提交 PR,併為 MIPS 打補丁。我們希望社群中更多的開發者和公司加入我們,共同推動 Kubernetes 在 MIPS 上的發展。

貢獻計劃:

  • 貢獻 MIPS 的 e2e 測試映象原始碼
  • 貢獻 MIPS 的 hyperkube 原始碼
  • 貢獻 MIPS 的部署工具(如 kubeadm)原始碼