介绍

Docker ComposeDocker官方编排(Orchestration)项目之一,负责快速的部署分布式应用。其代码目前在https://github.com/docker/compose上开源。Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目Fig

前面我们已经学习过使用一个Dockerfile模板文件,可以很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器或者缓存服务容器,甚至还包括负载均衡容器等。Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

Compose 中有两个重要的概念:

  • 服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
  • 项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。所以只要所操作的平台支持 Docker API,就可以在其上利用 Compose 来进行编排管理。

安装与卸载

Compose支持 Linux、macOS、Windows 10 三大平台。Compose 可以通过 Python 的包管理工具pip进行安装,也可以直接下载编译好的二进制文件使用,甚至能够直接在 Docker 容器中运行。前两种方式是传统方式,适合本地环境下安装使用;最后一种方式则不破坏系统环境,更适合云计算场景。Docker for Mac 、Docker for Windows 自带 docker-compose 二进制文件,安装 Docker 之后可以直接使用。

$ docker-compose --version
docker-compose version 1.17.1, build 6d101fb

二进制安装

在 Linux 上的也安装十分简单,从 官方 GitHub Release 处直接下载编译好的二进制文件即可。例如,在 Linux 64 位系统上直接下载对应的二进制包。

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

PIP 安装

注: x86_64 架构的 Linux 建议按照上边的方法下载二进制包进行安装,如果您计算机的架构是 ARM (例如,树莓派),再使用 pip 安装。

这种方式是将 Compose 当作一个 Python 应用来从 pip 源中安装。执行安装命令:

$ sudo pip install -U docker-compose
Collecting docker-compose
  Downloading docker-compose-1.17.1.tar.gz (149kB): 149kB downloaded
...
Successfully installed docker-compose cached-property requests texttable websocket-client docker-py dockerpty six enum34 backports.ssl-match-hostname ipaddress

bash 补全命令:

$ curl -L https://raw.githubusercontent.com/docker/compose/1.8.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

容器中执行

Compose 既然是一个 Python 应用,自然也可以直接用容器来执行它。

$ curl -L https://github.com/docker/compose/releases/download/1.8.0/run.sh > /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose

实际上,查看下载的run.sh脚本内容,如下:

set -e

VERSION="1.8.0"
IMAGE="docker/compose:$VERSION"

# Setup options for connecting to docker hostif [ -z "$DOCKER_HOST" ]; then
    DOCKER_HOST="/var/run/docker.sock"fiif [ -S "$DOCKER_HOST" ]; then
    DOCKER_ADDR="-v $DOCKER_HOST:$DOCKER_HOST -e DOCKER_HOST"else
    DOCKER_ADDR="-e DOCKER_HOST -e DOCKER_TLS_VERIFY -e DOCKER_CERT_PATH"fi

# Setup volume mounts for compose config and contextif [ "$(pwd)" != '/' ]; then
    VOLUMES="-v $(pwd):$(pwd)"fiif [ -n "$COMPOSE_FILE" ]; then
    compose_dir=$(dirname $COMPOSE_FILE)fi# TODO: also check --file argumentif [ -n "$compose_dir" ]; then
    VOLUMES="$VOLUMES -v $compose_dir:$compose_dir"fiif [ -n "$HOME" ]; then
    VOLUMES="$VOLUMES -v $HOME:$HOME -v $HOME:/root" # mount $HOME in /root to share docker.configfi
# Only allocate tty if we detect oneif [ -t 1 ]; then
    DOCKER_RUN_OPTIONS="-t"fiif [ -t 0 ]; then
    DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS -i"fi
exec docker run --rm $DOCKER_RUN_OPTIONS $DOCKER_ADDR $COMPOSE_OPTIONS $VOLUMES -w "$(pwd)" $IMAGE "$@"

可以看到,它其实是下载了docker/compose镜像并运行。

卸载

如果是二进制包方式安装的,删除二进制文件即可。

$ sudo rm /usr/local/bin/docker-compose

如果是通过 pip 安装的,则执行如下命令即可删除。

$ sudo pip uninstall docker-compose

使用

下面我们用 Python 来建立一个能够记录页面访问次数的 web 网站。 新建文件夹,在该目录中编写app.py文件

import time
import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

接着编写Dockerfile文件,内容为:

FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]

然后是编写docker-compose.yml文件,这个是 Compose 使用的主模板文件。

version: '3'
services:
  web:    
  build: .    
  ports:    
  - "5000:5000"
  volumes:
       - .:/code
  redis:    
  image: "redis:alpine"

运行 compose 项目:

$ docker-compose up

此时访问本地 5000 端口,每次刷新页面,计数就会加 1。

Compose 命令

对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。

执行docker-compose [COMMAND] --help或者docker-compose help [COMMAND]可以查看具体某个命令的使用格式。

docker-compose 命令的基本的使用格式是:

docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]

命令选项:

  • -f, --file FILE 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定。
  • -p, --project-name NAME 指定项目名称,默认将使用所在目录名称作为项目名。
  • --x-networking 使用 Docker 的可拔插网络后端特性
  • --x-network-driver DRIVER 指定网络后端的驱动,默认为 bridge
  • --verbose 输出更多调试信息。
  • -v, --version 打印版本并退出。

build 格式为docker-compose build [options] [SERVICE...]。 构建(重新构建)项目中的服务容器。服务容器一旦构建后,将会带上一个标记名,例如对于 web 项目中的一个 db 容器,可能是 web_db。可以随时在项目目录下运行docker-compose build来重新构建服务。选项包括:

  • --force-rm 删除构建过程中的临时容器。
  • --no-cache 构建镜像过程中不使用 cache(这将加长构建过程)。
  • --pull 始终尝试通过 pull 来获取更新版本的镜像。

config: 验证 Compose 文件格式是否正确,若正确则显示配置,若格式错误显示错误原因。

down:此命令将会停止 up 命令所启动的容器,并移除网络

exec:进入指定的容器。

help:获得一个命令的帮助。

images:列出 Compose 文件中包含的镜像。

kill:格式为docker-compose kill [options] [SERVICE...]。通过发送SIGKILL信号来强制停止服务容器。支持通过-s参数来指定发送的信号,例如通过如下指令发送SIGINT信号。

$ docker-compose kill -s SIGINT

logs:格式为docker-compose logs [options] [SERVICE...],查看服务容器的输出。默认情况下,docker-compose 将对不同的服务输出使用不同的颜色来区分。可以通过 --no-color来关闭颜色。该命令在调试问题的时候十分有用。

pause:格式为docker-compose pause [SERVICE...],暂停一个服务容器。

port:格式为docker-compose port [options] SERVICE PRIVATE_PORT,打印某个容器端口所映射的公共端口。选项:

  • --protocol=proto 指定端口协议,tcp(默认值)或者 udp。
  • --index=index 如果同一服务存在多个容器,指定命令对象容器的序号(默认为 1)。

ps:格式为docker-compose ps [options] [SERVICE...],列出项目中目前的所有容器。选项:

  • -q只打印容器的 ID 信息。

pull:格式为docker-compose pull [options] [SERVICE...],拉取服务依赖的镜像。选项:

  • --ignore-pull-failures 忽略拉取镜像过程中的错误。

push:推送服务依赖的镜像到 Docker 镜像仓库。

restart:格式为docker-compose restart [options] [SERVICE...],重启项目中的服务。选项:

  • -t, --timeout TIMEOUT 指定重启前停止容器的超时(默认为 10 秒)。

rm:格式为docker-compose rm [options] [SERVICE...],删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop命令来停止容器。选项:

  • -f, --force 强制直接删除,包括非停止状态的容器。一般尽量不要使用该选项。
  • -v 删除容器所挂载的数据卷。

run:格式为docker-compose run [options] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...],在指定服务上执行一个命令。例如:

$ docker-compose run ubuntu ping docker.com

将会启动一个 ubuntu 服务容器,并执行 ping docker.com 命令。默认情况下,如果存在关联,则所有关联的服务将会自动被启动,除非这些服务已经在运行中。

该命令类似启动容器后运行指定的命令,相关卷、链接等等都将会按照配置自动创建。

给定命令将会覆盖原有的自动运行命令; 不会自动创建端口,以避免冲突。

如果不希望自动启动关联的容器,可以使用--no-deps选项,例如:

$ docker-compose run --no-deps web python manage.py shell

将不会启动 web 容器所关联的其它容器,选项:

  • -d 后台运行容器。
  • --name NAME 为容器指定一个名字。
  • --entrypoint CMD 覆盖默认的容器启动指令。
  • -e KEY=VAL 设置环境变量值,可多次使用选项来设置多个环境变量。
  • -u, --user="" 指定运行容器的用户名或者 uid。
  • --no-deps 不自动启动关联的服务容器。
  • --rm 运行命令后自动删除容器,d 模式下将忽略。
  • -p, --publish=[] 映射容器端口到本地主机。
  • --service-ports 配置服务端口并映射到本地主机。
  • -T 不分配伪 tty,意味着依赖 tty 的指令将无法运行。

scale:格式为docker-compose scale [options] [SERVICE=NUM...],设置指定服务运行的容器个数。 通过 service=num 的参数来设置数量。例如:

$ docker-compose scale web=3 db=2

将启动 3 个容器运行 web 服务,2 个容器运行 db 服务。

一般的,当指定数目多于该服务当前实际运行容器,将新创建并启动容器;反之,将停止容器。选项:

  • -t, --timeout TIMEOUT 停止容器时候的超时(默认为 10 秒)。

start:格式为docker-compose start [SERVICE...],启动已经存在的服务容器。

stop:格式为docker-compose stop [options] [SERVICE...], 停止已经处于运行状态的容器,但不删除它。通过docker-compose start可以再次启动这些容器。选项:

  • -t, --timeout TIMEOUT 停止容器时候的超时(默认为 10 秒)。

top:查看各个服务容器内运行的进程。

unpause:格式为docker-compose unpause [SERVICE...],恢复处于暂停状态中的服务。

up:格式为docker-compose up [options] [SERVICE...],该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。链接的服务都将会被自动启动,除非已经处于运行状态。 可以说,大部分时候都可以直接通过该命令来启动一个项目。

默认情况,docker-compose up启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。 当通过 Ctrl-C 停止命令时,所有容器将会停止。

如果使用docker-compose up -d,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。

默认情况,如果服务容器已经存在,docker-compose up将会尝试停止容器,然后重新创建(保持使用 volumes-from 挂载的卷),以保证新启动的服务匹配 docker-compose.yml 文件的最新内容。如果用户不希望容器被停止并重新创建,可以使用 docker-compose up --no-recreate。这样将只会启动处于停止状态的容器,而忽略已经运行的服务。

如果用户只想重新部署某个服务,可以使用docker-compose up --no-deps -d <SERVICE_NAME>来重新创建服务并后台停止旧服务,启动新服务,并不会影响到其所依赖的服务。选项:

  • -d 在后台运行服务容器。
  • --no-color 不使用颜色来区分不同的服务的控制台输出。
  • --no-deps 不启动服务所链接的容器。
  • --force-recreate 强制重新创建容器,不能与--no-recreate同时使用。 --no-recreate如果容器已经存在了,则不重新创建,不能与 --force-recreate同时使用。 --no-build不自动构建缺失的服务镜像。
  • -t, --timeout TIMEOUT 停止容器时候的超时(默认为 10 秒)。

 

2. Docker Machine

Docker MachineDocker官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境。

Docker Machine项目基于Go语言实现,目前在Github上进行维护。

Docker Machine是 Docker 官方提供的一个工具,它可以帮助我们在远程的机器上安装 Docker,或者在虚拟机 host 上直接安装虚拟机并在虚拟机中安装 Docker。我们还可以通过 docker-machine命令来管理这些虚拟机和 Docker。

本章将介绍 Docker Machine 的安装及使用。

安装

Docker Machine 可以在多种操作系统平台上安装,包括 Linux、macOS,以及 Windows。

macOS、Windows

Docker for Mac、Docker for Windows 自带 docker-machine 二进制包,安装之后即可使用。查看版本信息。

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

Linux

在 Linux 上的也安装十分简单,从官方 GitHub Release处直接下载编译好的二进制文件即可。 例如,在 Linux 64 位系统上直接下载对应的二进制包。

$ 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 -v
docker-machine version 0.13.0, build 9ba6da9

使用

Docker Machine 支持多种后端驱动,包括虚拟机、本地主机和云平台等。

创建本地主机实例Virtualbox 驱动

使用virtualbox类型的驱动,创建一台 Docker 主机,命名为 test。

$ docker-machine create -d virtualbox test

你也可以在创建时加上如下参数,来配置主机或者主机上的 Docker。

  • --engine-opt dns=114.114.114.114配置 Docker 的默认 DNS
  • --engine-registry-mirror https://registry.docker-cn.com配置 Docker 的仓库镜像
  • --virtualbox-memory 2048 配置主机内存
  • --virtualbox-cpu-count 2 配置主机 CPU

更多参数请使用docker-machine create --driver virtualbox --help命令查看。

$ docker-machine create -d generic \
    --generic-ip-address=123.59.188.19 \
    --generic-ssh-user=root \
    --generic-ssh-key ~/.ssh/id_rsa \
    dev

MacOS xhyve 驱动

xhyve 驱动 GitHub: https://github.com/zchee/docker-machine-driver-xhyve,`xhyve`是`MacOS`上轻量化的虚拟引擎,使用其创建的 Docker Machine 较 VirtualBox 驱动创建的运行效率要高。

$ brew install docker-machine-driver-xhyve
......
$ docker-machine create \
      -d xhyve \
      # --xhyve-boot2docker-url ~/.docker/machine/cache/boot2docker.iso \
      --engine-opt dns=114.114.114.114 \
      --engine-registry-mirror https://registry.docker-cn.com \
      --xhyve-memory-size 2048 \
      --xhyve-rawdisk \
      --xhyve-cpu-count 2 \
      xhyve

注意:非首次创建时建议加上--xhyve-boot2docker-url ~/.docker/machine/cache/boot2docker.iso参数,避免每次创建时都从 GitHub 下载 ISO 镜像。

更多参数请使用docker-machine create --driver xhyve --help命令查看。

Windows 10

Windows 10安装Docker for Windows之后不能再安装VirtualBox,也就不能使用 virtualbox 驱动来创建 Docker Machine,我们可以选择使用 hyperv 驱动。

$ docker-machine create --driver hyperv vm

更多参数请使用docker-machine create --driver hyperv --help命令查看。

使用介绍

创建好主机之后,查看主机

$ docker-machine ls

NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER       ERRORStest      -        virtualbox   Running   tcp://192.168.99.187:2376           v17.10.0-ce

创建主机成功后,可以通过env命令来让后续操作对象都是目标主机。

$ docker-machine env test

后续根据提示在命令行输入命令之后就可以操作 test 主机。也可以通过SSH登录到主机。

$ docker-machine ssh test

docker@test:~$ docker --version
Docker version 17.10.0-ce, build f4ffd25

连接到主机之后你就可以在其上使用 Docker 了。

官方支持驱动

通过-d选项可以选择支持的驱动类型:

  • amazonec2
  • azure
  • digitalocean
  • exoscale
  • generic
  • google
  • hyperv
  • none
  • openstack
  • rackspace
  • softlayer
  • virtualbox
  • vmwarevcloudair
  • vmwarefusion
  • vmwarevsphere

操作命令

  • active 查看活跃的 Docker 主机
  • config 输出连接的配置信息
  • create 创建一个 Docker 主机
  • env 显示连接到某个主机需要的环境变量
  • inspect 输出主机更多信息
  • ip 获取主机地址
  • kill 停止某个主机
  • ls 列出所有管理的主机
  • provision 重新设置一个已存在的主机
  • regenerate-certs 为某个主机重新生成 TLS 认证信息
  • restart 重启主机
  • rm 删除某台主机
  • ssh SSH 到主机上执行命令
  • scp 在主机之间复制文件
  • mount 挂载主机目录到本地
  • start 启动一个主机
  • status 查看主机状态
  • stop 停止一个主机
  • upgrade 更新主机 Docker 版本为最新
  • url 获取主机的 URL
  • version 输出 docker-machine 版本信息
  • help 输出帮助信息

每个命令,又带有不同的参数,可以通过如下命令来查看具体的用法:

$ docker-machine COMMAND --help


3. Docker Swarm

基本概念

Swarm是使用SwarmKit构建的 Docker 引擎内置(原生)的集群管理和编排工具。Docker Swarm是 Docker 官方三剑客项目之一,提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。

使用它,用户可以将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。Swarm mode 内置 kv 存储功能,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得 Docker 原生的 Swarm 集群具备与MesosKubernetes竞争的实力。使用 Swarm 集群之前需要了解以下几个概念。

节点

运行 Docker 的主机可以主动初始化一个 Swarm 集群或者加入一个已存在的 Swarm 集群,这样这个运行 Docker 的主机就成为一个 Swarm 集群的节点 (node) 。节点分为管理 (manager) 节点和工作 (worker) 节点

管理节点用于Swarm集群的管理,docker swarm命令基本只能在管理节点执行(节点退出集群命令docker swarm leave可以在工作节点执行)。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为leader,leader 通过raft协议实现。

工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。来自Docker官网的这张图片形象的展示了集群中管理节点与工作节点的关系。 DOCKER 三架马车

​​

服务和任务

任务(Task)是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器;服务(Services)是指一组任务的集合,服务定义了任务的属性。服务有两种模式:

  • replicated services按照一定规则在各个工作节点上运行指定个数的任务。
  • global services每个工作节点上运行一个任务

两种模式通过docker service create--mode参数指定。来自 Docker 官网的这张图片形象的展示了容器、任务、服务的关系。 DOCKER 三架马车​​

初始化集群

我们这里利用上一节的docker machine来充当集群的主机,首先先创建一个manager节点,然后在该节点上执行初始化集群命令:

☁  ~  docker-machine create -d virtualbox manager
Running pre-create checks...
Creating machine...
(manager) Copying /Users/ych/.docker/machine/cache/boot2docker.iso to /Users/ych/.docker/machine/machines/manager/boot2docker.iso...
(manager) Creating VirtualBox VM...
(manager) Creating SSH key...
(manager) Starting the VM...
(manager) Check network to re-create if needed...
(manager) 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 manager
☁  ~  docker-machine env manager
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.101:2376"
export DOCKER_CERT_PATH="/Users/ych/.docker/machine/machines/manager"
export DOCKER_MACHINE_NAME="manager"
# Run this command to configure your shell:
# eval $(docker-machine env manager)
☁  ~  eval $(docker-machine env manager)
☁  ~  docker-machine ssh manager
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 18.03.1-ce, build HEAD : cb77972 - Thu Apr 26 16:40:36 UTC 2018
Docker version 18.03.1-ce, build 9ee9f40
docker@manager:~$ docker swarm init --advertise-addr 192.168.99.101
Swarm initialized: current node (3gsjpckj5ag1vvdg44fgzylow) is now a manager.

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

    docker swarm join --token SWMTKN-1-1aqikkhsz91l4n7k9ig3xinjz0iv0fh4gcrlhp9mk3643rblca-aqgqldlrw33k8heiao7yx27w5 192.168.99.101:2377

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

执行docker swarm init命令的节点自动成为管理节点。

增加工作节点

管理节点初始化完成后,然后同样的用docker-machine创建工作节点,然后将其加入到管理节点之中去即可:

☁  ~  docker-machine create -d virtualbox worker1
Running pre-create checks...
Creating machine...
(worker1) Copying /Users/ych/.docker/machine/cache/boot2docker.iso to /Users/ych/.docker/machine/machines/worker1/boot2docker.iso...
(worker1) Creating VirtualBox VM...
(worker1) Creating SSH key...
(worker1) Starting the VM...
(worker1) Check network to re-create if needed...
(worker1) 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 worker1

☁  ~  docker-machine ssh worker1
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 18.03.1-ce, build HEAD : cb77972 - Thu Apr 26 16:40:36 UTC 2018
Docker version 18.03.1-ce, build 9ee9f40
docker@worker1:~$ docker swarm join --token SWMTKN-1-1aqikkhsz91l4n7k9ig3xinjz0iv0fh4gcrlhp9mk364
3rblca-aqgqldlrw33k8heiao7yx27w5 192.168.99.101:2377
This node joined a swarm as a worker.

我们可以看到上面的提示信息:This node joined a swarm as a worker.,表明节点已经加入到swarm集群之中了。

查看集群

经过上边的两步,我们已经拥有了一个最小的 Swarm 集群,包含一个管理节点和两个工作节点。

管理节点使用docker node ls查看集群:

☁  ~  docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
3gsjpckj5ag1vvdg44fgzylow *   manager             Ready               Active              Leader              18.03.1-ce
cxmj5lr0vbwo1em9y9oang5m8     worker1             Ready               Active                                  18.03.1-ce
ksruum3uc1c265ywm4kn9a88g     worker2             Ready               Active                                  18.03.1-ce
☁  ~  docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
☁  ~  docker service create --replicas 3 -p 80:80 --name nginx nginx:1.13.7-alpine
4k9cbna8ive87p4or9mny9kfs
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged

☁  ~  docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
manager   *        virtualbox   Running   tcp://192.168.99.101:2376           v18.03.1-ce
worker1   -        virtualbox   Running   tcp://192.168.99.102:2376           v18.03.1-ce
worker2   -        virtualbox   Running   tcp://192.168.99.103:2376           v18.03.1-ce
☁  ~  docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                 PORTS
4k9cbna8ive8        nginx               replicated          3/3                 nginx:1.13.7-alpine   *:80->80/tcp
☁  ~  docker service ps nginx
ID                  NAME                IMAGE                 NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS
r7hmzkqsri8p        nginx.1             nginx:1.13.7-alpine   worker1             Running             Running about a minute ago
y0xgrfwmjfrj        nginx.2             nginx:1.13.7-alpine   worker2             Running             Running about a minute ago
j8k7be8xkbg3        nginx.3             nginx:1.13.7-alpine   manager             Running             Running about a minute ago

使用docker service logs来查看某个服务的日志。

☁  ~  docker service logs nginx

使用docker service rm来从 Swarm 集群移除某个服务:

☁  ~  docker service rm nginx
nginx

正如之前使用docker-compose.yml来一次配置、启动多个容器,在Swarm集群中也可以使用compose文件(docker-compose.yml)来配置、启动多个服务。

上一节中,我们使用docker service create一次只能部署一个服务,使用docker-compose.yml我们可以一次启动多个关联的服务。

我们以在Swarm集群中部署WordPress为例进行说明:(docker-compose.yml)

version: "3"

services:
  wordpress:
    image: wordpress
    ports:
      - 80:80
    networks:
      - overlay
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
    deploy:
      mode: replicated
      replicas: 3

  db:
    image: mysql
    networks:
       - overlay
    volumes:
      - db-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    deploy:
      placement:
        constraints: [node.role == manager]

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]

volumes:
  db-data:
networks:
  overlay:

其中constraints: [node.role == manager]是调度策略,文档地址:https://docs.docker.com/swarm/scheduler/filter/

在 Swarm 集群管理节点新建该文件,其中的 visualizer 服务提供一个可视化页面,我们可以从浏览器中很直观的查看集群中各个服务的运行节点。

在 Swarm 集群中使用 docker-compose.yml 我们用docker stack命令,下面我们对该命令进行详细讲解。

部署服务

部署服务使用docker stack deploy,其中-c参数指定 compose 文件名。

$ docker stack deploy -c docker-compose.yml wordpress

查看服务

$ docker stack ls
NAME                SERVICES
wordpress           3

移除服务

要移除服务,使用docker stack down:

$ docker stack down wordpress
Removing service wordpress_db
Removing service wordpress_visualizer
Removing service wordpress_wordpress
Removing network wordpress_overlay
Removing network wordpress_default

该命令不会移除服务所使用的数据卷,如果你想移除数据卷请使用docker volume rm