2017-08-19 22:50

(九)Docker - Swarm

商业转载请联系作者获得授权,非商业转载请注明出处. Leon(weippt.com)

Swarm 比较适用于企业内部集群应用部署、云计算资源扩展。它将一组 Docker 主机作为一个虚拟的Docker主机来管理,将多台 Docker 主机作为一个集群,并在集群级别上以标准 Docker API 的形式提供服务。现在的 Swarm 变化还是比较大的,所以我们有必要单独写一小节。在开始之前我们先来了解一下 Swarm、Swarm mode、Swarmkit 之间的关系,特别要说明的是我们很容易被 Swarm 和 Swarm mode 搞混!所以除了下面列表介绍的特性区别外,他们在使用上也有明显的差别。一般你在网上中看到的$ swarm 或 $ docker-machine --swarm 构建的都是 Docker Swarm,而且它会在你的目标主机上构建一个容器,使用 $ docker ps 可以看到这个容器;另外,使用 docker-machine ls 也可用看到 Swarm 的状态;

Docker Swarm
  • 已成为历史;

  • 独立于 Docker engine;

  • 以容器状态存在;

  • 与Docker Machine集成;

  • 使用Docker CLI;

  • 需额外的 KV 存储(通过 --swarm-discovery 可用指定 token(Docker Hub)、Consul、Etcd、Consul、ZooKeeper 等...

Swarmkit
  • Docker 在其 1.12 之后开源的项目;

  • 有自己的 CLI(swarmd、swarmctl);

  • 提供编排和调度服务;

  • 没有服务发现、负载均衡和路由功能;

Swarm mode
  • 基于 Swarmkit,内置于 Docker Engine 1.12 + (docker swarm);

  • 不在需要额外的 KV 存储;

  • 支持服务模型及扩容、服务发现、滚动升级、路由和负载均衡等;

  • 支持 TLS 加密通信;

  • 未与 Docker machine 与 Docker compose 集成(所以在 $ docker-machine ls 中你将看不到 Swarm 列的状态);

  • 详见:https://docs.docker.com/engine/swarm


接下来我们只介绍 Swarm mode 的使用。在使用 Swarm 之前要保证 Docker 主机节点的版本一致。这里我们将在 2 台主机上测试Swarm:

  • HostA  10.0.0.130

  • HostB  10.0.0.128

创建 Swarm 集群

HostA$ sudo docker swarm init

创建 Swarm 集群,设置此节点为 manager,并给出 worker 节点加入 manager 的方法提示!

HostB$ sudo docker swarm join ... # 使用 manager 给出的命令即可加入 manager。

HostA$ sudo docker swarm ls # 在 manager 上可以查看节点列表和状态。

$ sudo docker info 可以查看 swarm 当前信息;

就这么简单,Swarm集群就创建好了。接下来我们开始在集群上部署服务!

部署服务

我们首先创建一个最无聊的服务,在容器上定时输出“Hi, weippt.com"

$ sudo docker service create --replicas 1 --name test1 oooline/helloworld

$ sudo docker service create --replicas 1 --name test2 busybox /bin/sh -c "while true; do echo 'Hi weippt.com'; sleep 5; done"

这两个命令都是每5秒打印一次Hi weippt.com,其 test1 是汇编构建的仅 207B 的超小镜像,test2 是仅1M多的Linux系统。如果 test1 异常,可以使用 test2。

  • docker service create 创建服务
    --name 服务名设置为 test1;
    --replicas 设置运行的服务数量,后面可以通过 scale 动态伸缩;

  • docker service ls #查看服务列表

  • docker service inspect test2 #查看test2服务的详情

  • docker service ps test2 #查看test2所运行的节点及状态;

  • docker service scale test=5 #把服务数量扩展到5;

  • docker service rm test1 #删除服务;

  • 在节点上执行:$ docker ps 可以看到自己被分派正在运行的容器;

滚动更新

如果想更新我们的服务版本,也非常容易。我们先部署服务并为服务设置一个10秒更新间隔延迟(–update-delay):

  • $ sudo docker service create --replicas 5 --name phptest --update-delay 10s php:7.0-cli
    -update-delay 延迟时间(ns | us | ms | s | m | h)
    –update-parallelism 同时更新任务最大数

  • $ docker service update --image php:7.1-cli phptest  # 更新服务
    更新过程:停止第一个任务。对已停止的任务执行更新。启动已经完成更新的容器。如果更新任务返回RUNNING,等待一个指定的延迟然后停止下一个任务。如果在任何时候任务返回FAIlED,停止更新。

  • $ docker service inspect --pretty phptest  # 查看当前php版本,或通过 logs 查看服务的输出日志;

  • $ docker service update phptest  # 重启已暂停的更新;

  • $ docker service ps phptest  # 查看更新过程

上下线节点

不需要的节点下线之后,Swarm会在其他节点创建新的副本以保证副本数量不变!

$ docker node ls # 列出所有节点;

$ docker node update --availability drain HostB  # 下线指定节点

$ docker node update --availability active HostB  # 上线指定节点

新上线的节点是不回被分派任务的,除非出现下面几种情况:

在增大服务规模期间;在滚动更新期间;当设置另一个节点为Drain状态时;当一个任务在另一个Active节点失败时;

发布服务端口

$ docker service create --name my-web --publish 8080:80 --replicas 2 nginx

$ docker service update --publish-add <PUBLISHED-PORT>:<TARGET-PORT> <SERVICE>  # 为已存在的服务发布一个端口

通常情况下,Docker发布的都是TCP端口,如果需要指定UDP,可以使用:53:53/tcp 53:53/udp。

当你访问任意节点的8080端口,swarm的负载均衡会把你的请求路由到一个任意节点的可用的容器上。routing mesh 在swarm节点的所有IP上监听 published 端口。了解更多 routing mesh:https://docs.docker.com/engine/swarm/ingress/#publish-a-port-for-a-service

附:如果你的系统在防火墙后,要保证主机之间的以下端口是打开的:

  • TCP 端口 2377 用于集群管理通信(管理节点)

  • TCP 和 UDP 端口 7946 用于节点间通信(所有节点)

  • TCP 和 UDP 端口 4789 用于 overlay 网络流量(所有节点)

Overlay

详见:https://docs.docker.com/engine/swarm/networking/

商业转载请联系作者获得授权,非商业转载请注明出处. Leon(weippt.com)