Docker Stack and DAB 入门

理论

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 rundocker-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的定义等等,不过从整体还是来说编排一些无状态的服务还是没多大问题的。

更何况,在开源的时代,体验版都出来了,正式版还会远吗?

分享到:更多 ()