理论
Docker Stacks and DAB(Distributed Application Bundles)是Docker 1.12和Docker Compose 1.8之后的体验功能特性,伴随着Docker Engine中的Swarm Mode,Nodes和Services而来。
起初我们通过docker run
命令成功运行一个容器之后就可以访问容器中的应用,比如跑一个nginx的web服务;
如需跑一个由多容器组成的应用,我们会用到docker-compose up
,它会基于已定义好的YML文件来启动多个容器。比如跑一个WordPress应用(含WP应用和MySQL数据库两个容器)。这就是编排,个人认为compose编排的对象是容器;
暂且抛开外置的Swarm不谈,以上两种方式都是在单节点和极小规模的环境玩的,集群环境基本难以玩转。
随后Docker内置Swarm Mode,我们可以通过简单的几条命令就能够搭建一个Docker的集群环境,单个应用的多个容器可以被手动/自动调度到集群中的各个节点运行,内置负载均衡功能实现以Services为形式的服务,极大的提高了容器化应用的弹性。
我们可以使用docker service create
命令运行一个服务,每个服务下面可含有一个或多个容器。但需要注意的是,服务下的多个容器虽会被分配到不同的集群节点,但是容器本身是一样的(来自同一各Image)。比如创建一个含有3个容器的nginx服务,3个容器会被分配到3个节点,之后会由内置的负载均衡提供统一的服务出口,3个容器本身除了在不同的节点之外,不会有其他任何的差异。
我们没有办法在同一个服务里面跑两个不同的容器(比如一个WordPress的应用需要WPAP和WPDB两个容器是实现不了的)。目前的解决方法就是手动创建WordPress应用的WPAP和WPDB服务,然后通过服务的相关信息进行内部网络通信和外部网络访问。
提到网络也就多说一句,Docker网络常用的两种网络模式:local(本地)和overlay(全局)。local网络只能被docker run
和docker-compose
使用,overlay网络只能被docker service create
使用。
好在Docker在用户体验方面一直下足了功夫,Stacks和DAB应运而生。Stacks作为最终运行的容器化应用,下面会有多个服务,DAB专门负责这些服务的定义。例如我们可以将WordPress应用中WPAP和WPDB两个服务定义在dab文件中,之后通过docker deploy
命令部署WordPress这个Stack,这样就不需要手动一个个的去部署服务了。
总结一下:
集群环境中的docker service create 类似 单机环境中的docker run;
集群环境中的docker deploy 类似 单机环境中的 docker compose;
集群环境中的deploy dab文件 类似 单机环境中的 compose yml文件;
如果说compose是基于yml文件来编排容器,那么deploy就是基于dab文件来编排服务。
神来之笔是,就像我们可以用Dockerfile通过docker build生成Image一样,我们也可以用compose yml通过docker-compose bundle生成deploy dab,这无疑使得对DAB的理解和使用更加平滑。
为什么总说Docker上手和使用很简单?简单并不代表没有技术含量,相反,化繁为简才需要真正的技术含量。Docker Engine简化的容器操作,Swarm Mode简化的集群调度和DAB简化的应用编排等等,这些都是最好的诠释。
实践
前面说了那么多,也不知道说清楚没,下面以部署一个Docker币的应用为例动手实操体验一下。
环境准备
Docker Host: 2台(CentOS 7.2+Ubuntu 16.04)
[root@manager01 ~]# lsb_release -d Description: CentOS Linux release 7.2.1511 (Core) root@worker01:~# lsb_release -d Description: Ubuntu 16.04.1 LTS
Docker Engine: 1.12.3 Experimental
# docker version Client: Version: 1.12.3 API version: 1.24 Go version: go1.6.3 Git commit: 6b644ec Built: Wed Oct 26 22:07:18 2016 OS/Arch: linux/amd64 Experimental: true Server: Version: 1.12.3 API version: 1.24 Go version: go1.6.3 Git commit: 6b644ec Built: Wed Oct 26 22:07:18 2016 OS/Arch: linux/amd64 Experimental: true
注意:安装experimental版本才能体验Stacks和DAB的特性。
Docker Compose: 1.9
root@worker01:~# docker-compose -v docker-compose version 1.9.0, build 2585387
Docker Registry: 192.168.2.11:8080
需要Registry的原因是DAB使用的镜像必须有digests信息,所以镜像必须是存储在Registry中的。
具体如下
Generate a Distributed Application Bundle (DAB) from the Compose file. Images must have digests stored, which requires interaction with a Docker registry. If digests aren't stored for all images, you can fetch them with `docker-compose pull` or `docker-compose push`.
Docker Images:werbui,rng,worker,hasher,redis
# docker images 192.168.2.11:8080/dockercoins/dockercoins_webui latest 192.168.2.11:8080/dockercoins/dockercoins_rng latest 192.168.2.11:8080/dockercoins/dockercoins_hasher latest 192.168.2.11:8080/dockercoins/dockercoins_worker latest 192.168.2.11:8080/dockercoins/dockercoins_redis latest
Docker Engine和Docker Compose如果GFW抽风下载不了的话去get.daocloud.io看看吧,业界良心。
Swarm Mode激活
初始化Manager节点
[root@manager01 ~]# docker swarm init --advertise-addr 192.168.2.201 Swarm initialized: current node (2kroyys1kcoryffuex9nobcl3) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-17lmhxt8er26bxhhieupx8s3vce2bezhgql1za5c394ofkqnsn-6nskpxfs4jnm7ikk73vzkilc4 \ 192.168.2.201:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
加入worker节点
root@worker01:~# docker swarm join --token SWMTKN-1-17lmhxt8er26bxhhieupx8s3vce2bezhgql1za5c394ofkqnsn-6nskpxfs4jnm7ikk73vzkilc4 192.168.2.201:2377 This node joined a swarm as a worker.
查看节点信息
[root@manager01 ~]# docker node ls HOSTNAME STATUS AVAILABILITY MANAGER STATUS manager01.docanix.com Ready Active Leader worker01.docanix.com Ready Active
创建Overlay网络
# docker network create -d overlay dockercoins cy0zt5cfquov5ia9a2yen7r12 # docker network ls NETWORK ID NAME DRIVER SCOPE 171960155d4b bridge bridge local b1c3cdcc2dce docker_gwbridge bridge local cy0zt5cfquov dockercoins overlay swarm 3836eec16480 host host local 0h18kkjshga7 ingress overlay swarm 643bf0bce504 none null local
注:这一步可以略过,在Stacks部署的时候会自动创建一个overlay的全局网络,目前还未找到自定义网络的方法。
compose文件
# cat docker-compose.yml version: "2" services: rng: image: 192.168.2.11:8080/dockercoins/dockercoins_rng:latest ports: - "8001:80" networks: - dockercoins hasher: image: 192.168.2.11:8080/dockercoins/dockercoins_hasher:latest ports: - "8002:80" networks: - dockercoins webui: image: 192.168.2.11:8080/dockercoins/dockercoins_webui:latest ports: - "8000:80" networks: - dockercoins redis: image: 192.168.2.11:8080/dockercoins/dockercoins_redis:latest networks: - dockercoins worker: image: 192.168.2.11:8080/dockercoins/dockercoins_worker:latest networks: - dockercoins networks: dockercoins: external: true
拉取镜像
# docker-compose pull Pulling worker Digest: sha256:6f75cd9281ae6d5c68561d7917a8b21b9ce74f498d254da1b9cae990a965ffd3 Status: Downloaded newer image for 192.168.2.11:8080/dockercoins/dockercoins_worker:latest Pulling redis Digest: sha256:e14953e114bb12c396a3a69d1e648f1f676cbd746eea4397d6874ee0443acd1c Status: Downloaded newer image for 192.168.2.11:8080/dockercoins/dockercoins_redis:latest Pulling hasher Digest: sha256:9b37ea987721cd6cc99f645f3c85a0bf5c14cbdb90c50b3905ac342f319deb05 Status: Downloaded newer image for 192.168.2.11:8080/dockercoins/dockercoins_hasher:latest Pulling rng Digest: sha256:60d38f18bc33863d16dd75045da00d1625789c49a764be4dc92afa5ff6bdc629 Status: Downloaded newer image for 192.168.2.11:8080/ Pulling webui Digest: sha256:b328fa0c143959cccbbb1a9e8cea9f6aacdf54526eea5aab8810955bc9cf2ba4 Status: Downloaded newer image for 192.168.2.11:8080/dockercoins/dockercoins_webui:latest
可以看到拉取的五个镜像都有Digest信息。
生成DAB文件
[root@manager01 dockercoins]# docker-compose bundle WARNING: Unsupported top level key 'networks' - ignoring Wrote bundle to dockercoins.dab (compose v2里的networks参数目前还不支持所以出现告警并忽略,应用部署的时候自动创建一个overlay网络) # ls -lr -rw-r--r-- 1 root root 690 Nov 20 13:31 docker-compose.yml -rw-r--r-- 1 root root 1396 Nov 20 13:39 dockercoins.dab (dockercoins.dab文件成功生成) # cat dockercoins.dab { "Services": { "hasher": { "Image": "192.168.2.11:8080/dockercoins/dockercoins_hasher@sha256:9b37ea987721cd6cc99f645f3c85a0bf5c14cbdb90c50b3905ac342f319deb05", "Networks": [ "dockercoins" ], "Ports": [ { "Port": 80, "Protocol": "tcp" } ] }, "redis": { "Image": "192.168.2.11:8080/dockercoins/dockercoins_redis@sha256:e14953e114bb12c396a3a69d1e648f1f676cbd746eea4397d6874ee0443acd1c", "Networks": [ "dockercoins" ] }, "rng": { "Image": "192.168.2.11:8080/dockercoins/dockercoins_rng@sha256:60d38f18bc33863d16dd75045da00d1625789c49a764be4dc92afa5ff6bdc629", "Networks": [ "dockercoins" ], "Ports": [ { "Port": 80, "Protocol": "tcp" } ] }, "webui": { "Image": "192.168.2.11:8080/dockercoins/dockercoins_webui@sha256:b328fa0c143959cccbbb1a9e8cea9f6aacdf54526eea5aab8810955bc9cf2ba4", "Networks": [ "dockercoins" ], "Ports": [ { "Port": 80, "Protocol": "tcp" } ] }, "worker": { "Image": "192.168.2.11:8080/dockercoins/dockercoins_worker@sha256:6f75cd9281ae6d5c68561d7917a8b21b9ce74f498d254da1b9cae990a965ffd3", "Networks": [ "dockercoins" ] } }, "Version": "0.1" }
DAB文件内容比较长,主要是对每个服务进行描述,如服务名、镜像信息、端口信息等等。
需要注意的是DAB目前只支持Expose的端口,Published的端口会自动分配(从30000端口开始),不支持自定义,不过后面我们可以手动来修改。
部署Stack
[root@manager01 dockercoins]# docker deploy dockercoins Loading bundle from dockercoins.dab Creating network dockercoins_dockercoins Creating service dockercoins_hasher Creating service dockercoins_redis Creating service dockercoins_rng Creating service dockercoins_webui Creating service dockercoins_worker (注:Stacks的名字需要跟DAB文件名一致) [root@manager01 dockercoins]# docker network ls NAME DRIVER SCOPE bridge bridge local docker_gwbridge bridge local dockercoins overlay swarm dockercoins_dockercoins overlay swarm host host local ingress overlay swarm none null local (可以看到名为dockercoins_dockercoins的overlay网络被自动创建) [root@manager01 dockercoins]# docker service ls NAME REPLICAS dockercoins_hasher 1/1 dockercoins_redis 1/1 dockercoins_worker 1/1 dockercoins_webui 1/1 dockercoins_rng 1/1 (可以看到5个Service已经被创建且成功运行。 NAME为Service的名字,REPLICAS这个Service下面有多少个正在运行的容器,严格意义上来说应该是Task。 注:输出信息有ID,NAME,REPLICAS,IMAGE和COMMAND五列,为方便关键仅输出了NAME和REPLICAS列。) [root@manager01 dockercoins]# docker stack ps dockercoins NAME NODE CURRENT STATE dockercoins_worker.1 manager01.docanix.com Running 2 minutes ago dockercoins_webui.1 manager01.docanix.com Running 2 minutes ago dockercoins_rng.1 worker01.docanix.com Running about a minute ago dockercoins_redis.1 worker01.docanix.com Running about a minute ago dockercoins_hasher.1 manager01.docanix.com Running 2 minutes ago (可以看到dockercoins这个stack有5个容器运行,NAME为容器的名字,NODE为容器所在主机。 注:输出信息有ID,NAME,IMAGE,NODE,DESIRED STAT,CURRENT STATE和ERROR五列,为方便关键仅输出了NAME,NODE,CURRENT STATE列。)
应用访问
[root@manager01 dockercoins]# docker service inspect dockercoins_webui|grep -i publishedport "PublishedPort": 30002
由于Published的端口是自动分配的,我们需要去查看相应服务的端口。
可以看到dockercoins应用已经成功运行。
更改端口
如果我们需要自定义Published的端口也比较简单,通过docker service update
命令进行配置即可。
[root@manager01 dockercoins]# docker service update dockercoins_webui --publish-rm 80 dockercoins_webui [root@manager01 dockercoins]# docker service update dockercoins_webui --publish-add 8080:80 dockercoins_webui
访问测试
可以通过自定的8080端口访问应用。
服务扩展
使用docker service scale实现服务的在线手动扩展
# docker service scale dockercoins_worker=2 dockercoins_worker scaled to 2 (将dockercoins_worker服务扩展到2个副本) # docker service ls NAME REPLICAS dockercoins_hasher 1/1 dockercoins_redis 1/1 dockercoins_worker 2/2 dockercoins_webui 1/1 dockercoins_rng 1/1 (可以看到worker服务下面已经有2个副本在运行) # docker stack ps dockercoins NAME NODE CURRENT STATE dockercoins_webui.1 manager01.docanix.com Running 5 minutes ago dockercoins_worker.1 manager01.docanix.com Running 13 minutes ago dockercoins_redis.1 worker01.docanix.com Running 12 minutes ago dockercoins_hasher.1 manager01.docanix.com Running 13 minutes ago dockercoins_worker.2 manager01.docanix.com Running about a minute ago dockercoins_rng.2 worker01.docanix.com Running 3 minutes ago (名为dockercoins_worker.2的容器作为worker服务的第二个副本在manager01主机上运行)
访问测试
经过服务扩展至后,每秒生成的Docker币由4个变为6个。
Docker Stack和DAB的实际操作就到这里了,整体比较简单,有兴趣的朋友可以尝试一下。
总结
DAB作为体验功能特性还是有许多需要完善的地方,很多配置目前的DAB还不支持,比如自定义Published的端口,比如Volume的定义等等,不过从整体还是来说编排一些无状态的服务还是没多大问题的。
更何况,在开源的时代,体验版都出来了,正式版还会远吗?
评论前必须登录!
注册