5. Stacks

5. Stacks

介绍

在第4部分,你已经学会如何配置一个蜂群,蜂群是一个运行着docker的集群,然后你将app部署到这个蜂群上,容器运行在多个机器上。

在第5部分,我们马上介绍分布式应用层级的最上层的概念stack。一个stack是一组共享依赖的内部相关的服务,这些服务能够被一起编排和伸缩。单独的一个stack能够定义和协调整个应用的功能,一些复杂的应用可能需要定义多个stack。

不要慌,从第3部分开始,我们就已经接触到了stack,前面我们创建compose文件,然后运行docker stack deploy,这些都是和stack相关的内容。但是前面我们接触的都是运行在单台机器上的包含单个服务的stack,这个在生产环境中不常见。接下来,运用之前学到的知识,我们来创建多个相关的服务,然后运行在多台机器上。

增加一个Service 重新部署

修改docker-compose.yml文件很容易添加一个服务。首先我们增加一个免费的可视化服务,这个服务可以让我们看我们的蜂群是如何调度我们的容器的。

  1. 打开docker-compose.yml文件,修改为如下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: dockerjie/get-started:part2
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "4000:80"
networks:
- webnet
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
networks:
webnet:

注意上面有两个新的配置项,volumes,运行可视化服务访问宿主机的Docker的socket文件,placement则确保服务被部署在蜂群管理器swarm manager上面,而不是worker上,因为可视化服务是显示蜂群概览信息的,仅仅管理器才有权限获取到这些信息。

  1. 确保你的shell连接到myvm1机器上。docker-machine start \$(docker-machine ls -q)启动所有机器
    1. 运行docker-machine ls确保你连接到myvm1上。如果出现ip地址对应的cert不对应,则重新运行命令生成cert,docker-machine regenerate-certs \$(docker-machine ls -q)

image.png | left | 625x59

1
2. 如有必要运行 eval \$(docker-machine env myvm1)

image.png | left | 625x72

  1. 在蜂窝管理器上重新运行 docker stack deploy
    1
    docker stack deploy -c docker-compose-yml getstartedlab

部署完成后查看服务:

image.png | left | 681x47

访问可视化服务:

image.png | left | 681x666

可以看到两个服务:visualizer和web均已经启动,且web服务的副本数量为5,分布为:

  • myvm1*1
  • myvm2*2
  • myvm3*2

也可以使用docker命令查看:

1
docker stack ps getstartedlab

image.png | left | 681x75

持久化数据

到现在为止,我们的web服务中依赖的redis服务还没有配置。

  1. 修改docker-compose文件,增加redis服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: dockerjie/get-started:part2
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "4000:80"
networks:
- webnet
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
redis:
image: redis
ports:
- "6379:6379"
volumes:
- "/home/docker/data:/data"
deploy:
placement:
constraints: [node.role == manager]
command: redis-server --appendonly yes
networks:
- webnet
networks:
webnet:

redis有官方的镜像,因此具有一个short name redis。6379是redis容器预先配置的端口,需要对外暴露的,我们也暴露这个端口给宿主机。有两个额外的配置只得注意:

  • redis一直运行在manager上,因此它一直运行在相同的文件系统上,因为是同一个宿主机。
  • redis访问宿主机上的文件夹作为/data目录,redis将数据存储到这里。

redis需要持久化数据到容器里的/data目录,而容器启动, 停止后,里面的数据都没有了。因此为了持久化数据,需要将容器的某些目录映射到宿主机上,这样数据才会被真正的持久化。

  1. 在manager宿主机上创建data目录

    1
    docker-machine ssh myvm1 "mkdir ./data"
  2. 部署

1
docker stack deploy -c docker-compose.yml getstartedlab

image.png | left | 681x61

查看浏览器验证:

image.png | left | 747x698

查看持久化生效:

image.png | left | 681x214