本笔记参考 https://docs.docker.com/get-started/part4/

  • Containers
  • Services
  • Swarms
  • Stacks

什么是 Swarm clusters

考虑将Docker运行在一组机器上作为一个cluster群集使用,此时我们需要一个工具帮助我们创建和管理这些docker主机。 Swarm就是这样一个工具,有了它我们可以通过一个 Swarm manager运行Docker命令来控制cluster。使用Swarm操作集群,会使用户感觉就像是在一台主机上进行操作。

在Swarm中,只能通过Swarm managers 来执行命令或者授权其他机器作为worker加入swarm。而worker只负责提供计算能力无权控制其他机器工作。

Swarm是运行在Linux机器上的守护程序,它所绑定的网络接口与独立Docker实例相同(http/2375或https/2376)。Swarm 守护进程可以与标准的Docker客户端相连接并接受其发送来的信息,之后,Swarm服务会对来自Docker客户端的指令信息进行配置,最后通过代理的方式把信息发送给不同Docker的守护进程,Swarm服务同时也监听着标准的Docker端口。 比如,Swarm会基于不同的打包算法并结合Docker守护进程在启动时指定好标签(tags),把create命令分配到不同的Docker守护进程上来执行。根据这一特性,用户可以创建由不同的Docker主机所构成的分区集群(partitioned cluster)并且将整个集群在逻辑上以一个单一的Docker终端的形式公开给用户,Swarm使这个过程变得极其简单。

Swarm守护进程本身相当于是一个调度器和一个路由器。它实际上并没有运行容器,也就是说,如果Swarm服务停止了,它在终端Docker主机上已分配好的容器仍然是开启的。另外,由于它不处理任何网络路由(网络连接需要被直接发送到后端的Docker主机上),即使Swarm守护进程意外终止,运行的容器仍然可用。当Swarm从这样的崩溃中恢复,它依然能够查询终端以重建其元数据的列表。

什么是Docker machine

简单的说,Docker Machine 是一个安装和管理 Docker 的工具。它有自己的命令行工具:docker-machine 以及Docker engine client。

我们可以在本地系统上安装Docker Machine, 然后通过docker machine 在一个或者多个虚拟机上安装docker engine。

docker machine

安装Docker machine

$ curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

确认安装成功

$ docker-machine version
docker-machine version 0.13.0, build 9ba6da9

配置bash补全脚本

可以选择安装脚本在 /etc/bash_completion.d 或者 /usr/local/etc/bash_completion.d 目录下

$ scripts=( docker-machine-prompt.bash docker-machine-wrapper.bash docker-machine.bash ); \
for i in "${scripts[@]}"; \
do sudo wget https://raw.githubusercontent.com/docker/machine/v0.13.0/contrib/completion/bash/${i} \
-P /etc/bash_completion.d; done

修改~/.bashrc, 在PS1中添加 $(__docker_machine_ps1),以便启用docker-machine shell prompt

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]:\[$(__docker_machine_ps1)\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

卸载Docker machine

# To remove all machines: 
$docker-machine rm -f $(docker-machine ls -q)

# Remove the executable: 
$rm $(which docker-machine)

安装 virtualbox

sudo apt install virtualbox

建立swarm

Swarm大致工作流程如下:
- Docker主机服务(服务器上的Docker守护进程)通过–label key=value被启动并对网络进行监听。
- Swarm守护进程被启动并指向一个文件,这个文件包含有构成集群的主机以及这些主机所监听的端口列表。
- Swarm与每个Docker主机交互并确定他们的标记、健康状况以及资源使用量,并维护后端和它们元数据的列表。
- 客户端通过它的网络端口(2375)与Swarm交互。与Swarm的交互方式与Docker交互的方式类似:创建、销毁、运行、依附(attach)并获得运行容器的日志以及其他相关内容。
- 当一个命令发出给Swarm,Swarm会:
- 基于提供的constraint标签、终端的健康程度以及调度算法来决定把命令发送到哪里。
- 针对合适的Docker守护进程执行命令。
- 返回结果的格式与Docker守护进程相同。

使用docker machine 创建一对虚拟机

docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2

查看创建的VMs以及IP

$docker-machine ls
NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
myvm1   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.09.1-ce   
myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.09.1-ce

初始化 Swarm 并添加node

#通过docker-machine ssh到 myvm1, 并将其设为swarm manager

$docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100"
Swarm initialized: current node (llmexl5oj50imsntlkcm9nsxk) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-6001gprr2xe5suwtik7ajuk0vy1wtlabzjsnjdz3157fp05in9-8nem0f30uv6h3gzw7jflxrrdr 192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Ports 2377 and 2376

2377是 swarm management port 用于 swarm init 以及 swarm join

2376是 docker machine 返回的machine ip包含2376端口,这个端口实际是Docker daemon的监听端口

根据 docker init 返回的内容,添加myvm2 到swarm 群集

$ docker-machine ssh myvm2 "docker swarm join \
> --token SWMTKN-1-6001gprr2xe5suwtik7ajuk0vy1wtlabzjsnjdz3157fp05in9-8nem0f30uv6h3gzw7jflxrrdr \
> 192.168.99.100:2377"
This node joined a swarm as a worker.

查看创建的群集状态

$ docker-machine ssh myvm1 "docker node ls"
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
llmexl5oj50imsntlkcm9nsxk *   myvm1               Ready               Active              Leader
nnccrt9u7arepsd1lrblvpuct     myvm2               Ready               Active

部署app到swarm cluster上

配置docker-machine shell 指向swarm manager。 之后的shell命令都会发往myvm1

$eval $(docker-machine env myvm1)

确认myvm1 是active machine

[myvm1]$ docker-machine ls
NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
myvm1   *        virtualbox   Running   tcp://192.168.99.100:2376           v17.09.1-ce   
myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.09.1-ce

在swarm manager上部署app

[myvm1]$ docker stack deploy -c docker-compose.yml myClusterApp
Creating network myClusterApp_webnet
Creating service myClusterApp_web

查看 stack 部署情况,我们可以看见 service 被分布到了不同nodes 上

[myvm1]$ docker stack ps myClusterApp
ID                  NAME                 IMAGE                            NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
rpim63c3hp7s        myClusterApp_web.1   misterchi/repositorytest:hello   myvm2               Running             Running about a minute ago                       
n1tqaa1amsno        myClusterApp_web.2   misterchi/repositorytest:hello   myvm2               Running             Running about a minute ago                       
ztlo0ybs1k37        myClusterApp_web.3   misterchi/repositorytest:hello   myvm1               Running             Running about a minute ago                       
0okow9m17jre        myClusterApp_web.4   misterchi/repositorytest:hello   myvm2               Running             Running about a minute ago                       
ogxanth75jno        myClusterApp_web.5   misterchi/repositorytest:hello   myvm1               Running             Running about a minute ago 

用 docker-machine env 或者 docker-machine ssh 连接VMs
- docker-machine env: 使用 eval $(docker-machine env ) 可以使当前shell 直接指向指定的nodes
- docker-machine ssh “” : 新登录指定node 然后执行命令,再退出。

测试部署在cluster上的 app, 反复运行可以看见5个不同的 hostname 循环出现。

$ curl http://192.168.99.100
<h3>Hello World!</h3><b>Hostname:</b> 18c98332c414<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>

$ curl http://192.168.99.101
<h3>Hello World!</h3><b>Hostname:</b> 18c98332c414<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>

Swarm ingress network

移除重启

移除worker : docker-machine ssh myvm2 “docker swarm leave”
移除Manager :docker-machine ssh myvm1 “docker swarm leave –force”

# 拆除 swarm stack

[myvm1]$ docker stack rm myClusterApp
Removing service myClusterApp_web
Removing network myClusterApp_webnet

unset docker-machine 相关的shell 设置

eval $(docker-machine env -u)

停止/启动 docker machine

docker-machine ls
docker-machine start <machine-name>
docker-machine stop <machine-name>

常用命令

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
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐