本文发布已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已过时。
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 技术的使用和优化方面拥有丰富的经验。 最近,我们尝试为 Kubernetes 适配 MIPS 架构平台,并在此过程中取得了新的进展。 该团队完成了 Kubernetes 和相关组件的迁移和适配,不仅构建了一个稳定且高可用的 MIPS 集群,还完成了 Kubernetes v1.16.2 的一致性测试。
图 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 和 MIPS 架构上 E2E 测试镜像的 E2E 镜像脚本。
成功构建上述组件后,我们使用 kubespray 和 kubeadm 等工具来完成 kubernetes 集群的构建。
名称 | 版本 | MIPS 仓库 |
---|---|---|
MIPS 上的 golang | 1.12.5 | - |
MIPS 上的 docker-ce | 18.09.8 | - |
MIPS 上 CKE 的 metrics-server | 0.3.2 | registry.inspurcloud.cn/library/cke/kubernetes/metrics-server-mips64el:v0.3.2 |
MIPS 上 CKE 的 etcd | 3.2.26 | registry.inspurcloud.cn/library/cke/etcd/etcd-mips64el:v3.2.26 |
MIPS 上 CKE 的 pause | 3.1 | registry.inspurcloud.cn/library/cke/kubernetes/pause-mips64el:3.1 |
MIPS 上 CKE 的 hyperkube | 1.14.3 | registry.inspurcloud.cn/library/cke/kubernetes/hyperkube-mips64el:v1.14.3 |
MIPS 上 CKE 的 coredns | 1.6.5 | registry.inspurcloud.cn/library/cke/kubernetes/coredns-mips64el:v1.6.5 |
MIPS 上 CKE 的 calico | 3.8.0 | registry.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 的云容器引擎
图 2 K8S-MIPS 集群组件
图 3 CPU 架构
图 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-apache
、redis
和 perl
。
经过漫长的镜像构建过程后,我们完成了大约四十多个镜像,包括测试 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
(镜像自发布以来已更改 - 之前使用的是 registry "k8s.gcr.io")registry.k8s.io/pause:3.1
(镜像自发布以来已更改 - 之前使用的是 registry "k8s.gcr.io")
最后,我们运行了测试并得到了测试结果,包括 e2e.log
,这表明所有测试用例都通过了。 此外,我们将测试结果作为 拉取请求提交给了 k8s-conformance。
图 5 一致性测试结果的拉取请求
下一步
我们手动构建了 kubernetes-MIPS 组件并完成了符合性测试,这验证了 Kubernetes 在 MIPS 平台上的可行性,并大大增强了我们对 Kubernetes 推广 MIPS 架构支持的信心。
未来,我们计划积极地将我们的经验和成果贡献给社区,提交 PR 和 MIPS 的补丁。 我们希望社区中更多的开发人员和公司加入我们,共同推广 MIPS 上的 Kubernetes。
贡献计划:
- 贡献 MIPS 的 e2e 测试镜像的源代码
- 贡献 MIPS 的 hyperkube 源代码
- 贡献 MIPS 的 kubeadm 等部署工具的源代码