参考文档:Get Started, Part 5: Stacks
Prerequisites
- 安装1.13版本或者更高版本的Docker
- 完成Part 3的prerequisites部分的Docker Compose
- 完成Part 4的prerequisites部分的Docker Machine
- 阅读Part 1
- 阅读Part 2学习如何创建container
- 确保你已经发布了
friendlyhello
镜像,我们使用这个共享镜像 - 确保你的的镜像像一个部署的容器一样运行,运行这个指令,替换
username
,repo
,tag
为你自己的信息docker run -p 80:80 username/repo:tag
,然后访问http://localhost/
- 拷贝一份你在Part 3中的
docker-compose.yml
文件 - 确保Part 4中创建的机器出于运行状态。运行
docker-machine ls
来验证这个,如果机器处于stop状态,运行docker-machine start myvm1
来启动manager,然后运行docker-machine start myvm2
来启动worker机器。 - 确保你在Part 4中创建的swarm是好的,运行
docker-machine ssh myvm1 "docker node ls"
来验证。如果swarm是活跃的,nodes会返回ready
状态。如果不是,重新初始化swarm并且加入swarm,如同Set up your swarm章节的内容。
Introduction
在part 4中,你已经学习了如何设置一个swarm,swarm也就是一串运行docker的机器,并且在其上部署了应用,多个容器在多台机器上共同发挥作用。
现在在part 5,你已经到达了分布式应用的最高层——stack。一个stack是一组相互关联的服务,他们有着共同的依赖,他们可以一起协作。一个单独的stack可以定义与协调整个应用的功能性,尽管复杂的应用可能需要多个stack。
但是也有一个好消息,你已经在技术上在part 3中使用了stack技术,当你创建一个compose file的时候,然后使用docker stack deploy
。但是这只是一个单独的service stack运行在单一主机上,在真实的生产中通常不会是这样的。现在,你可以使用你学习的东西,创建多个相互关联的services,并且将他们运行在多台机器上。
You’re doing great, this is the home stretch!
Add a new service and redeploy
在我们的docker-compose.yml
文件中添加service非常容易,首先,让我们先加一个免费的可视化服务,让我们看我们的swarm是如何管理container的。
1、 在编辑器中打开docker-compose.yml
,将下面的文件替换原有文件。确保将username/repo:tag
替换为你自己的image信息
1 |
|
这里唯一新的东西是对于web
的点服务(peer service),叫做visualizer
。注意这里的两个事情:一个是名为volumes
的键,这个键给了visualizer对于Docker访问主机的socket文件,另一个是placement
键,这个键保证了这个服务只会运行在swarm manager上,而不是worker机上。因为这个创建于Docker开源项目的container展示了运行在swarm上的Docker服务的图形化界面。
2、确保shell配置好来执行myvm1
主机了(如果你不知道怎么做,点击这里)
- 运行
docker-machine ls
来列出所有的机器,确保你连接到myvm1
主机,成功的话会有*
在Active一栏中。 - 如果需要,运行
docker-machine env myvm1
,然后运行给出的指令来配置shell
在Mac和Linux下指令是
1 | eval $(docker-machine env myvm1) |
在Windows中指令是:
1 | & "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression |
3、在manager机器上重运行docker stack deploy
指令,然后所有需要更新的服务都会更新
1 | $ docker stack deploy -c docker-compose.yml getstartedlab |
4、去看看visualizer
在Compose file中,你看到了visualizer
运行在8080端口。访问这两个虚拟机中的任意一个ip的8080端口,你可以看到visualizer运行着:
唯一一个visualizer
正在你希望看到的manager机器上运行,另外五个web
的实例分布在swarm上。你可以通过docker stack ps <stack>
指令对其进行协作:
1 | docker stack ps getstartedlab |
这个visualizer十一个独立的service,他可以运行在任何在栈中包含该service的app中,他不需要依赖任何其他的东西。现在我们创建一个需要依赖的服务:Redis服务。这个服务作为一个visitor存在。
Persist the data
让我们再次做一遍相同的工作流来将用于存储app数据的Redis服务添加进来。
1、保存新的docker-compose.yml
文件,这个文件最终添加了Redis服务。确保将username/repo:tag
替换为你自己的镜像信息:
1 |
|
Redis在Docker库中有官方镜像,他已经被授予了短名镜像,你只需要输入redis
即可,所以这里就不用以username/repo
的格式了。Redis的6379端口已经被预先配置好了,这样就可以从容器暴露给主机,同时在这个compose file中,我们将其从主机暴露给外界,所以你可以在Redis Desktop Manager中输入任何一个节点的ip地址来管理这些Redis实例。
更重要的是,有一些事情在redis的指定配置中,使数据持久化于栈的开发过程中:
- redis总是运行在manager上,所以他总是有相同的文件系统
- redis访问主机文件系统
/data
的任意的目录,这里也就是Redis储存数据的地方
总的来说,这正在你的主机的物理文件系统中创建一个「source of truth」用于Redis数据。没有这些,Redis会存储数据在容器文件系统的/data
目录下,这样的话一旦容器被重新部署了,数据就会被抹除。
这个「source of truth」有两个部分组成:
- 你对于Redis服务设置的placement constraint,确保他一直使用相同的host
- 你创建的让容器访问
./data
作为访问/data
的volume。尽管容器会被删除和创建,但是存储在特定主机上的./data
数据会持久化。
你已经准备好创建你的新的使用Redis的stack了。
2、在manager上创建一个./data
目录
1 | docker-machine ssh myvm1 "mkdir ./data" |
3、确保你的shell已经配置好用于向myvm1
输入指令了。
- 运行
docker-machine ls
来显示出所有的机器,确保你已经连接到myvm1
,这样的话旁边会有一个*
的标志 - 如果需要,重新运行
docker-machine env myvm1
,然后运行给出的指令来配置shell。
在Mac和Linux下指令是
1 | eval $(docker-machine env myvm1) |
在Windows中指令是:
1 | & "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression |
4、运行docker stack deploy
依次
1 | docker stack deploy -c docker-compose.yml getstartedlab |
5、运行docker service ls
来验证这三个服务是否按照预期的运行了
1 | docker service ls |
6、访问你的任意一个节点,比如http://192.168.99.101
,看看访客计数器,现在已经可以用了,并且存储了Redis的数据。
与此同时,访问8080端口的visualizer,你可以注意到redis
服务和web
服务、visualizer
服务一同运行了