Skip to content

Docker Swarm on Aliyun

chuchengcao edited this page Nov 17, 2015 · 12 revisions

阿里云上部署和使用Docker Swarm集群

10546E1A_9602_4F67_82C7_B2A90F0A18BF

在2014年底,Docker公司提出了三个容器编排(orchestration )工具Docker Machine、Compose与Swarm;它们可以简化Docker环境的创建,应用的组装以及集群管理。

  • Docker Machine - 简化不同云环境下Docker环境或集群的创建。
  • Docker Compose - 原名Fig,是一个流行的Docker应用开发工具;可以简单实现容器的组装,适于构建微服务架构应用。
  • Docker Swarm - Docker的原生集群管理工具。

这些技术已经得到了社区的广泛接受和使用,并在不断快速演化。如果开发者希望搭建Docker Swarm集群来进行学习和测试,需要一些繁琐的安装和配置过程,而这些体验对初学者并不友好。通常的建议是利用Docker Machine来在云上构建Swarm集群。目前Docker Machine已经支持了Amazon EC2, Microsoft Azure等国外的公有云和Virtualbox,VMWare vSphere等私有云,但目前没有支持阿里云ECS的驱动。

为此,我提交了支持ECS驱动的Pull Request https://github.com/docker/machine/pull/1925 。这个功能能够帮助大家简化在阿里云上部署Docker集群环境的过程,只需几个简单的命令行操作,就可以完成Docker Swarm集群的创建。

本文将介绍如何在阿里云上部署和使用Docker集群。 如果需要进行试验,需要满足的先决条件如下:

  • 首先,读者应具备相应的Docker基本概念和使用经验,并需要在本机安装配置Docker开发环境;如果是Windows或Mac用户请先安装 docker-toolbox。如果您的docker-toolbox早于1.9,请升级
  • 其次,需要拥有阿里云的账号,http://www.aliyun.com/,并创建Access Key ID和Access Key Secret以供Docker Machine使用ECS开放API创建虚机。

注意:测试过程中会创建相应的虚拟机,请保证账号余额充足并及时释放虚拟机。土豪随意 :-)

Docker Swarm集群的基本概念

下图是Swarm集群的高层架构, B2182571_A52E_4D5B_B3F6_99CF931F5F27

  • 在Docker Swarm集群中,每个节点上都会安装Docker Daemon来运行Docker应用,节点上会安装Swarm agent来注册相应的Docker Daemon的服务地址,并定时向Discovery Service汇报自己节点的健康状态。
  • 集群中有一个Swarm Manager用于集群管理和服务处理:它会利用Discovery Service提供的节点的健康信息管理集群,并根据集群中资源使用状态实现动态任务调度。
  • Docker Client使用标准的Docker REST API和Swarm Manager交互,Swarm Manager会接受请求并将命令其发送至相应集群节点的Docker Daemon上执行,Docker Daemon处理命令之后由Swarm Manager返回执行结果。
  • Docker Swarm支持多种发现服务(Discovery Service)来管理集群节点信息,比如Zookeeper, Etcd, Consul等。 文本采用了最简单的方式,即以Docker Hub提供的发现服务构建集群;如果你希望支持其他发现服务请参阅文档介绍 https://github.com/docker/swarm/blob/master/discovery/README.md

Swarm与其他的Docker集群方案相比,如 Google Kubernetes和CoreOS Fleet等,其最大优势是:Swarm使用标准的Docker API作为其访问接口;换言之,各种已有Docker Client(命令行工具, docker_py, docker-ui等)均可以直接与Swarm通信。所以通过Swarm,应用可以将单节点的Docker开发测试环境,透明的切换到使用Docker集群的部署方式;Swarm可以完全复用现有的代码和工具,这样极大方便了Docker应用的开发与运维。但是Docker Swarm目前并不完善,缺乏对容器的生命周期管理、跨节点访问、服务发现等能力。在未来的文章中,我会向大家介绍如何解决这些问题。

安装Docker Machine

为了在阿里云上构建相应的Swarm集群,我们需要安装增强过的Docker Machine

如果你熟悉Go语言开发,可以从Github直接获取源代码并编译包含ECS driver的Docker Machine。 地址:https://github.com/denverdino/machine

或者直接从持续集成环境中下载阿里云ECS Driver编译结果,这些版本是基于最新的0.5 开发版的基础上自动编译完成的。

我们只在下载文件中包含了阿里云ECS的驱动,需要使用Docker Machine

如果您安装了1.9或以上版本的docker-toolbox,Docker Machine已经被缺省安装。下文的操作介绍是基于Mac OSX的,请根据你所使用的操作系统做相应的调整。

mkdir docker-machine
# Download and unzip Aliyun ECS driver
curl -L https://drone.io/github.com/denverdino/machine/files/driver/docker-machine-driver-aliyunecs_darwin-amd64.tgz >driver-aliyunecs.tgz && tar xzvf driver-aliyunecs.tgz && rm driver-aliyunecs.tgz
mv docker-machine* /usr/local/bin

如您自己希望自己安装Docker Machine 0.5,可以参照 https://github.com/docker/machine/releases。下面的操作介绍是基于Mac OSX的,请根据你所使用的操作系统做相应的调整。

mkdir docker-machine
cd docker-machine
# Download and unzip docker-machine 0.5.0
curl -L https://github.com/docker/machine/releases/download/v0.5.0/docker-machine_darwin-amd64.zip > machine.zip && unzip machine.zip && rm machine.zip
# Download and unzip Aliyun ECS driver
curl -L https://drone.io/github.com/denverdino/machine/files/driver/docker-machine-driver-aliyunecs_darwin-amd64.tgz >driver-aliyunecs.tgz && tar xzvf driver-aliyunecs.tgz && rm driver-aliyunecs.tgz
mv docker-machine* /usr/local/bin

关于Docker Machine的阿里云ECS驱动的详细使用,可参考如下文档 https://github.com/denverdino/machine/blob/master/docs/drivers/aliyun.md

或执行如下命令来显示所有可能的配置参数 (由于某些众所周知的网络因素会导致连接docker资源地址出问题,在真正创建ECS机器前请先配置环境变量export MACHINE_DOCKER_INSTALL_URL=http://docker-mirror\.oss-cn-hangzhou.aliyuncs以使用阿里云镜像地址)

docker-machine create -d aliyunecs

利用Docker Machine在ECS上创建Swarm集群

首先,我们需要创建一个token用于集群配置发现。(请不要直接使用本文中创建的token)

ubuntu@ubuntu:~/docker-machine$ docker run swarm create
a47fb27ce0947b9f93b40b1210ff26d4

然后,我们需要在阿里云上创建一个Swarm集群的master节点,它会安装Swarm manager来作为集群管理节点

为了简化命令行参数,我们可以利用环境变量来设置阿里云ECS的基本参数,如Access Key ID, Access Key Secret和指定的地域等

export ECS_ACCESS_KEY_ID=<your_access_key_id>
export ECS_ACCESS_KEY_SECRET=<your_access_key_secret>
export ECS_REGION=cn-beijing
# Mirror of docker engine packages
export MACHINE_DOCKER_INSTALL_URL=http://docker-mirror.oss-cn-hangzhou.aliyuncs.com/

docker-machine create --driver aliyunecs --swarm --swarm-master --swarm-discovery token://a47fb27ce0947b9f93b40b1210ff26d4 --engine-insecure-registry registry.mirrors.aliyuncs.com swarm-ecs-master 

关于命令行的使用解释:

  • --swarm: 创建Swarm集群
  • --swarm-master:创建Swarm集群Master节点
  • --swarm-discovery token://a47fb27ce0947b9f93b40b1210ff26d4:用于指明Swarm集群的发现协议
  • --engine-insecure-registry registry.mirrors.aliyuncs.com:配置阿里云的Docker镜像目录服务,这样ECS节点可以通过内网连接该registry, 你也可以配置成为自己的私有Docker registry访问地址。建议直接改用--engine-opt registry-mirror=xxxx来设置阿里云加速器地址,详见国内加速访问Docker相关资源
  • swarm-ecs-master: 是集群master节点的名称,之后可以在docker-machine中利用它进行访问和管理
  • Master节点也会注册成为一个集群节点提供服务,只是其之上部署了Swarm Manger对外提供集群访问
  • 如果不指定创建虚机节点所需的虚机镜像,ECS driver会自动选择最新的Ubuntu 14.04镜像

几分钟后,应该从命令行输出看到如下的内容,这样就表明虚机创建配置成功了

Creating key pair for instances...
Configuring security groups...

Launching instance with generated password, please update password in console or log in with ssh key.
Launching instance with image ubuntu1404_64_20G_aliaegis_20150325.vhd ...
To see how to connect Docker to this machine, run: docker-machine env swarm-ecs-master

接着,我们可以利用如下命令在集群中添加新的节点

docker-machine create --driver aliyunecs --swarm --swarm-discovery token://a47fb27ce0947b9f93b40b1210ff26d4 --engine-insecure-registry registry.mirrors.aliyuncs.com swarm-ecs-node-1
docker-machine create --driver aliyunecs --swarm --swarm-discovery token://a47fb27ce0947b9f93b40b1210ff26d4 --engine-insecure-registry registry.mirrors.aliyuncs.com swarm-ecs-node-2
  • 每个节点都指定相同的--swarm-discovery参数,可以将节点自动加入Master所在Swarm集群
  • 对于Swarm节点,不要指定swarm-master参数
  • swarm-ecs-node-1和swarm-ecs-node-2: 是集群节点的名称,之后可以在docker-machine中利用它进行访问和管理
  • 可以随时动态创建和删除集群节点,Swarm manager会负责管理集群中节点的可用状态。

如果创建节点过程中出现异常,通常原因是我天朝的Great Firewall发威了,建议是使用删除相应的节点并重新执行创建命令。希望Docker会逐步改善国内的访问速度和稳定性,或是阿里云能够提供相应的镜像服务。

docker-machine kill <name>
docker-machine rm -f <name>

创建节点成功之后,我们就可以利用Docker Machine方便地进行管理。比如列出所有创建的节点信息:

ubuntu@ubuntu:~/docker-machine$ docker-machine ls
NAME               ACTIVE   DRIVER      STATE     URL                         SWARM
swarm-ecs-master            aliyunecs   Running   tcp://182.92.235.65:2376    swarm-ecs-master (master)
swarm-ecs-node-1            aliyunecs   Running   tcp://112.126.68.35:2376    swarm-ecs-master
swarm-ecs-node-2            aliyunecs   Running   tcp://182.92.169.233:2376   swarm-ecs-master

使用SSH证书登录到新创建的ECS虚拟机上

docker-machine ssh swarm-ecs-master

Docker Machine创建了Swarm集群,也保证了集群的安全访问:

  • 为了保证虚拟机的安全,Docker Machine的ECS driver会为每个创建的虚拟机动态生成root密码和SSH key pair,所以用户初始只能通过SSH证书的方式访问,相应的证书文件存放在 ~/.docker/machine/machines/<name>/ 的目录下。 如需要使用密码方式访问SSH,可以在使用证书登录后修改root用户密码。此外执行如下命令可以重新配置节点上的SSH证书
docker-machine regenerate-certs <name>
  • 同时Docker Machine也为所有节点之上的Docker Daemon创建了SSL证书来确保远程访问的安全传输和身份认证。
ubuntu@ubuntu:~/docker-machine$ ls ~/.docker/machine/machines/swarm-ecs-master/
ca.pem  cert.pem  config.json  id_rsa  id_rsa.pub  key.pem  server-key.pem  server.pem

使用Swarm集群

只需在环境变量中指明Swarm master的访问端点,就可以利用现有Docker命令行工具来访问Swarm集群,

查看和访问Docker集群所需的环境变量可以使用如下命令

ubuntu@ubuntu:~/docker-machine$ docker-machine env --swarm swarm-ecs-master
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://182.92.235.65:2376"
export DOCKER_CERT_PATH="/home/ubuntu/.docker/machine/machines/swarm-ecs-master"
export DOCKER_MACHINE_NAME="swarm-ecs-master"
# Run this command to configure your shell: 
# eval "$(docker-machine env --swarm swarm-ecs-master)"

注意:Docker Swarm Master的访问端口是3376 可以利用下面的命令在Shell中配置访问Swarm集群所需环境变量

eval "$(docker-machine env --swarm swarm-ecs-master)"

配置成功之后,我们就可以像访问本地Docker环境一样访问Docker集群

ubuntu@ubuntu:~/docker-machine$ docker version
Client:
 Version:      1.8.0
 API version:  1.20
 Go version:   go1.4.2
 Git commit:   0d03096
 Built:        Tue Aug 11 17:17:40 UTC 2015
 OS/Arch:      darwin/amd64

Server:
 Version:      swarm/0.4.0
 API version:  1.16
 Go version:   go1.4.2
 Git commit:   d647d82
 Built:        
 OS/Arch:      linux/amd64
ubuntu@ubuntu:~/docker-machine$ docker info
Containers: 4
Images: 3
Storage Driver: 
Role: primary
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 3
 swarm-ecs-master: 182.92.235.65:2376
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.018 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-32-generic, operatingsystem=Ubuntu 14.04.2 LTS, provider=aliyunecs, storagedriver=aufs
 swarm-ecs-node-1: 112.126.68.35:2376
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.018 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-32-generic, operatingsystem=Ubuntu 14.04.2 LTS, provider=aliyunecs, storagedriver=aufs
 swarm-ecs-node-2: 182.92.169.233:2376
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.018 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-32-generic, operatingsystem=Ubuntu 14.04.2 LTS, provider=aliyunecs, storagedriver=aufs
Execution Driver: 
Kernel Version: 
Operating System: 
CPUs: 3
Total Memory: 3.053 GiB
Name: 
ID: 
Http Proxy: 
Https Proxy: 
No Proxy: 

使用Compose在集群上部署Wordpress应用

通过Docker Compose应用模板,开发者可以方便地描述如何将一组容器组合成一个完整的应用程序;它非常适于利用Docker来开发和测试微服务应用。关于Docker Compose的安装使用,请参阅https://docs.docker.com/compose/

我们也可以在Swarm集群上使用Compose。首先,我们需要创建一个docker-compose.yml来描述Wordpress应用的部署

web:
  image:  wordpress:latest
  ports:
    - "80:80"
  links:
    - db:mysql
db:
  image:  mysql:5.6
  environment:
    MYSQL_ROOT_PASSWORD: password

这个简单的Wordpress应用会使用两个容器服务:

  • 容器服务“web”会启动Apache 2来运行wordpress PHP应用;
  • 容器服务“db”会创建MySQL数据库服务器;
  • “web”容器通过容器链接,使用“db”服务来创建所需的数据库。

为了在Swarm集群上部署应用,我们需要执行以下命令

启动应用所需的Docker容器

ubuntu@ubuntu:~/docker-machine$ docker-compose up -d
Creating dockermachine_db_1...
Creating dockermachine_web_1...

显示应用中Docker容器信息

ubuntu@ubuntu:~/docker-machine$ docker-compose ps
       Name                      Command               State            Ports           
---------------------------------------------------------------------------------------
dockermachine_db_1    /entrypoint.sh mysqld            Up      3306/tcp                 
dockermachine_web_1   /entrypoint.sh apache2-for ...   Up      112.126.68.35:80->80/tcp 

从以上结果中,我们可以了解到相应Wordpress应用的访问端点是“112.126.68.35:80” 然后我们可以从浏览器访问刚才部署的Wordpress应用了

515525F6_DB47_4C7D_BA95_A2D42748371E 8DA37E61_B499_4B0F_9244_D57BC836923C

总结

本文简单介绍了在ECS上部署和使用Docker集群的方法,希望能对大家的工作学习有所帮助。关于集群中网络配置,VPC集成等内容我会在未来向大家介绍。

Docker Machine的ECS扩展只是一个业余时间的项目,如果你有任何建议或意见,或是在使用过程中发现了什么问题请发信给我 ([email protected]),或者在Github上与我沟通。

另外感谢焦义和屠虎的合作,和很多阿里同学的建议。

谢谢