A swarm is a group of machines that are running Docker and joined into a cluster. After that has happened, you continue to run the Docker commands you’re used to, but now they are executed on a cluster by a swarm manager. The machines in a swarm can be physical or virtual. After joining a swarm, they are referred to as nodes.
Swarm managers can use several strategies to run containers, such as “emptiest node” – which fills the least utilized machines with containers. Or “global”, which ensures that each machine gets exactly one instance of the specified container. You instruct the swarm manager to use these strategies in the Compose file, just like the one you have already been using.
Swarm managers are the only machines in a swarm that can execute your commands, or authorize other machines to join the swarm as workers. Workers are just there to provide capacity and do not have the authority to tell any other machine what it can and cannot do.
Up until now, you have been using Docker in a single-host mode on your local machine. But Docker also can be switched into swarm mode, and that’s what enables the use of swarms. Enabling swarm mode instantly makes the current machine a swarm manager. From then on, Docker will run the commands you execute on the swarm you’re managing, rather than just on the current machine.
蜂群是一组安装了Docker的机器组成的集群,我们可以像之前一样执行Docker命令,但是只能在蜂群管理机上才能执行。蜂群中的机器可以是真实机器或者虚拟机,当接入蜂群后,他们被视为节点。
蜂群管理机有几种运行容器的策略,比如“空闲节点”:用容器填满最少使用的机器,“整体”:确保每个机器都能准确地获得指定容器的一个实例。我们可以在Compose文件中定义这些。
只有在蜂群管理机上才能执行命令,或者授权其他机器作为工作机加入蜂群,工作机只提劳动力,无权告诉其他机器自己能做什么。
目前为止,我们只在单机使用Docker,但是Docker可以切换到蜂群模式。切换到蜂群模式,会立即使当前操作的机器变为管理机。然后Docker会将命令执行在蜂群上,而不仅是在当前机器上。
1.创建多台机器的集群,目前是单机测试所以需要使用虚拟机,以下几种方式可供选择,推荐安装docker toolbox
1.1 docker toolbox
https://docs.docker.com/toolbox/overview/
1.2 oracle VirtualBox
https://www.virtualbox.org/wiki/Downloads
1.3 如果是win10可直接使用 Hyper-V Manager
利用docker toolbox自带虚拟机,创建一对VM 通过docker-machine help查看相关命令
docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2
myvm1的控制台输出
Running pre-create checks...
(myvm1) Default Boot2Docker ISO is out-of-date, downloading the latest release...
(myvm1) Latest release for github.com/boot2docker/boot2docker is v17.10.0-ce
(myvm1) Downloading /Users/jionglu/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v17.10.0-ce/boot2docker.iso...
(myvm1) 0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
Creating machine...
(myvm1) Copying /Users/jionglu/.docker/machine/cache/boot2docker.iso to /Users/jionglu/.docker/machine/machines/myvm1/boot2docker.iso...
(myvm1) Creating VirtualBox VM...
(myvm1) Creating SSH key...
(myvm1) Starting the VM...
(myvm1) Check network to re-create if needed...
(myvm1) Found a new host-only adapter: "vboxnet1"
(myvm1) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env myvm1
创建完2个VM后查看VM列表
docker-machine ls
控制台输出
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - virtualbox Running tcp://192.168.99.100:2376 v17.10.0-ce
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v17.10.0-ce
2.下面设置第一台机器A作为管理机,执行管理命令、验证工作机加入蜂群,第二台机器B作为工作机,先通过docker-machine ssh命令操作VM
2.1 管理机初始化蜂群
docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100"
控制台输出
Swarm initialized: current node (i9pgdm5g061yombmj8b4tqvfi) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-4fv4d3nbbqy1kwbl4zbqu033qxati9075ohsat9892u8mln0zd-5o1ncmtydr3c1krvbuvjznulf 192.168.99.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2.2 根据管理机的提示,在工作机上执行加入蜂群的命令,注意端口要是2377,2366是守护进程的端口
docker-machine ssh myvm2 "docker swarm join --token SWMTKN-1-4fv4d3nbbqy1kwbl4zbqu033qxati9075ohsat9892u8mln0zd-5o1ncmtydr3c1krvbuvjznulf 192.168.99.100:2377"
控制台输出
This node joined a swarm as a worker.
注:客户端离开蜂群命令 docker swarm leave
管理端离开蜂群命令 docker swarm leave --force
2.3 通过docker-machine ssh在管理机查看节点
docker-machine ssh myvm1 "docker node ls"
控制台输出
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
i9pgdm5g061yombmj8b4tqvfi * myvm1 Ready Active Leader
bckre41y6jrovnmuz7djwbiej myvm2 Ready Active
3.通过docker-machine env命令操作docker-machine
之前执行命令都是用docker-machine ssh包裹命令,使用非常不方便,更好选择是通过执行docker-machine env myvm1来获取并执行一个命令。通过env的方式可以使用本地的docker-compose.yml文件远程部署应用,不需要将它拷贝到管理机或者工作机上。
注:如果一定要拷贝,也可以使用scp命令拷贝文件
docker-machine scp docker-compose.yml myvm1:~
3.1 执行
docker-machine env myvm1
控制台输出
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/jionglu/.docker/machine/machines/myvm1"
export DOCKER_MACHINE_NAME="myvm1"
# Run this command to configure your shell:
# eval $(docker-machine env myvm1)
3.2 根据提示执行
eval $(docker-machine env myvm1)
注:类似于ssh远程登录到mymv1,但是目录还是显示本地的目录,可以把本地文件用于远程执行。
docker-machine ls 查看myvm1是否是当前激活的机器
控制台输出
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 * virtualbox Running tcp://192.168.99.100:2376 v17.10.0-ce
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v17.10.0-ce
ACTIVIE列为*号表示当前激活的虚拟机,如果已经激活,可以像文章3中用相同的命令操作myvm1
注意:
a.mac使用Item,只有在执行eval $(docker-machine env myvm1)的窗口才会显示*号,所以可以打开多个窗口对应多个VM
b.如果docker-machine不是Ruuning状态,执行开启命令docker-machine start myvm1
c.退出控制虚拟机eval $(docker-machine env -u)
3.3 像之前一样在本地执行命令
docker stack deploy -c docker-compose.yml getstartedlab
查看进程
docker stack ps getstartedlab
控制台输出
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
eomp0knftsxd getstartedlab_web.1 gaojingyuan/testrepo:v1 myvm2 Running Preparing 24 seconds ago
xzfb2fbtc78h getstartedlab_web.2 gaojingyuan/testrepo:v1 myvm1 Running Preparing 24 seconds ago
pismd6w405in getstartedlab_web.3 gaojingyuan/testrepo:v1 myvm2 Running Preparing 24 seconds ago
4bg66tpcjejf getstartedlab_web.4 gaojingyuan/testrepo:v1 myvm2 Running Preparing 24 seconds ago
f85u2q958tn9 getstartedlab_web.5 gaojingyuan/testrepo:v1 myvm1 Running Preparing 24 seconds ago
可见service启动时,利用了myvm1和myvm2两个节点。
总结:多个container组成了一个service对外提供服务,使用swarm,用多个节点分担这个service的压力。
备注:
docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10
docker-machine env myvm1 # View basic information about your node
docker-machine ssh myvm1 "docker node ls" # List the nodes in your swarm
docker-machine ssh myvm1 "docker node inspect <node ID>" # Inspect a node
docker-machine ssh myvm1 "docker swarm join-token -q worker" # View join token
docker-machine ssh myvm1 # Open an SSH session with the VM; type "exit" to end
docker node ls # View nodes in swarm (while logged on to manager)
docker-machine ssh myvm2 "docker swarm leave" # Make the worker leave the swarm
docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm
docker-machine ls # list VMs, asterisk shows which VM this shell is talking to
docker-machine start myvm1 # Start a VM that is currently not running
docker-machine env myvm1 # show environment variables and command for myvm1
eval $(docker-machine env myvm1) # Mac command to connect shell to myvm1
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression # Windows command to connect shell to myvm1
docker stack deploy -c <file> <app> # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file
docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>" # Deploy an app using ssh (you must have first copied the Compose file to myvm1)
eval $(docker-machine env -u) # Disconnect shell from VMs, use native docker
docker-machine stop $(docker-machine ls -q) # Stop all running VMs
docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images