ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(三)
在上文中,我介绍了如何使用Azure DevOps为ASP.NET Core应用程序案例:tasklist搭建持续集成环境。在持续集成的过程中,Azure DevOps的Build Pipeline会下载tasklist的源代码,使用Docker容器环境进行项目构建,将构建的容器镜像推送到Docker Hub,并将源代码库中的yml文件复制到构建生成目录(Build Artifacts),以备持续部署时使用。今天,我打算介绍一下基于Azure Kubernetes Service和Azure DevOps的部署过程,本章节结束后,你可以看到我们的tasklist已在Kubernetes集群中运行。
强烈建议在阅读本文前,先对上两篇文章做一个大致的了解,然后阅读tasklist源码库,因为tasklist源码库展示的是一个完整的案例。
Kubernetes与Azure Kubernetes Service
好吧,既然介绍Kubernetes部署,就离不开这两个概念:Kubernetes与Azure Kubernetes Service。Kubernetes(k8s)是Google开源的容器编排集群系统,可以让一个或一组容器运行在集群环境,从而使基于容器的应用程序获得可伸缩与高可用的特性。Kubernetes使用Go语言实现,它有一个实验性的版本,叫Minikube。Minikube是一个只包含一个节点的Kubernetes集群,可以在Windows、Linux等多平台中部署Minikube,部署过程也相对简单,因此,如果是用于学习或者一些简单的实验,可以选择Minikube。在Kubernetes集群运行起来后,就可以使用Kubectl命令行客户端对集群进行管理。 如果是自己部署生产级别的Kubernetes集群的话,配置过程会相对比较复杂,此外,由于Kubernetes是Google的项目,有很多配置部署的脚本以及二进制文件都是使用Google的CDN进行分发,国内是无法访问这些资源的,所以,我还是建议大家使用托管的Kubernetes服务,比如Azure的Azure Kubernetes Service(AKS),这样可以省去繁杂的配置过程,而且还可以根据自己的需要来决定Kubernetes集群的体量,非常方便。 Azure Container Service为容器化的应用程序的运行提供了容器集群环境,它支持三种不同的容器编排器(container orchestrator):Docker Swarm、基于DC/OS的Marathon服务,以及大家熟知的Kubernetes,也就是今天我打算介绍的Azure Kubernetes Service。大家如果有兴趣的话,也不妨了解一下Docker Swarm和DC/OS Marathon。在Azure上创建托管的Kubernetes(AKS)集群
据我所知,目前Azure中国区版没有官方的AKS服务,网上也有一些资料,帮助读者在Azure中国区版中部署Kubernetes集群,但是过程也相对比较繁杂。在这里,我会使用Azure国际版进行介绍。 首先,登录Azure国际版,点击Create a resource按钮,在新建资源的列表中输入Kubernetes进行搜索,在搜索结果中点击Kubernetes Service选项: 在Create Kubernetes Cluster页面中,进入Basics标签页,然后填写以下信息:- Subscription:选择你的Azure订阅
- Resource Group:为Kubernetes集群选择一个Azure的资源组(Resource Group),之后为Kubernetes创建的所有资源都会被划入该资源组中,便于管理。你也可以点击Create new按钮新建一个资源组
- Kubernetes cluster name:新创建的Kubernetes集群的名称
- Region:创建资源所属的Region
- Kubernetes version:Kubernetes的版本,选择默认的即可
- DNS name prefix:所创建集群的DNS名称前缀
- Node size:集群中每个节点的虚拟机配置,可以根据自己的实际情况进行选择,当然,配置越高费用也越高。这里我只选择Standard B2s,一个月40美金的样子
- Node count:集群中的节点个数,为了演示,我选择2个节点,于是,Node size * Node count,费用大概一个月80美金的样子
- 首先确保已经安装Azure命令行工具(Azure CLI)2.0.27或以上版本,有关Azure CLI的安装,可以参考:https://docs.microsoft.com/zh-cn/cli/azure/install-azure-cli?view=azure-cli-latest
- 使用以下命令安装kubectl命令行工具:
az aks install-cli
- Kubectl工具安装完成之后,可以将kubectl的路径添加到PATH环境变量中,方便今后使用。然后,执行下面的命令,以下载集群的登录连接凭证:
az aks get-credentials --resource-group <resource_group> --name <k8s_cluster_name>
此处<resource_group>表示在创建Kubernetes集群时指定的资源组名称,<k8s_cluster_name>则是创建集群时指定的Kubernetes集群名称 - 执行以下命令,即可打开Kubernetes集群的仪表盘(Dashboard),其中参数如上所述:
az aks browse --resource-group<resource_group> --name <k8s_cluster_name>
tasklist容器的部署
在前一篇文章中,我们已经将构建生成的容器镜像推送到Docker Hub中,并将用于部署的yml文件复制到了构建输出目录。简便起见,我已经将yml文件保存到了代码库中,在tasklist的代码库中,目前有三个yml文件:docker-compose.pki.yml,docker-compose.yml以及k8s.deployment.yml。前两个文件都是用于构建或者运行容器的(docker-compose.pki.yml文件是我私人使用的,这里可以忽略),只有k8s.deployment.yml才是真正用来实现部署的。接下来,我们将使用这个k8s.deployment.yml,将tasklist容器部署到Kubernetes集群中。Compose?Kompose?
在Kubernetes上部署容器应用,需要使用YAML格式的配置文件,然后使用kubectl apply命令实现部署。通过阅读官方网站的文档,你会发现其实编写这些YAML文件还是有一定工作量的。对于tasklist案例,我使用Google官方的Kompose命令行工具,它可以很方便地将Docker Compose文件转为Kubernetes的部署文件。官方的解释就是:Kubernetes + Compose = Kompose。不过可惜的是,Kompose的网站在国内是打不开的,不过可以通过Kompose的代码库来了解这个工具。tasklist所使用的k8s.deployment.yml文件,正是通过Kompose生成的,不过我也基于自己的需要进行了一些简单的定制。在Azure Pipeline中创建部署任务
打开Azure DevOps管理界面,选择我们在上一讲中创建的tasklist-demo项目,然后,在Pipelines下选择Releases,然后点击New pipeline按钮,新建一个Release Pipeline。 然后,在Select a template页面,选择Deploy to a Kubernetes cluster模板,点击Apply按钮使用该模板: 在Stage的配置中,填入Stage的名称: 回到All pipelines的配置界面,首先为我们的部署任务起个名字,然后,点击Add an artifact选项,将之前持续集成的输出结果文件,也就是用于k8s部署的YAML文件作为Release Pipeline的输入,添加到Artifacts中。在Add an artifact界面中,我们选择Build类型,表示要使用构建的输出结果,然后,Source选择Build Pipeline的名称,也就是tasklist-demo,其它选项可以默认。当然,你也可以根据自己项目的需求对这些默认的设置进行更改,不过,在此也就不多介绍了。一切设置好之后,点击Add按钮,将Artifact加入Release Pipeline。 之后,点击创建好的K8S Deployment stage,在Agent job列表中,选择kubectl apply,表示我们需要更改一个Kubernetes的集群,然后,在右边的Deploy to Kubernetes界面中,进行如下设置:- Display name:当前任务的名称,随便起一个有意义的名字就行了
- Kubernetes service connection:选择所需部署的k8s集群的连接信息。目前我们没有可用的连接,所以需要创建一个。点击New按钮即可创建:
- 在Add a Kubernetes service connection对话框中,可以选择两种认证模式:Kubeconfig和Service account。前者需要使用由Azure k8s集群提供的认证配置文件;后者则是直接通过Azure的服务账号来创建连接。这里,我们选用Kubeconfig
- 在Connection name中,输入名称
- 打开Azure Portal,进入tasklist-demo Kubernetes集群的主页,找到API server address项,将内容复制到剪贴板:
- 回到Add a Kubernetes service connection对话框,将复制的内容粘贴到Service URL中,注意前面加上https://的前缀
- 打开Azure Portal,进入tasklist-demo Kubernetes集群的主页,点击View Kubernetes dashboard连接,在Windows命令行中执行获取credential的命令,这个内容在上文也已经介绍过了,这里就贴个截图示意一下:
- 在操作系统中,打开当前用户目录(比如,Windows下为C:\Users\daxnet,Linux下为/home/daxnet),找到.kube文件夹,然后用文本编辑器打开config文件
- 复制config文件的所有内容,然后回到Add a Kubernetes service connection对话框,将内容粘贴到KubeConfig项
- 目前我们暂时不涉及证书的问题,所以勾选Accept untrusted certificates复选框
- 点击Verify connection链接,确保连接Kubernetes集群成功:
- 回到Deploy to Kubernetes页面,此时Kubernetes service connection会自动选中刚刚所创建的Kubernetes连接
- 勾选Use Configuration file复选框,在Configuration file文本框右边点击省略号按钮:
- 在Select a file or folder对话框中,选择k8s.deployment.yml。还记得上面我们选择Build作为Artifact的类型吗?这个k8s.deployment.yml就是从那边复制过来的:
- 对于其它的配置选项,我们暂且使用默认值,然后点击Save按钮,保存我们的Release Pipeline设置