本文次要介绍云联壹云平台如何适配ARM,并运行在ARM CPU架构的机器上。

背景介绍

1、平台服务运行架构

云联壹云平台采纳容器化,分布式的架构运行在 Kubernetes(K8s)之上。上面是平台服务运行的架构图:

在多个节点之上,咱们会构建Kubernetes的集群 ,它是一个容器治理的平台。

在Kubernetes的平台之上,后端服务都是容器化的,是以容器的形式去分布式运行。

通过K8s去做调度的治理,而后将服务主动地打散到多个节点上运行,总结两点是服务容器化,并依附K8s来提供容器分布式运行的环境。

另外,底层的节点是有类型的,管制层面的服务运行在管制节点,平台内置了一个公有云,提供了残缺的公有云性能。

若要应用私用云这个性能,则还须要一些计算节点,计算节点上会跑虚拟化相干的软件,提供公有云虚拟化的性能,总结来说就是计算节点运行公有云的虚拟机。

2、CPU架构简介

大家相熟的服务器或者台式机都是X86架构的CPU,X86架构的CPU特点是性能高,并且软件的兼容性很好。

大家平时工作中应用的大部分是英特尔等提供的X86架构的CPU,对于英特尔和AMD大家都不生疏,这两家厂商专门生产X86架构CPU。

另外X86 64位这种架构的CPU存在别名,例如x86_64或者amd64都代表X86架构的64位CPU。

与X86不同的是还有另一种称为ARM的架构,这是本文的主题,那么ARM架构的CPU和X86架构的CPU相比有何不同?

它的制作老本更低,ARM架构的芯片的功耗也很低,代表性的厂商和使用者是苹果和华为。

苹果将生产的ARM芯片用到笔记本或IMAC上,ARM架构的CPU越来越遍及。

国内的华为会生产基于ARM架构的服务器,64位ARM架构CPU也有别名,例如arm64、aarch64,这两种叫法表白同一个意思。

3、为什么适配ARM

因为ARM的CPU遍及是大环境下的发展趋势,例如在国内上,苹果将ARM架构的CPU投入到笔记本和台式机上,在国产化方面,国内有鲲鹏和飞腾CPU,国产的基于ARM架构的服务器,当初市场上支流的是鲲鹏和飞腾。 在国产化上,应用ARM架构也是一个趋势。

另外是适配了ARM架构可能晋升产品的竞争力,竞争力体现在可能反对治理基于ARM64位和X86_64架构的虚拟化混合部署。

这种混合部署的意思是能够同时把服务运行在ARM和X86的服务器上,同时运行各自的虚拟化,能够通过咱们平台对立部署和治理。

如何适配ARM64?

1、须要解决的关键问题

第一个方面是怎么把服务运行在64位的ARM架构上?

还有一方面是因为咱们内置了一个公有云,下层的公有云业务如何反对64位的ARM架构?

通过架构图能够理解到服务是容器化运行在K8s之上的,再由K8s帮咱们将服务分布式地运行在各个节点上,所以第一步是要部署异构CPU架构的K8s集群,异构CPU架构的意思是K8s集群要运行在X86和ARM架构的机器上。

具体而言就是要抉择一个反对ARM架构的Linux的发行版。

K8s节点上的操作系统是Linux,首先要抉择反对ARM架构的Linux操作系统,操作系统同时可能装置K8s必要的软件(比方docker-ce、kubelet等)

当咱们把K8s集群给部署起来之后,就要将不同架构的容器镜像对立制作进去。

对立容器镜像的意思是一个容器镜像中要蕴含X86和ARM架构,相当于同一个镜像名称中有两种架构的镜像。

第二个大的方面是下层公有云业务怎么反对ARM64。

次要是分为两个问题,第一个问题是要反对ARM的虚拟机镜像,同时下层的公有云业务可能标记宿主机,宿主机就是运行虚拟机的服务器。

要可能标记这种宿主机是什么架构,同时要在这个宿主机上运行ARM的虚拟化软件。

平台应用的虚拟化软件基于qemu/kvm,网络方面依赖openvswitch组件,要求这些组件也要可能在ARM架构上运行。

这就是要介绍的一些关键问题,解决好这些关键问题,不论是底层的业务还是下层的公有云业务,都能在ARM上运行。

2、Linux发行版抉择

咱们抉择的发行版是Debian 10(开源)和统信UOS(国产零碎)。

抉择这两个发行版的第一个起因是客户业务上要求在ARM64服务器上运行“统信UOS”。

要适配的话也是首先适配国产统信UOS,在适配过程中,UOS中的内核和打包工具与Debian基本一致。

适配UOS之后,发现其工作基本相同,所以又抉择了Debian 10(开源)进行适配。

如此无论是对于开源用户还是其余客户,如果不抉择UOS,也能够抉择Debian 10的发型版运行此平台,Debian系列对ARM64位的反对很好,

Debian发行版的官网软件仓库中曾经制作好了很多ARM64的包,如果要装置docker和K8s的软件包,Debian中曾经做好,间接下载安装即可。

为什么不在ARM架构下面再抉择CentOS7发行版?

起因在于CentOS7官网行将进行保护,所以抉择了Debian系列的发行版。

3、统信UOS适配认证

对统信UOS适配过后,通过其官网测试,为咱们颁发了认证证书。

4、对立软件依赖—包管理工具

抉择好发行版后?怎么对立装置这些软件?

咱们可能应用不同发行版的包管理工具去装置雷同的软件,例如在X86的CentOS上装置docker和K8s这些包时调用yum,在Debian上调用apt install 等同样的包名即可。

上游的软件仓库中曾经把包做好,只需间接装置,软件间接下载即可应用。

在底层软件方面,ARM和X86的治理,只有发行版是支流的,验证Debian和X86的包没有区别,曾经将底层的包装置部署好。

5、部署kubernetes集群

另外一个话题是部署kubernetes集群,如何在ARM上部署K8s集群?

首先,咱们写了名称为ocboot的部署工具,它的底层原理是调用ansible实现部署ARM64+X86_64的多节点Kubernetes,这个截图的意思是通过这个工具部署过后的混布的就是异构的K8s集群的节点的资源。

从截图中能够发现,第一个节点是centos-x86-64,发行版名称是centos7,内核是3.10,K8s会通过打标签的形式标记这个节点,它是amd64。

amd64代表它是X86架构的一个节点,另外一个节点是uos-arm64,它的发行版是uos,内核是4.19.0-arm64的内核。K8s会通过打标签标记它是ARM64的一个节点,这就代表是一个同时基于X86和ARM64的节点构建的K8s集群。

应用K8s集群的益处是K8s 集群提供了不同CPU架构节点的对立治理,通过一个API可能把所有架构的节点拿到,可能基于这些节点提供容器服务的运行。
6、服务对立镜像运行
部署好K8s集群之后如何运行云联壹云的服务?

例如K8s中有daemonset的资源,这种资源示意在每一个K8s节点上都会运行pod容器。

它要求在这个资源中写好服务容器镜像的地址,即红框中所标记的。

只有依照这样的格局写,写好之后创立到k8s集群中,K8s就会将提供的镜像以容器化的形式运行到各个节点上。

从图中能够理解到,在centos X86的节点上和UOS ARM架构的节点上都同时运行host的服务,这是如何做到的呢?

这就要求对立服务的出项,要在host:v3.6.10的镜像中蕴含两种架构的镜像格局,它的底层同时将X86和ARM的格局捆绑到一起,在理论运行过程中,在不同的架构的节点上,docker会依据以后节点的架构拉取镜像中不同架构的格局的镜像运行。

7、公有云业务如何反对ARM64?

  • 宿主机 列表

在运行虚拟机的宿主机下来标记宿主机的架构类别,云平台的前端界面能够看到,给宿主机列表下面加了CPU架构的属性,ARM架构服务器的宿主机,会给它一个称为aarch64的CPU架构来标记,X86则会标记x86_64的CPU架构属性 。

若要运行虚拟机,则须要先提供虚拟机的镜像,咱们在虚拟机的镜像中也应用了CPU架构的属性来标记虚拟机镜像是X86架构还是ARM 64位的架构。

提供宿主机和虚构镜像过后,即可创立虚拟机,在创立虚拟机的表单中,会让用户去抉择是要创立ARM架构的虚拟机还是X86架构的虚拟机。

创立好虚拟机过后,平台负责将这些虚拟机依据所提供的CPU架构调入到不同架构的宿主机上,这是一个在平台同时创立的X86和ARM的虚拟机列表界面。

在此列表中通过CPU架构的字段理解虚拟机的架构类型,这就是在公有云这个业务做的革新并反对ARM64位架构。

技术细节
如何制作对立的容器镜像(反对X86_64和ARM64)?

  • docker buildx计划

docker原生反对的多架构镜像制作计划

  • 应用穿插编译而后打包

别离编译打包出x86_64和arm64的容器镜像,而后捆绑到一起。

1、对立容器镜像—docker buildx

  • 编写实用buildx的 Dockerfile

docker通过读取file中的语句,制作出镜像,Dockerfile先基于一个称golang:alpine的镜像,把它作为一个build容器。

同时,其中会传两个参数,别离是TARGETPLATFORM 和BUILDPLATFORM。

TARGETPLATFORM的意思是制作出的镜像架构,BUILDPLATFORM 是以后制作镜像机器的架构 ,这里RUN的命令会读取这两个环境变量,而后将他们的值打到名称为log的文件中。

第二步,FROM alpine 的语句是找到alpine这个镜像,基于这个容器镜像将build容器中的log文件拷贝进去。

应用buildx 同时制作x86_64和arm64架构的镜像。

-t的意思是build出的镜像的名称,push代表要push到docker镜像仓库中,platform参数代表制作进去的镜像同时代表两个架构,别离是x86 64位架构和arm64位架构。

运行此命令,docker buildx就会基于dockerfile的步骤,同时拉取ARM架构和X86架构的根底镜像。

基于根底镜像运行外面雷同的语句,例如红色标记的中央,它同时运行两个架构的指令,相当于同时拉取了amd64和arm64的alpine 镜像。

去build时,同一条build语句也在amd64和arm64这两个架构上运行。

通过build出的后果即可发现RUN的这个命令,是在X86架构的机器上制作的镜像build出的后果,例如第一条是build出了arm64的镜像,第二条是build出X86 64位的镜像。

build完镜像过后,把它push到镜像仓库中,即可通过docker manifest 这个命令去查问这个镜像外面的一些元数据,查看方才制作的镜像,manifest 中有两种格局,第一种格局是amd64,示意X86_64架构,第二种格局是ARM64,是可能运行在ARM上的镜像,这些都是buildx做好的,咱们只须要写dockerfile。

它默认帮咱们制作进去一个多架构的容器镜像。

buildx 如何在 x86_64的机器上制作arm64的镜像?

通过binfmt_misc模仿arm64硬件的用户空间,而后调用qemu的用户态模式编译程序。

最终后果是调用buildx的命令过后,编译过程后,会运行qemu-aarch64 工具,相当于模拟出arm64的硬件环境,而后调用ARM的工具做编译,截图中,后端服务都是用Golang编写,都须要做编译。

2、对立容器镜像-穿插编译

穿插编译:间接在x86_64开发机上编译arm64二进制。

图中的Go代码,其中写了main的函数,在X86的机器上间接编译,调go build工具,而后把它编译成一个叫做t_x86_64的二进制可执行文件。

而后在操作系统上调用file去看可执行文件的内容,通过信息可知这是一个64位的可执行文件,并且是x86-64架构。

Go中的穿插变异很简略,指定GOARCH的环境变量,而后把它设置为arm64,而后再运行雷同的go  build的命令,即可应用穿插编译,编译出ARM可执行的文件。 

编译进去之后,再去看t_arm64的二进制文件,即可发现它也是64位的执行文件,但其架构为ARM,此即为穿插编译的简略的示例。 相当于在X86的开发机上应用穿插编译工具编译出ARM执行文件。

3、如何将不同架构镜像打包

将穿插编译后的x86_64和arm64容器镜像组合到一起。

例如曾经有名称为service:v1_x86_64的容器镜像和service:v1_arm64的镜像,如何将其组合为service:v1 = service:v1_x86_64 + service:v1_arm64 的容器镜像?

首先创立 service:v1 的 manifest 镜像,而后将x86_64的镜像和arm64的镜像捆绑到一起,而后调用docker manifest标记镜像 service:v1_arm64 的架构为 arm64 ,标记镜像 service:v1_x86_64 的架构为 amd64 ,再调用docker push将service:v1 镜像上传到镜像仓库即可,如此制作进去的一个镜像中即可蕴含两个架构。

4、buildx与穿插编译打包比照

如果应用buildx+binfmt_misc的形式,速度很慢,在本地x86机器上运行,复杂度很低。

如有ARM服务器,能够告诉buildx ssh到近程的ARM机器,会把编译arm的局部交给远端的ARM机器,速度很快,环境要求为本地x86+远端arm64机器,因为个别不会给每个开发人员提供ARM服务器,所以未采纳此种形式。

最初是穿插编译+manifest打包的形式,速度很快,因为编译器中做了穿插编译的优化,可能间接编译出ARM架构的二进制,此种形式只依赖本地的开发环境,此种形式复杂度较高。

现阶段应用的形式是同时应用buildx + binfmt_misc和穿插编译 + manifest 打包的形式。

前端不须要编译的服务:应用buildx + binfmt_misc后端编译型的服务:应用穿插编译而后打包

5、公有云治理—虚拟化软件

公有云下层业务反对X86和ARM虚拟化混合治理,要做混布反对,首先要让虚拟化软件可能运行在ARM架构上,次要运行虚拟机的软件是通过名称为qemu的虚拟化软件工具,通过穿插编译的形式运行在ARM架构上。

在做编译之前,只须要配置好指标的架构是aarch64即可。

qemu在理论生产应用中要联合KVM虚拟化减速工具,debian 10 4.19.0 aarch64 内核原生反对。

openvswitch 网络虚构交换机能够间接在debian 中装置应用。

6、公有云治理—业务反对

例如在宿主机的资源中加上属性,标记宿主机是ARM架构还是X86架构,还有在平台虚拟机镜像中加上架构的属性,同时调度器的服务也要做革新,保障用户创立一台ARM架构的虚拟机,可能调度到ARM的宿主机上。

大家能够依据图中列出的 PR具体地址理解业务反对详情。