如何使用Azure Container Service Engine在Azure中国区部署容器服务(一):DC/OS篇

前言

目前越来越多的企业正在尝试使用容器来构建他们的服务,他们或者在自己的本地数据中心搭建基于容器的集群,或者利用公有云来承载基于容器和微服务的集群架构,然而很多企业发现搭建一套能够适用于生产环境的容器集群并不是一件容易的事情。容器服务集群所带来的高密度和高复杂性的分布式运算使得传统的IT管理和运维手段变得非常的低效。

ACS是微软在2015年12月推出的一项基于容器的云端PaaS服务。ACS的诞生就是为了给企业提供一套经过优化的,可适用于生产环境的,配置简单的基于开源编排框架来简化企业部署容器集群的复杂程度。ACSengine是微软提供的一个“转换器”,用户只需要配置几个简单的参数来描述容器集群的规格,然后ACSengine就可以将这个“集群规格说明”文档转化成ARM模板来自动化地在Azure公有云上生成容器集群。

ACS完全基于开源组件,目前ACS支持主流的编排框架有:DC/OS,Swarm,Kubernetes。ACS engine也已经在GitHub上开源(https://github.com/azure/acs-engine),企业可以在任何的云平台使用并迁移这套容器服务,避免了对某个平台的耦合。有兴趣的朋友可以下载尝试。

DC/OS介绍

DC/OS是一套企业级的容器编排框架,它不仅支持Docker镜像,同时也支持其他的镜像格式。DC/OS已经被很多著名的公司使用,包括Twitter,Apple,Yelp等等。AzureDC/OS是微软和Mesosphere公司联合开发的分布式容器解决方案。基于这套方案可以为企业带来很多的便利:

  • 高可用性 – 基于Marathon编排算法,保证服务的高可用性
  • 定制化部署方案 – 方便用户将容器部署到指定的环境中
  • 服务发现/负载均衡– 灵活的服务发现和负载均衡机制,满足业务的弹性扩展
  • 服务状态监测 – 实时服务健康状态监测,保证服务随时可用
  • 灰度发布 – 实现新旧版本服务的平滑升级和回滚
  • 丰富的UI和API接口 – 支持CLI和REST API

ACS Engine架构解读

首先我们可以看一下acs engine的架构图(以DC/OS为例):
ACS engine是一个ARM模板生成器,通过acs engine我们可以将预先配置好的集群描述文件转化成一组ARM模板,然后通过azure提供的CLI命令,可以将这组模板部署到Azure上面。下面是一个DC/OS集群描述文件的例子:

1{ 2 "apiVersion": "vlabs", 3 "properties": { 4 "orchestratorProfile": { 5 "orchestratorType": "DCOS" 6 }, 7 "masterProfile": { 8 "count": 1, 9 "dnsPrefix": "", 10 "vmSize": "Standard_D2_v2" 11 }, 12 "agentPoolProfiles": [ 13 { 14 "name": "agentprivate", 15 "count": 3, 16 "vmSize": "Standard_D2_v2" 17 }, 18 { 19 "name": "agentpublic", 20 "count": 3, 21 "vmSize": "Standard_D2_v2", 22 "dnsPrefix": "", 23 …… 24 "linuxProfile": { 25 "adminUsername": "azureuser", 26 "ssh": { 27 "publicKeys": [ 28 { 29 "keyData": "" 30 } 31 …… 32

其中几个比较关键的参数:

  • orchestratorType:用来指定编排器的类型,可选DCOS,Swarm和Kubernetes。这个例子中我们使用DCOS。

  • masterProfile:指定DCOS集群中master节点的数量和配置

  • dnsPrefix用来指定master节点的名称,这个名称加上azure的固有后缀就组成了访问这台master节点的名称。比如我们指定dnsPrefix为“master-01”,集群部署成功后我们就可以使用“master-01..cloudapp.chinacloudapi.cn”这个域名来访问master节点了.

    • count: master节点的数量,一般选择奇数个,这里我们指定1个master
    • vmSize:指定虚机的规格
  • agentPoolProfiles:指定DCOS集群中agent节点的数量和硬件配置

  • ssh/publicKeys/keyData:这个字段用来指定ssh的证书,集群建立好以后可以通过这个证书访问集群节点。

配置好以上几个参数后就可以使用acs engine来生成我们需要的ARM模板了,在生成模板之前,让我们看一下acs源码的大致目录结构,加深一下对acs engine的印象:

  • docs目录存放了如何使用acs engine的介绍,包括如何使用acs engine生成ARM模板,如何使用客户端工具去连接部署好的容器集群等等。

  • examples目录包含了很多的集群描述文件,用户可以根据需要来选择不同规格的集群,比如小到1个master和3个agent的小规模集群和大到1000个以上节点的大规模集群。

  • parts目录包含了很多用来生成ARM模板的“片段”,这些“片段”主要分为几类:

  • 用来初始化基础计算资源的脚本-这类脚本主要的作用是根据集群描述文件中定义的集群拓扑结构来生成各种虚机,存储,虚拟网络,公共IP和安全组策略等。

    • 用来初始化计算节点服务的脚本 - 这类脚本会在基础计算资源建立好以后在每个计算节点运行。比较典型的脚本就是下载DCOS相关的依赖组件,然后在系统初始化的时候进行安装和配置。
  • pkg目录包含了acs engine的核心逻辑,其中最主要的是engine.go模块,它通过用户指定的集群描述文件来在“parts”目录中选择相应的ARM模板片段,然后将这些片段“组装”起来生成一个完整的ARM模板并输出到_output目录中。

  • script目录包含了一些如何利用docker来运行acsengine的脚本,让用户更加方便地使用。

  • test目录存放了测试相关的一些数据。

部署准备

由于DC/OS在部署的过程中需要从Azure CDN上下载安装依赖,而由于国内防火墙的问题,Azure CDN目前在国内无法访问,所以我们需要手动修改一下dcosprovison.sh这个脚本,将安装依赖的选项修改到国内,这样安装过程才能顺利执行。具体的修改流程如下:
打开parts/dcosprovision.sh脚本:

1#!/bin/bash 2MESOSDIR=/var/lib/mesos/dl 3mkdir $MESOSDIR 4curl -fLsSv --retry 20 -Y100000 -y 60 -o $MESOSDIR/bootstrap.tar.xz https://dcosio.azureedge.net/dcos/testing/bootstrap/${BOOTSTRAP_ID}.bootstrap.tar.xz& 5curl -fLsSv --retry 20 -Y100000 -y 60 -o $MESOSDIR/bootstrap.tar.xzhttps://az837203.vo.msecnd.net/dcos/testing/bootstrap/${BOOTSTRAP_ID}.bootstrap.tar.xz& 6curl -fLsSv --retry 20 -Y100000 -y 60 -o $MESOSDIR/d.debhttps://az837203.vo.msecnd.net/dcos-deps/docker-engine_1.11.2-0~xenial_amd64.deb& 7curl -fLsSv --retry 20 -Y100000 -y 60 -o $MESOSDIR/1.debhttps://az837203.vo.msecnd.net/dcos-deps/libipset3_6.29-1_amd64.deb & 8curl -fLsSv --retry 20 -Y100000 -y 60 -o $MESOSDIR/2.debhttps://az837203.vo.msecnd.net/dcos-deps/ipset_6.29-1_amd64.deb & 9curl -fLsSv --retry 20 -Y100000 -y 60 -o $MESOSDIR/3.debhttps://az837203.vo.msecnd.net/dcos-deps/unzip_6.0-20ubuntu1_amd64.deb & 10curl -fLsSv --retry 20 -Y100000 -y 60 -o $MESOSDIR/4.debhttps://az837203.vo.msecnd.net/dcos-deps/libltdl7_2.4.6-0.1_amd64.deb & 11wait 12

修改红色的部分为:

1curl -fLsSv --retry 20 -Y 100000 -y 60-o $MESOSDIR/bootstrap.tar.xzhttp://acsengine.blob.core.chinacloudapi.cn/dcos/${BOOTSTRAP_ID}.bootstrap.tar.xz& 2curl -fLsSv --retry 20 -Y 100000 -y 60-o $MESOSDIR/d.debhttp://acsengine.blob.core.chinacloudapi.cn/dcos/docker-engine_1.11.2-0~xenial_amd64.deb& 3curl -fLsSv --retry 20 -Y 100000 -y 60-o $MESOSDIR/1.debhttp://acsengine.blob.core.chinacloudapi.cn/dcos/libipset3_6.29-1_amd64.deb& 4curl -fLsSv --retry 20 -Y 100000 -y 60-o $MESOSDIR/2.debhttp://acsengine.blob.core.chinacloudapi.cn/dcos/ipset_6.29-1_amd64.deb & 5curl -fLsSv --retry 20 -Y 100000 -y 60-o $MESOSDIR/3.debhttp://acsengine.blob.core.chinacloudapi.cn/dcos/unzip_6.0-20ubuntu1_amd64.deb& 6curl -fLsSv --retry 20 -Y 100000 -y 60-o $MESOSDIR/4.debhttp://acsengine.blob.core.chinacloudapi.cn/dcos/libltdl7_2.4.6-0.1_amd64.deb& 7

修改过后我们就可以开始编译部署了。

部署流程

  1. 编译生成acs engine

Windows环境

  • 安装软件

  • Git for Windows.

    • Go for Windows.
    • Powershell
  • 编译步骤

  • 新建GO工作目录,比如c:\gopath

    • 运行Win+R,打开命令窗口,运行“rundll32sysdm.cpl,EditEnvironmentVariables”命令打开系统环境变量设置窗口
    • 将c:\go\bin加入到PATH环境变量中
    • 新建GOPATH环境变量,并将路径指向刚刚新建的c:\gopath目录
    • 打开命令行窗口,将工作目录定位到c:\gopath
    • 运行go get github.com/Azure/acs-engine命令将acsengine代码下载到本地目录中
    • 运行go get all命令获取依赖项
    • 参考上个章节中的介绍,修改dcosprovision.sh脚本,将AzureCDN的依赖选项改到国内可以访问的地址。
    • 重新生成pkg/acsengine/template.go文件,打开命令行工具,运行下面的命令(假设$ACS_HOME是源码根目录):
  • go get -u github.com/jteeuwen/go-bindata(获取go-bindata) * cd $ACS_HOME * rm -fr pkg/acsengine/templates.go (删除原来的template.go) * cd parts * go-bindata -o ../pkg/acsengine/template.go .

    • 运行go build命令编译生成acsengine

OS X/linux

  • 安装软件

  • Go for OS X/Linux.

  • 编译步骤:

  • 新建gopath目录:mkdir$HOME/gopath

    • 设置path环境变量
    • 新建$HOME/.sh_profile文件,添加下面的内容
  • export PATH=$PATH:/usr/local/go/bin * export GOPATH=$HOME/gopath * 激活配置source$HOME/.sh_profile

    • 运行go get github.com/Azure/acs-engine命令获取acsengine代码到本地目录
    • 运行go get all命令获取依赖项
    • 参考上个章节中的介绍,修改dcosprovision.sh脚本,将AzureCDN的依赖选项改到国内可以访问的地址。
    • 重新生成pkg/acsengine/template.go文件,打开命令行工具,运行下面的命令(假设$ACS_HOME是源码根目录):
  • go get -u github.com/jteeuwen/go-bindata(获取go-bindata) * cd $ACS_HOME * rm -fr pkg/acsengine/templates.go (删除原来的template.go) * cd parts * go-bindata -o ../pkg/acsengine/template.go .

    • 运行go build命令编译生成acsengine

编译成功后,acs-engine就会生成了,如下图:

2.编辑examples/dcos.json集群描述文件

打开examples/dcos.json,将空白处的masterProfile/dnsPrefix, agentPoolProfiles/dnsPrefix, ssh/publickeys/keydata分别填入相应的参数,例如:

1{ 2 "apiVersion": "vlabs", 3 "properties": { 4 "orchestratorProfile": { 5 "orchestratorType": "DCOS" 6 }, 7 "masterProfile": { 8 "count": 1, 9 "dnsPrefix": "test-master1", 10 "vmSize": "Standard_D2_v2" 11 }, 12 "agentPoolProfiles": [ 13 { 14 "name": "agentprivate", 15 "count": 3, 16 "vmSize": "Standard_D2_v2" 17 }, 18 { 19 "name": "agentpublic", 20 "count": 3, 21 "vmSize": "Standard_D2_v2", 22 "dnsPrefix": "test-agent1", 23 "ports": [ 24 80, 25 443, 26 8080 27 ] 28 } 29 ], 30 "linuxProfile": { 31 "adminUsername": "azureuser", 32 "ssh": { 33 "publicKeys": [ 34 { 35 "keyData":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx(SSH KEY)" 36 ...... 37

3.运行acsengine生成ARM模板
运行acs-engineexamples/dcos.json,相应的ARM模板就会在_output目录中生成,如下图:
azuredeploy.json是核心的ARM模板
azuredeploy.parameters.json是对应的配置参数

至此为止,aceengine的任务就圆满结束了,接下来就需要将生成好的ARM模板部署到Azure上面了。

4.利用Azure CLI命令部署DCOS集群

  1. 登录Azure中国区

azure login –e AzureChinaCloud
2) 设置azurecli的模式为arm
azure config mode arm
3) 创建资源组(集群中的所有资源都会在这个资源组中创建)
azure group create --name="<resource_group_name>"--location="<location>", 这里的location可选china north或者china east.
4) 部署DCOS集群
azure group deployment create --name="<deployment_name>"--resource-group="<resource_group_name>"--template-file="./azuredeploy.json"--parameters-file="./azuredeploy.parameters.json"
部署成功以后,访问azure.cn的门户预览界面,可以看到DCOS已经启动,这个集群具有一个master节点和两个vmss(虚拟机规模集)

通过ssh tunnel访问DCOS集群master节点

1.在azure门户预览中,点击下图中红色框中的内容,在弹出的界面中拷贝masterFQDN,这个地址就是我们稍等要访问的地址.
2.打开terminal,执行以下命令创建一个ssh tunnel

1sudo ssh -L 80:localhost:80-f -N <username>@<masterFQDN> -p 2200 2username就是我们在集群描述文件中的adminUsername 3masterFQDN就是刚才我们在门户预览中复制的地址 4

3.打开本地浏览器访问http://localhost,如果能显示下面的界面就表示已经创建成功了
4.如果我们想部署一个简单的hello-world容器服务的话,可以点选“Services”,然后点击“DeployService”
5.设置需要部署的服务的id为“helloworld”,然后点击“Container Settings”,在弹出的界面中设置需要部署的docker镜像的名称
6.点击“Deploy”后并部署成功后,点选“helloworld”服务,就可以查看部署的服务的详细信息了
具体的DCOS的使用细节可以参考其官方文档,这里就不多赘述了

结论

通过上面的操作我们发现ACS确实是一大利器,能够最大限度地简化容器集群的部署和配置,用户只需要配置几个简单的集群描述参数就能迅速享受到容器化集群给生产环境带来的各种便利。同时因为本身架构是基于开源解决方案,用户可以很方便地将已经运行在本地数据中心的容器集群迁移到Azure上,也可以将Azure上的ACS服务迁移到别的数据中心,减少了服务和平台的耦合性,让用户享受便利的同时,免除了对平台耦合的顾虑,唯一美中不足的地方就是国内防火墙的存在对安装过程有些阻碍,目前笔者暂时先把这些依赖的组件放到了Azure的存储里面,笔者相信Azure在将来一定会有更加完善的CDN的解决方案来更加快速地帮着用户完成部署。

代码交流 2021