你的云原生应用如果想部署到Kubernetes的集群上,需要先将应用编译并打包到容器镜像里,才能被调度到集群中,因此从(源代码)source code –>(容器镜像)container image这条路径是应用上云(K8S)的必经之路。在实际生产中,有很多的方法,工具和产品都可以完成这个工作。从最基本的(Docker Build) Dockerfile,到一些和语言相关的工具(例如Google为Java语言提供的JIB),到厂家自己提供的工具(例如openshift的S2I,Uber的Maskisu,Google的Kaniko等等),以及一些CICD的工具(例如Jekins等),将这些工具集成到整个CICD的Pipeline里了。
我准备通过一系列文章来介绍VMWare最近推出来的Tanzu Build Service。在第一篇文章中,我主要是介绍Tanzu Build Service的基本概念,以及如何在vSphere with Tanzu上部署Tanzu Build Service的服务。在今后的文章中,我还会进一步介绍Tanzu Build Service的高级特性,以及如何编写和定制你自己的Tanzu Build Service组件。
1. 什么是Tanzu Build Service
早在2019年以前,VMWare在推出整个Tanzu架构概念的时候,构建(Build)服务就是非常重要的一个组件(如上图所示)。直到最近,Tanzu Build Service发布以后,这个缺失的模块才算是被补齐了,构建服务(Build),运行时服务(Run)和管理服务(Manage)是Tanzu架构最主要的三个模块。
Tanzu Build Service和其他的构建工具一样,主要职责是将应用程序的源代码转换成可运行的基于OCI标准的容器镜像。那问题来了,既然现在市面上有那么多可供选择的工具,为什么VMWare要重新造个轮子,来发布自己的构建组件呢,这个新的组件会有客户认可吗?
事实上,Tanzu Build Service是基于CNCF的一个开源项目Cloud Native Buildpacks (CNBs)包装而成。CNB最早源于Heroku的Buildpacks。Pivotal的CloudFoundry就使用了Buildpacks来构建应用。在VMware收购了Pivotal之后,将这个颇受欢迎构建工具包装成自己的产品也是顺理成章的事情。Cloud Native Buildpacks并不只有Heroku和VMWare(Pivotal)来使用,像微软的Azure,Google的云平台都用CNB作为App Engine和Cloud Functions的构建系统(https://github.com/GoogleCloudPlatform/buildpacks)。
之所以那么多大厂都使用CNB,是因为它有一些独特的特点和优势,下面的比较图表来之CNB官方网站(https://buildpacks.io/features/):
2. 在vSphere7U1 with Tanzu上 部署Tanzu Build Service
在本文中主要介绍如何在vSphere7U1 with Tanzu的产品上部署这个Tanzu Build Service。vSphere with Tanzu这个产品,原来叫vSphere with Kubernetes,如果有不太了解的请参考我之前的博客:
- vSphere with kubernetes实战之:用户访问控制(https://blogs.vmware.com/china/2020/04/27/vsphere-with-kubernetes-iam/)
- vSphere with kubernetes实战之:节点访问(https://blogs.vmware.com/china/2020/05/02/vsphere-with-kubernetes-nodeaccess/)
- vSphere with kubernetes实战之:访问镜像注册表(https://blogs.vmware.com/china/2020/05/05/vsphere-with-kubernetes-harbor/)
2.1 部署环境
vSphere with Tanzu这个产品事实上有两层Kubernetes集群,底层的Supervisor集群,和上层的Tanzu Kubernetes Grid Services集群。因为Tanzu Build Service有些组件需要较高的权限(例如部署Operator),在Supervisor集群上部署不是很简单,因此我们选择在上层的Tanzu Kubernetes Grid Services集群上部署Tanzu Build Service。
另外Tanzu Build Service在部署的时候,需要选择将一系列的容器镜像保存在哪个镜像仓库里。为了性能,一般都会选择本地私有仓库。因此我们会将和Tanzu Build Service相关的镜像部署在vSphere with Tanzu自带的镜像仓库(Harbor)里。
2.2 安装文档说明
其实Tanzu Build Service的安装部署步骤在文档(https://docs.pivotal.io/build-service/1-0/installing.html)都有。
但是按照上面文档中的步骤,在我们这个环境里却无法成功部署,从文档中也能看出,他们并没有在TKG的环境里测试过。安装不成功的主要原因是在使用Harbor私有仓库的时候,因为仓库证书通常是自签名的,因此需要配置Kubernetes环境去信任这个证书,才能从Harbor下载和上传容器镜像。其实在Tanzu Build Service有专门自动化处理这个证书信任的逻辑,能够在绝大多数的Kubernetes集群产品里起作用。不幸的是,我们的TKG的worker nodes是photonOS(VMware的Linux)操作系统,Tanzu Build Service的自动化部署程序并没有解决在photonOS下的这个证书信任的问题,因此,我们在安装部署Tanzu Build Service的之前,需要自己解决这个问题。
另外还有一些和TKG,Harbor相关的步骤也需要特地说明一下,因此,我将安装的步骤完整的列在文章中。如果需要其他不同环境的安装文档,还是建议去官方网站去查看(https://docs.pivotal.io/build-service/1-0/installing.html)都有。
2.3 安装准备工作
在这里假设已经成功安装和配置了vSphere7U1 with Tanzu以及在它上面成功部署了TKG集群,并获得了对Supervisor集群以及TKG集群的访问权限。
2.3.1 准备default StorageClass
Tanzu Build Service使用了缺省的StorageClass来生成PesistentVolumeClaims,作为构建服务的缓存,因此需要Kubernetes缺省设置了default StorageClass。但是由于在当前版本在Tanzu Kubernetes集群上设置缺省的StorageClass有点问题,因此需要在以Supervisor集群上的Namespace管理员来设置这个Tanzu Kubernetes集群的缺省StorageClass。
用Namespace管理员的身份登录到Supervisor集群上,用以下命令来设置Tanzu Kubernetes集群的缺省StorageClass (假设我们的Tanzu Kubenetes 集群的名称为“TBS-Cluster”)
$ kubectl edit tanzukubernetescluster/TBS-Cluster
在settings里面添加下面的配置,并保存 (假设我们系统使用的storageclass名为:pacific-storage-policy)
2.3.2 配置TKG信任Harbor的证书
要配置TKG各个worker nodes去信任Harbor的证书是个繁琐的过程,具体请参见:我的博客(https://blogs.vmware.com/china/2020/05/05/vsphere-with-kubernetes-harbor)中的第5节的内容。
2.3.3 预先注册的镜像仓库账号
在安装过程中需要访问Pivotal的镜像仓库,这个仓库需要账号才能访问。如果你还没有Pivotal的账号,可以马上注册一个,请访问(https://login.run.pivotal.io),点击创建账号的链接。
2.3.4 预先安装的软件工具
- 在你的桌面操作系统中安装Docker客户端
- 在你的桌面操作系统中安装Carvel(https://carvel.dev/)套件,我们在安装过程中要用到其中的三个工具(kapp,ytt,kbld).如果想要了解kbld工具的具体用法,请参考我的博客(https://blogs.vmware.com/china/2020/10/26/imageredirect/)
- 从Pivotal网站(https://network.pivotal.io/products/build-service/)下载Tanzu Build Service的客户端命令行工具kp,这会需要你刚才注册的用户账号登录。请选择正确的操作系统的链接来下载安装。
2.3.5 配置Docker登录凭证
在安装过程中需要你的Docker客户端拥有对Pivotal镜像仓库和你的Harbor私有仓库的登录凭证,也就是说在安装Tanzu Build Service之前,需要用docker login去登录这两个仓库,登录成功后,才能继续安装。
- docker login registry.pivotal.io
- docker login your/harbor/url
登录Pivotal的镜像仓库,只要使用前一步骤中注册的用户账户就行,不需要额外的配置。但由于你的Harbor私有仓库通常是自签名的证书,因此,要额外的步骤来配置你的docker客户端,来信任这个harbor证书。主要有三步:
- 下载这个harbor的证书。通过浏览器登录到Harbor界面。选择你要访问的Project或者(Namespace)转到“Repositories”页,下载这个镜像仓库的证书。
- 将这个证书复制到相应的位置。
- 在MacOS中,执行以下命令:
security add-trusted-cert -d -r trustRoot -k ~/Library/Keychains/login.keychain pathtofile/harbor-cert.crt - 在Ubuntu中执行以下命令:
cp pathtofile/harbor-cert.crt /usr/local/share/ca-certificates/
update-ca-certificates
- 在MacOS中,执行以下命令:
- 重启Docker服务: service docker restart
2.4 安装步骤
上面的准备工作完成以后就可以安装Tanzu Build Service.
- 需要从Pivotal网站上(https://network.pivotal.io/products/build-service/)下载Tanzu Build Service的安装文件,这会需要你注册的账号来登录。下载后解压到临时的目录下(或者其他你指定的目录)
$ tar xvf build-service-<version>.tar -C /tmp - 再从Pivotal网站上(https://network.pivotal.io/products/tbs-dependencies/)下载Tanzu Build Service所依赖组件的安装文件(descriptor-<version>.yaml)。
- 使用kbld命令来进行镜像重定向。进入到刚才解压的临时目录中,执行下面的命令(假设我的Harbor仓库的地址是117.233.2,我的项目名称为yu):
kbld relocate -f images.lock –lock-output images-relocated.lock –repository 10.117.233.2/yu/build-service
这个命令对于中国的用户很重要,因为原始的容器镜像很多都在gcr.io上,这个地址通常是中国大陆无法访问的。上面的命令是将gcr.io和pivotal的镜像仓库里的镜像重定向到你指定的的镜像仓库中(本文是我的harbor私有仓库)。如果你的环境有限制,不能同时访问gcr.io仓库和你的私有仓库,可以使用镜像备份的方法来重定向。具体步骤请参考我的博客:(https://blogs.vmware.com/china/2020/10/26/imageredirect/) - 执行下面的命令来安装Tanzu Build Service:
- 使用下面的命令来确保安装是正确的
- 使用下面的命令来安装Tanzu Build Service的一些依赖包:
kp import -f descriptor-<version>.yaml –registry-ca-cert-path <path-to-ca-cert>
descriptor-<version>.yaml是你刚才从pivotal网站下载的依赖包描述文件,<path-to-ca-cert>是你私有仓库(harbor)的证书。这个命令根据你的网络状况,可能会执行较长的一段时间。 - 为了验证安装是否成功,请执行命令: kp clusterbuilder list
3. 体验Tanzu Build Service
- 我们准备使用官方的用例来创建我们的容器镜像:(https://github.com/spring-projects/spring-petclinic)。这是一个Spring的Java应用。
- 取决于你的镜像仓库的性质,接下来要创建的容器镜像想要被你们的Pod或Deployment所使用,则需要用以下命令在相应的namespace里创建一个secret。下面的命令适用于我的Harbor(117.233.2),用户名为yu。执行命令后会提示让你输入仓库账号密码。
$ kp secret create my-harbor-creds –registry 10.117.233.2 –registry-user yu
- 在你指定的镜像仓库里创建这个容器的镜像
$ kp image create spring-petclinic –tag 10.117.233.2/yu/spring-petclinic
–git https://github.comyu/spring-projects/spring-petclinyu/spring-projectsic.git
–git-revision main - 可以用“kp build list spring-petclinic”命令检查镜像是否创建成功
- 镜像创建成功后,可以在Kebernetes的Pod或Depolyment中使用,当然,也可以使用Docker直接运行:
$ docker run –rm -p 8080:8080 10.117.233.2/yu/spring-petclinic:latest
4. Dockerfile 不香了吗
从源码(source code)到容器镜像(image)这条路径有很多工具都可以完成。最典型和原始的方式就是使用通过Docker的Buildkit使用Dockerfile来创建容器镜像。当然还有其他工具,例如Google的Kaniko,和Java语言相关的jib,和Go语言相关的ko等都可以完成source code到image的过程。而且大多数CICD的工具都可以集成它们来完成pipeline的自动编译打包过程。例如Jekins就有集成docker build的插件,来构建pipeline,通过用户定义的Dockerfile,自动为应用从源码到容器镜像打包提供一条龙服务。
那为什么要使用Tanzu Build Service呢,这和使用Dockerfile来比,到底有哪些不同和优势呢?
- 编写一个高水平的Dockerfile不是一件很容易的事情,同样的软件栈,不同的写法,容器镜像的层次和大小完全不一样。而Tanzu Build Service根本不需要写什么Dockerfile,里面包含的BuildPack将你的应用以最佳的方式分层打包。
- 使用Buildkit你需要为每个应用写一个Dockerfile。不同的语言,不同的框架结构,构建容器镜像的Dockerfile完全不一样。而使用Tanzu Build Service,里面内置的多个BuildPack可以自动识别应用的开发语言,开发框架和中间件,不需要任何类似Dockerfile的文件就能生成容器镜像。
- 通常CICD和Buildkit(Dockerfile)的集成,需要第三方插件。而Tanzu Build Service使用Kubernetes标准的接口(使用kubectl或者yaml文件),只要支持Kubernetes的CICD就能很容易集成Tanzu Build Service,非常的方便易用。
- Tanzu Build Service可以根据企业需要,定制符合企业个性化要求的BuildPack,让用户使用更加简单。例如用户仅仅提供深度计算的Python脚本,而企业自定义的BuildPack自动将Bitfusion客户端的依赖库和配置文件打包到镜像中,使得当前应用可以利用Bitfusion进行GPU加速,获得更好的性能。这一切都不需要用户自己干预。
5. 总结
在本文中只是简单的介绍了如何在vSphere with Tanzu上部署Tanzu Build Service,并且如何从github中的源代码创建你的容器镜像。其实Tanzu Build Service的功能远不止这些,它甚至可以自动探测你源码的变化,自动创建新的容器镜像;可以给多个容器镜像升级底层的操作系统而不需要重新构建你的镜像等等。在今后的文章中我会介绍Tanzu Build Service那些高级功能,并且介绍如何自定义你自己的BuildPack,能够将你的深度学习的脚本,自动打包成bitfusion client的镜像,运行在TKG上。