Docker 三剑客之 Docker Swarm

--test--阅读目录:

  • Docker Machine 创建 Docker 主机
  • Docker Swarm 配置集群节点
  • Docker Service 部署单个集群服务
  • Docker Stack 部署多个集群服务,以及 GUI 管理页面
  • docker-machine、docker swarm、docker node、docker service 和 docker stack 常用命令

Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。

从 Docker 1.12.0 版本开始,Docker Swarm 已经包含在 Docker 引擎中(docker swarm),并且已经内置了服务发现工具,我们就不需要像之前一样,再配置 Etcd 或者 Consul 来进行服务发现配置了。

1. Docker Machine 创建 Docker 主机

在进行 Docker Swarm 配置之前,我们还需要说下 Docker 另外一个官方工具 Docker Machine(也是 Docker 三剑客之一),其作用就是快速帮助我们搭建 Docker 主机环境,比如我们要使用 Docker Swarm,就必须有很多的 Docker 主机来进行操作,Docker Machine 就是最理想的工具。

因为我是在 Mac OS 上进行操作的,并且 Docker for Mac 已经包含了 Docker Machine(docker machine),所以我不需要再额外进行安装了,如果使用 Linux 系统的话,安装也非常简单,命令:

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

好了,我们先使用 Docker Machine 创建四个 Docker 主机,命令:

$ docker-machine create -d virtualbox manager1 && 
docker-machine create -d virtualbox manager2 && 
docker-machine create -d virtualbox worker1 && 
docker-machine create -d virtualbox worker2

Running pre-create checks...
(worker1) No default Boot2Docker ISO found locally, downloading the latest release...
(worker1) Latest release for github.com/boot2docker/boot2docker is v17.11.0-ce
(worker1) Downloading /Users/xishuai/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v17.11.0-ce/boot2docker.iso...

执行上面命令,你会发现速度巨慢(如上),原因是从 GitHub 上下载一个boot2docker.iso文件(国内网络没办法),怎么解决呢?很简单,我们使用翻X的浏览器手动下载boot2docker.iso文件,然后拷贝到对应目录下(我电脑的目录/Users/xishuai/.docker/machine/cache/),然后再执行上面的命令,发现速度快的一批。

我们可以查看下创建的 Docker 主机信息,命令:

$ docker-machine ls
NAME       ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
manager1   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.11.0-ce   
manager2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.11.0-ce   
worker1    -        virtualbox   Running   tcp://192.168.99.102:2376           v17.11.0-ce   
worker2    -        virtualbox   Running   tcp://192.168.99.103:2376           v17.11.0-ce   

可以看到,我们创建了四个 Docker 主机(两个 Manager 和两个 Worker),我们还可以连接到任何一台服务器进行操作,命令:

$ docker-machine ssh manager1
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 17.11.0-ce, build HEAD : e620608 - Tue Nov 21 18:11:40 UTC 2017
Docker version 17.11.0-ce, build 1caf76c

2. Docker Swarm 配置集群节点

我们执行下面命令:

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

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

    docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-envtxo4dl6df2ar3qldcccfdg 192.168.99.100:2377

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

上面是在manager1主机上,创建一个 Docker Swarm 管理节点(初始化集群的时候,会自动把当前节点设置为管理节点)。

接着,我们在worker1worker2主机上,创建两个工作节点,并加入到集群中,命令:

$ docker-machine ssh worker1 "docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-envtxo4dl6df2ar3qldcccfdg 192.168.99.100:2377"
This node joined a swarm as a worker.

$ docker-machine ssh worker2 "docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-envtxo4dl6df2ar3qldcccfdg 192.168.99.100:2377"
This node joined a swarm as a worker.

还有另外一个manager2主机,需要配置为管理节点,我们需要先在manager1主机上,获取管理节点对应的token,然后再配置为管理节点,命令:

$ docker-machine ssh manager1 "docker swarm join-token manager"
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-0koz1b98sco8r5cn3g61eahnu 192.168.99.100:2377

$ docker-machine ssh manager2 "docker swarm join --token SWMTKN-1-5uwpqibnvmho1png8zmhcw8274yanohee32jyrcjlait9djhsk-0koz1b98sco8r5cn3g61eahnu 192.168.99.100:2377"
This node joined a swarm as a manager.

配置好之后,我们进入manager1主机内(上面的命令也可以在主机内执行),然后查看集群节点的信息,命令:

$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
n0ub7dpn90rxjq97dr0g8we0w *   manager1            Ready               Active              Leader
t4cy67qp0bf2spgabsutwxnzt     manager2            Ready               Active              Reachable
if0kmzp4ww3oy57y7cha7v36t     worker1             Ready               Active              
jgg61cujzaeb3du5796fm0x2g     worker2             Ready               Active       

Leader表示当然集群的头,Reachable可以理解为头的候选人,头一挂掉它就顶上去了。


需要注意的是,我当天配置好之后,把所有的 Docker 主机都stop了,然后隔天重新start之后,出现了下面问题:

docker node ls
Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online.

好像是集群节点丢失了头,相关问题:如何处理 docker swarm 集群"The swarm does not have a leader"问题,按照文章进行解决:

$ docker swarm init --force-new-cluster
Error response from daemon: could not choose an IP address to advertise since this system has multiple addresses on different interfaces (10.0.2.15 on eth0 and 192.168.99.102 on eth1) - specify one with --advertise-addr
$ docker swarm init --force-new-cluster --advertise-addr 192.168.99.102
Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.
$ docker node ls
卡死
$ docker-machine restart manager1 
重启不了,一直转圈

没办法,后来我只能删掉四个 Docker 主机,重新进行创建了。

3. Docker Service 部署单个集群服务

在部署集群服务之前,我们需要做些准备工作,因为 Docker 主机中没有配置 Docker 镜像加速地址,所以在拉取官方镜像的时候,肯定会非常慢,除了配置 Docker 镜像加速地址之外,我们还可以使用 Docker 私有镜像仓库,来解决这个问题。

参考文章:Ubuntu Docker Registry 搭建私有仓库

这边,我再简单说明下配置步骤,首先,在 Mac OS 上执行下面命令:

$ docker run -d -v /Users/xishuai/Documents/Docker:/var/lib/registry -p 5000:5000 --restart=always --name registry registry

$ docker tag nginx 192.168.99.1:5000/nginx:latest && 
docker push 192.168.99.1:5000/nginx:latest && 
docker pull 192.168.99.1:5000/nginx:latest

$ curl http://192.168.99.1:5000/v2/_catalog
{"repositories":["nginx"]}

我们在 Mac OS 上创建了一个私有仓库容器,并把nginx镜像放到私有仓库中,因为没有使用 Https,所以在拉取和推送镜像的时候,会报如下错误(Mac OS 和 Docker 主机都会报错):

$ docker pull 192.168.99.1:5000/nginx:latest
The push refers to a repository [192.168.99.1:5000/nginx]
Get https://192.168.99.1:5000/v1/_ping: http: server gave HTTP response to HTTPS client

解决方式,我们需要分别在四个 Docker 主机中添加配置(Docker for Mac 在管理界面配置即可),命令:

$ sudo touch /etc/docker/daemon.json && 
sudo chmod 777 /etc/docker/daemon.json && 
sudo echo '{ "insecure-registries":    ["192.168.99.1:5000"] }' > /etc/docker/daemon.json

然后重启四个 Docker 主机(Docker for Mac 也需要重启),命令:

$ docker-machine restart manager1 && 
docker-machine restart manager2 && 
docker-machine restart worker1 && 
docker-machine restart worker2

上面比较啰嗦,我们接下来正式部署集群服务,还是拿nginx镜像做为示例,命令(docker service create命令详细说明):

$ docker service create --replicas 4 -p 8088:80 --name nginx 192.168.99.1:5000/nginx:latest
ap8h8srb8yh3mni0h2nz61njz
overall progress: 4 out of 4 tasks 
1/4: running   [==================================================>] 
2/4: running   [==================================================>] 
3/4: running   [==================================================>] 
4/4: running   [==================================================>] 
verify: Service converged 

需要注意的是,--replicas 4表示创建服务的实例个数(默认是一个),啥意思?比如4,就是在四个 Docker 主机上,分别创建一个nginx服务,如果是3,那就是三个 Docker 主机,或者你可以理解为 Docker 主机的个数,另外,REPLICAS会有进度显示,并且执行是异步的。

我们也可以手动设置实例个数,命令:

$ docker service scale nginx=4

部署好服务后,我们就可以进行查看了,命令:

$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                            PORTS
ap8h8srb8yh3        nginx               replicated          4/4                 192.168.99.1:5000/nginx:latest   *:8080->8080/tcp

$ docker service ps nginx
ID                  NAME                IMAGE                            NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
l2rdrwzs5zog        nginx.1             192.168.99.1:5000/nginx:latest   manager1            Running             Running about a minute ago                       
vsfczzbwanx3        nginx.2             192.168.99.1:5000/nginx:latest   manager2            Running             Running about a minute ago                           
qtbgw5h6dsi9        nginx.3             192.168.99.1:5000/nginx:latest   worker              Running             Running about a minute ago                           
za2ejnvb3n6z        nginx.4             192.168.99.1:5000/nginx:latest   worker2             Running             Running about a minute ago

我们任意使用四个 Docker 主机中的一个 IP 地址,浏览器打开:http://192.168.99.100:8088/

 

4. Docker Stack 部署多个集群服务,以及 GUI 管理页面

docker service部署的是单个服务,我们可以使用docker stack进行多服务编排部署,使用的同样是docker-compose.yml配置文件,示例:

version: "3"

services:
  nginx:
    image: 192.168.99.1:5000/nginx:latest
    ports:
      - 8088:80
    deploy:
      mode: replicated
      replicas: 4

  visualizer:
    image: 192.168.99.1:5000/dockersamples/visualizer:latest
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

  portainer:
    image: 192.168.99.1:5000/portainer/portainer:latest
    ports:
      - "9000:9000"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

如上所示,我们总共需要部署三个服务,出了nginx服务作为示例之外,visualizer(官方地址)和portainer(官方地址)都是集群 GUI 管理服务。

部署命令:

$ docker stack deploy -c docker-compose.yml deploy-demo
Creating service deploy-demo_nginx
Creating service deploy-demo_visualizer
Creating service deploy-demo_portainer

部署成功之后,我们可以查看具体详情,命令:

$ docker stack ls
NAME                SERVICES
deploy-demo         3

查看visualizerGUI 集群管理,浏览器打开:http://192.168.99.100:8080/

1

查看portainerGUI 集群管理,需要先配置账号信息,浏览器打开:http://192.168.99.100:9000/

1

可以看到,portainervisualizer强大太多了,甚至我们所有的操作都可以在portainer上完成。

5. docker-machine、docker swarm、docker node、docker service 和 docker stack 常用命令

docker-machine 常用命令

命令说明
docker-machine create创建一个 Docker 主机(常用-d virtualbox
docker-machine ls查看所有的 Docker 主机
docker-machine sshSSH 到主机上执行命令
docker-machine env显示连接到某个主机需要的环境变量
docker-machine inspect输出主机更多信息
docker-machine kill停止某个主机
docker-machine restart重启某台主机
docker-machine rm删除某台主机
docker-machine scp在主机之间复制文件
docker-machine start启动一个主机
docker-machine status查看主机状态
docker-machine stop停止一个主机

docker swarm 常用命令

命令说明
docker swarm init初始化集群
docker swarm join-token worker查看工作节点的 token
docker swarm join-token manager查看管理节点的 token
docker swarm join加入集群中

docker node 常用命令

命令说明
docker node ls查看所有集群节点
docker node rm删除某个节点(-f强制删除)
docker node inspect查看节点详情
docker node demote节点降级,由管理节点降级为工作节点
docker node promote节点升级,由工作节点升级为管理节点
docker node update更新节点
docker node ps查看节点中的 Task 任务

docker service 常用命令

命令说明
docker service create部署服务
docker service inspect查看服务详情
docker service logs产看某个服务日志
docker service ls查看所有服务详情
docker service rm删除某个服务(-f强制删除)
docker service scale设置某个服务个数
docker service update更新某个服务

docker stack 常用命令

命令说明
docker stack deploy部署新的堆栈或更新现有堆栈
docker stack ls列出现有堆栈
docker stack ps列出堆栈中的任务
docker stack rm删除堆栈
docker stack services列出堆栈中的服务
docker stack down移除某个堆栈(不会删除数据)

参考资料:

  • Get Started, Part 4: Swarms
  • Docker 三剑客之 Docker Swarm
  • Docker Swarm 入门一篇文章就够了
  • Docker 的命令之集群节点管理 Swarm node
  • docker service 命令
  • Docker 命令行参考(37) – docker service create 创建一个服务
  • Docker Machine 是什么?
  • docker swarm 学习命令整理

 

来源:  https://www.cnblogs.com/xishuai/p/docker-swarm.html