5. Stacks
介绍
在第4部分,你已经学会如何配置一个蜂群,蜂群是一个运行着docker的集群,然后你将app部署到这个蜂群上,容器运行在多个机器上。
在第5部分,我们马上介绍分布式应用层级的最上层的概念stack。一个stack是一组共享依赖的内部相关的服务,这些服务能够被一起编排和伸缩。单独的一个stack能够定义和协调整个应用的功能,一些复杂的应用可能需要定义多个stack。
不要慌,从第3部分开始,我们就已经接触到了stack,前面我们创建compose文件,然后运行docker stack deploy,这些都是和stack相关的内容。但是前面我们接触的都是运行在单台机器上的包含单个服务的stack,这个在生产环境中不常见。接下来,运用之前学到的知识,我们来创建多个相关的服务,然后运行在多台机器上。
增加一个Service 重新部署
修改docker-compose.yml文件很容易添加一个服务。首先我们增加一个免费的可视化服务,这个服务可以让我们看我们的蜂群是如何调度我们的容器的。
- 打开docker-compose.yml文件,修改为如下内容:
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上,因为可视化服务是显示蜂群概览信息的,仅仅管理器才有权限获取到这些信息。
- 确保你的shell连接到myvm1机器上。docker-machine start $(docker-machine ls -q)启动所有机器
- 运行docker-machine ls确保你连接到myvm1上。如果出现ip地址对应的cert不对应,则重新运行命令生成cert,docker-machine regenerate-certs $(docker-machine ls -q)
2. 如有必要运行 eval \$(docker-machine env myvm1)
- 在蜂窝管理器上重新运行 docker stack deploy
docker stack deploy -c docker-compose-yml getstartedlab
部署完成后查看服务:
访问可视化服务:
![](/qrcode.jpg)
可以看到两个服务:visualizer和web均已经启动,且web服务的副本数量为5,分布为:
- myvm1*1
- myvm2*2
- myvm3*2
也可以使用docker命令查看:
docker stack ps getstartedlab
持久化数据
到现在为止,我们的web服务中依赖的redis服务还没有配置。
- 修改docker-compose文件,增加redis服务
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目录,而容器启动, 停止后,里面的数据都没有了。因此为了持久化数据,需要将容器的某些目录映射到宿主机上,这样数据才会被真正的持久化。
- 在manager宿主机上创建data目录
docker-machine ssh myvm1 "mkdir ./data"
- 部署
docker stack deploy -c docker-compose.yml getstartedlab
查看浏览器验证:
查看持久化生效: