参考文档:Get Started, Part 4: Swarms
Prerequisites
- 安装1.13或者更高版本的Docker
- 如Part 3中所说的安装Docker Compose
- 安装Docker Machine,Windows版本和Mac版本的Docker已经预先就有了,但是在Linux系统你需要直接安装。在Windows 10之前的版本(没有Hyper V),以及Windows 10 家庭版本使用Docker Toolbox
- 看Part 1中的内容
- 看Part 2中的内容学会如何创建container
- 确保你已经发布了
friendlyhello
镜像,你应应该在发布到registry这一节中创建了,在本节中我们将使用这个镜像 - 确保你的image作为一个部署了的容器一样运行,运行下面这个指令,将
username
,repo
,tag
三个换成你自己的docker run -p 80:80 username/repo:tag
,然后访问http://localhost/
- 复制你在Part 3中创建的
docker-compose.yml
文件
Introduction
在Part 3中,你已经知道怎么将Part 2中写的app运行起来了,并且定义了它在生产环境中应该如何运行,也就是作为一个服务,将其规模化,形成进程中的5个容器
在这里Part 4,你需要部署这个application在一个集群上(cluster),将其运行在多个机器上。通过将多台机器加入docker化的集群,多个容器多台机器的应用的程序将会形成,我们称之为集群(swarm)。
Understanding Swarm clusters
一个swarm是一组运行Docker的机器,他们的加入形成了cluster。之后,你继续运行你习惯的Docker指令,但是现在他们现在是通过swarm manager运行在一个cluster上。集群中的机器可以是实体的也可是虚拟的,通过加入一个集群,每一台机器称为一个结点(node)。
Swarm manager可以使用多种策略来运行容器,比如“emptiest node”策略,这个策略是指使用最少的已经有容器的主机(fills the least utilized machines with containers)。或者”global”策略,这个策略确保每一个机器只会获得一个特定容器的实例。你可以通过swarm manager来使用Compose文件中的这些策略,就像你已经使用了的。
Swarm managers是sawrm中唯一运行你的指令的那些机器,或者授权其他用户作为workers加入swarm。Workers是指那些提供能力(capacity)但是无权告诉其他机器能做什么或者不能做什么的。
直到现在,你一直使用Docker在一个单一主机的模式上。但是Docker同样可以切换到swarm模式,这样就可以使用swarm了。启动swarm mode立刻就会让当前的机器称为一个swarm manager。从这时起,Docker会在你管理的机器上运行指令,而不仅仅是当前的机器。
Set up your swarm
一个swarm由多个node组成,这些node可以是实体机器也可以是虚拟机器。最基本的概念非常简单,运行docker swarm init
就可以启动swarm模式,让你当前的机器成为swarm manager了,然后运行docker swarm join
在其他的机器上,这样别的机器就可以作为workers加入。选择下面之一的一个tab,去看看如何在多个环境下做这些事情。我们这里使用虚拟机来快速创建一个包含两个机器的cluster,并且将其转化为一个swarm。
Create a cluster
VMS ON YOUR LOCAL MACHINE (MAC, LINUX, WINDOWS 7 AND 8)
这里只翻译Local VM(Mac, Linux, Windows 7 and 8)部分,Local VMs(Windows 10/Hyper-V)请见doc
你需要一个可以创建虚拟机的管理程序(hypervisor),所以安装适合你机器系统的Oracle VirtualBox。
注意:如果你使用已安装Hyper-V的Windows系统,比如Windows 10,那么就不需要安装VirtualBox了,并且你应该直接使用Hyper-V。通过另一个tab(就是没翻译的那部分)查看Hyper-V的使用教程。如果你咋使用Docker Toolbox,你应该已经安装了VirtualBox,所以你可以继续了。
现在,使用docker-machine
创建一系列虚拟机,使用Virtualbox driver:
1 | docker-machine create --driver virtualbox myvm1 |
LIST THE VMS AND GET THEIR IP ADDRESSES
现在你有两个虚拟机了,名字为myvm1
和myvm2
使用这个指令列出这些主机,并且获取他们的ip地址
1 | $ docker-machine ls |
INITIALIZE THE SWARM AND ADD NODES
第一个机器作为manager,它来执行指令,控制其他worker加入swarm,第二个十一个worker。
你可以通过使用docker-machine ssh
来将指令发送到虚拟机上。在myvm1
上执行docker swarm init
指令使之成为swarm manager,然后你会看到这样的输出:
1 | $ docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>" |
端口2377和2376
总是通过运行docker swarm init
和docker swarm join
在2377端口(这个端口是swarm的管理端口),或者不指定端口让其使用默认端口
通过docker-machine ls
返回的机器IP地址包括了2376,这个是Docker守护进程的端口,不要占用这个端口,否则你会遇到一些错误使用SSH的时候遇到了问题?试试加上
--native-ssh
标记
Docker Machine允许你使用系统的SSH,如果因为某种原因你无法向你的Swarm manager发送指令,那么使用--native-ssh
标记当使用ssh
指令的时候docker-machine --native-ssh ssh myvm1 ...
如你所见,docker swarm init
指令的反馈包含了一句配置好的docker swarm join
指令,你可以用他运行在任何nodes上。复制这个指令,通过docker-machine ssh
指令发送到myvm2
上,让你的myvm2
加入你的swarm。
1 | $ docker-machine ssh myvm2 "docker swarm join \ |
恭喜你,你已经创建好了一个swarm了。
运行docker node ls
在manager机器上,就可以看到swarm中的集群了
脱离一个swarm
如果你想重来,你可以在node上运行docker swarm leave
来脱离swarm
Deploy your app on the swarm cluster
最难的部分已经结束了,现在你可以重复你在part 3的过程来部署你的swarm了。但是记住一点,只有像myvm1
一样的manager具有执行docker指令的权力,其他的worker只是用来被调用资源的(for their capacity)。
Configure a docker-machine
shell to the swarm manager
目前位置,你已经把Docker指令包装在了docker-machine ssh
中发送给了虚拟机。另一个选择是运行docker-machine env <machine>
来获取和运行一个指令从而配置你当前的Shell,让其将指令传送给虚拟机中的Docker守护进程。这个方法对于下一步效果更好,因为他允许你使用本地的docker-compose.yml
文件来远程部署你的文件,而不用把它复制来复制去。
键入docker-machine env myvm1
,然后复制粘贴运行你向myvm1
发送指令时输出的最后一行。
输出的指令会因为你是Mac/Linux/Windows系统的不同而不同,下面列出了不同系统的反馈实例
Mac, Linux
DOCKER MACHINE SHELL ENVIRONMENT ON MAC OR LINUX
运行docker-machine env myvm1
来获取指令,然后配置你的shell向myvm1
发送指令
1 | $ docker-machine env myvm1 |
运行给出的指令
1 | eval $(docker-machine env myvm1) |
运行docker-machine ls
来验证myvm1
是一个活跃的机器,如同下面的*
所表示的那样
1 | $ docker-machine ls |
Windows
运行docker-machine env myvm1
来获取指令,然后配置你的shell向myvm1
发送指令
1 | PS C:\Users\sam\sandbox\get-started> docker-machine env myvm1 |
运行给出的指令
1 | & "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression |
运行docker-machine ls
来验证myvm1
是一个活跃的机器,如同下面的*
所表示的那样
1 | PS C:PATH> docker-machine ls |
Deploy the app on the swarm manager
现在你有myvm1
了,你可以发挥他作为swarm manager的作用来部署你的app,通过和part 3中你用过的相同的指令docker stack deploy
,以及你本地的docker-compose.yml
文件。这个指令可能需要花几秒来完成,部署同样需要一些时间。使用docker service ps <service_name>
指令来验证是否所有的服务都被重新部署了。
你现在通过docker-machine
来连接到myvm1
,你仍然可以访问你主机的文件,确保你已经在相同的文件目录下了,也就是说会有一个你在part3中创建的docker-compose.yml
文件。
如同之前,运行下面的指令来在myvmm1
上部署你的app。
1 | docker stack deploy -c docker-compose.yml getstartedlab |
就这样,你的app部署在一个swarm的cluster上了。
注意:如果你的镜像存储在私有的registry而不是Docker Hub上,你需要使用
docker login <your-registry>
来登录你的registry,然后你需要对上面的指令添加--with-registry-auth
标记,比如:
1
2
3 docker login registry.example.com
docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab这会发送你登录的令牌到你部署服务的swarm结点上,使用加密的WAL日志。有了这个信息,结点就可以登录到registry上并且把image给pull下来。
现在你可以使用part 3中相同的docker指令了。不过请注意,这里指令会被部署到myvm1
和myvm2
上。
1 | $ docker stack ps getstartedlab |
通过
docker-machine env
和docker-machine ssh
连接到虚拟机
- 为了让你的Shell向不同的机器发送指令(比如
myvm2
),重新执行docker-machine env
在相同或者不同的Shell中,然后运行给出的指向myvm2
的指令。这个总是针对当前的shell。如果你切换到一个未识别的shell或者新开一个,你需要重新运行指令。使用docker-machine ls
来列出所有机器,看他们是什么状态,获得他们的IP地址,找出你正在连接哪个。更多资料请访问Docker Machine getting started topics- 或者,你可以把指令包装在
docker-machine ssh <machine> "<command>"
,但是日志会直接记录在虚拟机中,并不会给你任何访问你本机的权力- 在Mac和Linux中,你可以使用
docker-machine scp <file> <machine>:~
指令来将文件在多个机器间拷贝,但是Windows用户需要像Git Bash这种的Linux终端来进行此类操作。这个教程展现了
docker-machine ssh
和docker-machine env
,由于这些在全平台的docker-machine
客户端上都可用。
Accessing your cluster
你可以访问你的app通过myvm1
或者myvm2
的IP地址。
你创建的网络对于两者来说是共享的,并且可以实现负载均衡。运行docker-machine ls
来获取你的虚拟机的IP地址,然后访问两者中的任意一个,然后点击刷新。
总共有5个可能的container ID,随机循环,表示负载均衡。
两个IP都有效的原因是swarm中的nodes参与了一个ingress routing mesh。这确保了你的swarm中部署在一个特定端口的一个服务总是有留给自身的端口,不管哪个node实际上在运行容器。这有一个图可以表示一个名为my-web
的服务的routeing mesh,这个服务发布在8080端口,是一个三结点的swarm:
有连接问题?
记住,在swarm中使用ingress网络,你需要在你开启swarm mode前在swarm node间开启这些端口
- 7946端口 TCP/UDP for container network discovery.
- 4789端口 UDP for the container ingress network.
Iterating and scaling your app
在这里你可以做你在part 2和part 3中学习的东西了。
通过更改docker-compose.yml
文件来规模化你的app。
通过修改代码来更改app行为,然后重建,然后push新的image。(按照你之前学习的build the app和publish the image来)
不管在哪个情况下,只运行docker stack deploy
一次来部署这些改变。
你可以加入任何的机器,实体的或者虚拟的,通过使用docker swarm join
命令,如同你使用在myvm2
上的一样,新的capacity会加入你的cluster。通过使用docker stack depoly
,你的app可以利用新的资源。
Cleanup and reboot
Stacks and swarms
你可以通过docker stack rm
指令来拆掉stack,比如
1 | docker stack rm getstartedlab |
保留swarm还是移除他?
在后面的某些时候,你能够移除这个swarm,通过在worker机上运行docker-machine ssh myvm2 "docker swarm leave"
以及在manager机器上运行docker-machine ssh myvm1 "docker swarm leave --force"
,但是在Part 5中你需要这个swarm,所以暂时先留着他吧
Unsetting docker-machine shell variable settings
在你当前的shell中,通过以下指令,你可以重置docker-machine
的环境变量:
1 | eval $(docker-machine env -u) |
这会让shell和docker-machine
创建的虚拟机分开,并且允许你继续在相同的shell下工作,现在使用本地的docker
指令(比如,在Docker for Mac或者Docker for Windows)。了解更多,请看Machine topic on unsetting environment variables
Restarting Docker machines
如果你关掉你的本地主机,Docker machine会停止运行。你可以检查机器的状态通过运行docker-machine ls
命令
1 | $ docker-machine ls |
想要重启已经停止的机器,运行:
1 | docker-machine start <machine-name> |
比如,
1 | $ docker-machine start myvm1 |
Recap and cheat sheet (optional)
在Part4中,你学习了Swarm是什么,swarm中的nodes如何成为manager或者worker,创建一个swarm,并且在上面部署一个应用,你可以看到Docker核心指令从Part3开始就没有变化,他们只是必须要被运行在swarm manager上。你也看到了Docker的网络方面的能力,这保证了container之间的负载均衡,尽管他们运行在不同的机器上,最后,你学习了如何iterate和scale你的app在cluster上。
1 | docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux) |