了解Swarm集群
Swarm集群是一组运行Docker并加入集群的计算机。但现在它们由集群管理器控制在集群上执行。群中的机器可以是物理的或虚拟的。加入群组后,它们被称为节点。
Swarm管理器可以使用多种策略来运行容器,例如“emptiest node” - 它使用容器利用率最低的机器。或“global”,它确保每台机器只获得指定容器的一个实例。您可以使用Compose文件指定这些策略。
Swarm管理器是群中唯一可以执行命令的机器,或授权其他机器作为worker加入Swarm管理器。worker只是在那里提供工作能力,没有权力告诉任何其他机器能做什么和不能做什么。
到目前为止,一直在本地计算机上以单主机模式使用Docker。但Docker也可以切换到swarm模式,这就是使用群集的原因。立即启用Swarm集群模式使当前计算机成为swarm管理器。从现在起,Docker指令就会运行在swarm集群上,而不仅仅是在当前机器上。
开启集群模式
群由多个节点组成,可以是物理或虚拟机。基本概念很简单:运行docker swarm init
以启用swarm模式并使当前计算机成为一个swarm管理器,然后在其他计算机上运行docker swarm join
以使它们作为worker加入swarm。我们使用VM快速创建一个双机群集并将其转换为swarm集群。
创建一个集群
本地计算机上的VM(MAC,LINUX,WINDOWS 7和8)
您需要一个可以创建虚拟机(VM)的虚拟机管理程序,因此为您的计算机操作系统安装Oracle VirtualBox。
注意:如果您使用的是安装了Hyper-V的Windows系统(如Windows 10),则无需安装VirtualBox,而应使用Hyper-V。如果你使用的是Docker Toolbox,你应该已经安装了VirtualBox作为其中的一部分。就不用安装了。
现在,docker-machine
使用VirtualBox驱动程序创建几个VM :
docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2
本地计算机上的VM(WINDOWS 10)
首先,快速创建虚拟交换机以供虚拟机(VM)共享,以便它们可以相互连接。
- 启动Hyper-V管理器
- 单击右侧菜单中的虚拟交换机管理器
- 单击新建虚拟网络交换机,类型为外部
- 为其命名
myswitch
,然后选中该框以共享主机的活动网络适配器
创建虚拟网络交换机
创建完成
现在,使用我们的节点管理工具创建几个VM docker-machine
:
注意:您需要以管理员身份运行以下命令,否则您无权创建hyperv VM!
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm2
创建完成
列出虚拟机并获取其IP地址
您现在创建了两个名为myvm1
和的VM myvm2
。
使用此命令列出计算机并获取其IP地址。
注意:您需要以管理员身份运行以下命令,否则您将无法获得合理的输出(仅“未知”)。
docker-machine ls
以下是此命令的示例输出。
C:\Windows\system32>docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - hyperv Running tcp://192.168.1.100:2376 v18.09.6
myvm2 - hyperv Running tcp://192.168.1.102:2376 v18.09.6
初始化SWARM并添加节点
第一台机器充当管理器,它执行管理命令并验证worker加入群,第二台是worker。
您可以使用命令docker-machine ssh
向VM发送命令。使myvm1
成为一个swarm管理器即在myvm1
上执行docker swarm init
并查找如下输出:
docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>"
C:\Windows\system32>docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.1.100"
Swarm initialized: current node (dvlpu7zv6kkwg2qr3dpa0sk3k) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-4x24xi9xtm4pbu42py3fugh2lee1cekodzy8rt8e82nq99rtgh-00i3d8t9sh6445n4akxe71zkf 192.168.1.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
C:\Windows\system32>
端口2377和2376
docker swarm init
和docker swarm join
使用端口2377(集群管理端口),没有给定端口的时候,使用这个默认值。
docker-machine ls
返回的计算机IP地址包含端口2376 ,即Docker守护程序端口。请勿使用此端口,否则 您可能会遇到错误。
使用SSH时遇到问题?试试--native-ssh标志
Docker Machine 可以让您使用自己系统的SSH,如果由于某种原因您无法向Swarm管理器发送命令。只需
--native-ssh
在调用ssh
命令时指定 标志:docker-machine --native-ssh ssh myvm1 ...
如您所见,响应docker swarm init
包含一个预先配置的 docker swarm join
命令,您可以在要添加的任何节点上运行该命令。复制此命令,并将其发送到myvm2
比如 docker-machine ssh
将myvm2
作为worker加入到swarm集群:
$ docker-machine ssh myvm2 "docker swarm join \
--token <token> \
<ip>:2377"
This node joined a swarm as a worker.
示例输出:
C:\Windows\system32>docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - hyperv Running tcp://192.168.1.100:2376 v18.09.6
myvm2 - hyperv Running tcp://192.168.1.102:2376 v18.09.6
C:\Windows\system32>docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.1.100"
Swarm initialized: current node (dvlpu7zv6kkwg2qr3dpa0sk3k) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-4x24xi9xtm4pbu42py3fugh2lee1cekodzy8rt8e82nq99rtgh-00i3d8t9sh6445n4akxe71zkf 192.168.1.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
C:\Windows\system32>docker-machine ssh myvm2 "docker swarm join --token SWMTKN-1-4x24xi9xtm4pbu42py3fugh2lee1cekodzy8rt8e82nq99rtgh-00i3d8t9sh6445n4akxe71zkf 192.168.1.100:2377"
This node joined a swarm as a worker.
万一token 被清除了咋办?执行docker swarm join-token worker|manager
命令:
PS F:\dockerExample> docker-machine ssh myvm1 "docker swarm join-token worker"
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3oarvifh2gcrbogkim66wj9enk0exh5r3jn1oagqrpp6tynds6-1wcidoxi0hilmuxgrvw0tdu8n 192.168.1.100:2377
PS F:\dockerExample>
恭喜你,你已经创建了你的第一个集群!
使用docker node ls
在swarm管理器上运行以查看此群中的节点:
C:\Windows\system32>docker node ls
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
C:\Windows\system32>docker-machine ssh myvm1 "docker node ls"
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
dvlpu7zv6kkwg2qr3dpa0sk3k * myvm1 Ready Active Leader 18.09.6
gvhr76swgxf98i22lzilrbq3f myvm2 Ready Active 18.09.6
离开集群
可以在节点上运行
docker swarm leave
C:\Windows\system32>docker-machine ssh myvm2 "docker swarm leave"
Node left the swarm.
C:\Windows\system32>docker-machine ssh myvm1 "docker node ls"
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
dvlpu7zv6kkwg2qr3dpa0sk3k * myvm1 Ready Active Leader 18.09.6
gvhr76swgxf98i22lzilrbq3f myvm2 Down Active 18.09.6
# 可以看到不是真的离开了集群,只是状态变为Down了,重新连一下:
PS F:\dockerExample> docker-machine ssh myvm2 "docker swarm join --token SWMTKN-1-3oarvifh2gcrbogkim66wj9enk0exh5r3jn1oagqrpp6tynds6-1wcidoxi0hilmuxgrvw0tdu8n 192.168.1.100:2377"
This node joined a swarm as a worker.
PS F:\dockerExample> docker-machine ssh myvm1 "docker node ls"
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
w4pvuf32jsatq0q8g89tq5sm8 * myvm1 Ready Active Leader 18.09.6
pxl1s3glvsxmdg14c5sj3w2bh myvm2 Ready Active 18.09.6
qr2nfew2478b5wriz7d3edxow myvm2 Down Active 18.09.6
PS F:\dockerExample> docker-machine ssh myvm1 "docker node rm myvm2"
Error response from daemon: node myvm2 is ambiguous (2 matches found)
exit status 1
# 多了一个myvm2,状态为Down,作为一个强迫症,我要删除它
PS F:\dockerExample> docker-machine ssh myvm1 "docker node rm qr2nfew2478b5wriz7d3edxow"
qr2nfew2478b5wriz7d3edxow
PS F:\dockerExample> docker-machine ssh myvm1 "docker node ls"
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
w4pvuf32jsatq0q8g89tq5sm8 * myvm1 Ready Active Leader 18.09.6
pxl1s3glvsxmdg14c5sj3w2bh myvm2 Ready Active 18.09.6
计算机异常关机了,或者说正常重启之后,通过hyper-v创建的虚拟机地址变了咋办?
其实在创建完成虚拟机之后就给它设置静态ip,通过本教程创建的虚拟机的操作系统类型是tinycorelinux
如果想给他配置静态ip,可以执行docker-machine ssh myvm*
去修改网络配置文件,但是很不幸,我没找到相关资料,所以我决定删除它们,通过docker-machine rm myvm*
删除虚拟机,如果报错exit code 1 之类的话,执行docker-machine rm -f myvm*
,再去hyper-v管理器中手动删除虚拟机,再重新创建一边就好,当然,你如果找到了tinycorelinux的网络配置文件,也可以跟我说一下
在群集群集上部署您的应用程序
请记住,Swarm管理器
myvm1
才能执行Docker命令; woker只是为了干活。
使用docker-machine
为swarm管理器配置shell
到目前为止,我们都是通过docker-machine ssh
命令与VM通信中。另一种更方便的方式是执行docker-machine env <machine>
获取一个命令,该命令将当前shell配置为与VM上的Docker守护程序通信,即将当前命令行的输入转发到虚拟机执行。在执行下一步之前,最好执行这个命令,因为它允许您使用本地docker-compose.yml
文件“远程”部署应用程序,而无需将该文件复制到虚拟机
键入docker-machine env myvm1
,复制输出的最后一行提供的命令并运行,以配置要与之通信的shell(myvm1
swarm管理器)。记住,只有swarm管理器才能执行docker命令,worker 只是干活的
配置shell的命令在Mac,Linux或Windows上是不同的
MAC或LINUX上的Docker 配置shell
运行docker-machine env myvm1命令获取与 myvm1配置shell的命令。
$ docker-machine env myvm1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.1.100:2376"
export DOCKER_CERT_PATH="/Users/sam/.docker/machine/machines/myvm1"
export DOCKER_MACHINE_NAME="myvm1"
# Run this command to configure your shell:
# eval $(docker-machine env myvm1)
WINDOWS上的DOCKER机器SHELL环境
运行docker-machine env myvm1命令获取与 myvm1配置shell的命令。
PS C:\Users\sam\sandbox\get-started> docker-machine env myvm1
$Env:DOCKER_TLS_VERIFY = "1"
$Env:DOCKER_HOST = "tcp://192.168.203.207:2376"
$Env:DOCKER_CERT_PATH = "C:\Users\sam\.docker\machine\machines\myvm1"
$Env:DOCKER_MACHINE_NAME = "myvm1"
$Env:COMPOSE_CONVERT_WINDOWS_PATHS = "true"
# Run this command to configure your shell:
# & "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
运行给定命令来配置与myvm1
通信的shell 。
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
运行docker-machine ls
来验证myvm1
是活动计算机(Active列为*)。
PS C:PATH> docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 * hyperv Running tcp://192.168.203.207:2376 v17.06.2-ce
myvm2 - hyperv Running tcp://192.168.200.181:2376 v17.06.2-ce
在swarm管理器上部署应用程序
现在你配置了本地shell连接到myvm1
,您可以使用本地shell作为Swarm管理器,它现在也可以访问你本地计算机上的文件,通过使用docker stack deploy
命令以及本地docker-compose.yml
文件来部署您的应用程序。部署需要一些时间才能完成。使用docker service ps <service_name>
命令验证是否已部署所有服务。
与以前一样,运行以下命令部署应用程序:
docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
就是这样,应用程序部署在一个多机集群中!
注意:如果您的映像存储在私有仓库而不是Docker Hub上,则需要使用登录
docker login <your-registry>
,然后需要将--with-registry-auth
标志添加到部署命令中。例如:docker login registry.example.com docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
这会使用加密的WAL日志将登录令牌从本地客户端传递到部署服务的swarm节点。有了这些信息,节点就可以登录注册表并提取图像。
现在,您可以使用docker stack ps getstartedlab
命令查看堆的状态。只是这一次的服务(和相关容器)已经在myvm1
和myvm2
两者上都有部署。
$ docker stack ps getstartedlab
ID NAME IMAGE NODE DESIRED STATE
jq2g3qp8nzwx getstartedlab_web.1 gordon/get-started:part2 myvm1 Running
88wgshobzoxl getstartedlab_web.2 gordon/get-started:part2 myvm2 Running
vbb1qbkb0o2z getstartedlab_web.3 gordon/get-started:part2 myvm2 Running
ghii74p9budx getstartedlab_web.4 gordon/get-started:part2 myvm1 Running
0prmarhavs87 getstartedlab_web.5 gordon/get-started:part2 myvm2 Running
使用
docker-machine env
和docker-machine ssh
连接到VM
- 要将shell设置为与其他机器通信,只需将命令
docker-machine env <machine>
输出的最后一行命令,在相同或不同的shell中运行。这始终特定于当前shell。如果更改为未配置的shell或重新打开的shell,则需要重新运行。
- 或者,使用命令
docker-machine ssh <machine> "<command>"
直接发送到VM中,但不能访问本地主机上的文件。你需要用scp命令或者类似的远程拷贝工具来拷贝本地文件到远程
- 在Mac和Linux上,您可以使用
docker-machine scp <file> <machine>:~
跨机器复制文件,但Windows用户需要像Git Bash这样的Linux终端模拟器才能正常执行。本教程演示的
docker-machine ssh
和docker-machine env
,他们可以在任何平台执行
访问集群上的应用
你可以用myvm1
或myvm2
的IP地址来访问你的应用程序 。
它们之间共享网络并进行负载均衡。运行 docker-machine ls
获取VM的IP地址,并在浏览器上访问其中任何一个,点击刷新(或者执行curl
命令)。
HostName有五种可能,都是五个容器ID中的一个,这表明进行了负载均衡。
两个IP地址都可以正常访问的原因是群中的节点都加入了路由网格。这可确无论实际运行容器的是哪个节点,部署在swarm中某个端口的服务始终将该端口保留给自身,下面是一个图表,说明在三节点群上上发布的端口为8080
的my-web
服务的路由网格:
连接时候出了问题?
请记住,要在群集中使用ingress network,您需要在启用群集模式之前在群集节点之间打开以下端口:
- 端口7946 TCP / UDP用于容器网络发现。
- 端口4789 UDP 用于容器ingress network。
仔细检查您的Web服务端口,并确保您在浏览器中输入的IP地址正确
迭代和扩展您的应用程序
通过更改docker-compose.yml
文件来扩展应用程序。
通过编辑代码,可以重建并推送新图像来更改应用程序行为。
在任何情况下,只需再次运行docker stack deploy
即可部署这些更改。
您可以使用docker swarm join
命令将任何计算机(物理或虚拟)加入这个集群,并将容量添加到群集中。只需在之后运行docker stack deploy
,您的应用就会部署到新的节点。
清理并重新启动
stack和swarm
你可以docker stack rm
从stack中停止服务。例如:
docker stack rm getstartedlab
如何从群中移除节点
如果你想从群里移除节点,如果是worker,比如要移除myvm2节点,可以执行
docker-machine ssh myvm2 "docker swarm leave"
,如果是Swarm管理器,比如myvm1,则执行docker-machine ssh myvm1 "docker swarm leave --force"
取消设置docker-machine shell变量设置
您可以docker-machine
使用给定命令在当前shell中取消环境变量设置。这样当前命令行就不会转发命令给docker vm
在Mac或Linux上,命令是:
eval $(docker-machine env -u)
在Windows上,命令是:
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env -u | Invoke-Expression
这会使shell与docker-machine
创建的虚拟机断开连接
重启Docker机器
如果关闭本地主机,重启后Docker创建的虚拟计算机将停止运行。您可以通过运行docker-machine ls
来检查机器的状态。
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - virtualbox Stopped Unknown
myvm2 - virtualbox Stopped Unknown
要重新启动已停止的计算机,请运行:
docker-machine start <machine-name>
例如:
$ docker-machine start myvm1
Starting "myvm1"...
(myvm1) Check network to re-create if needed...
(myvm1) Waiting for an IP...
Machine "myvm1" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
$ docker-machine start myvm2
Starting "myvm2"...
(myvm2) Check network to re-create if needed...
(myvm2) Waiting for an IP...
Machine "myvm2" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
网友评论