看 Docker Swarm 如何做集群

ArlPegues 8年前
   <h2>看 Docker Swarm 如何做集群</h2>    <p>本文所有服务均采用docker容器化方式部署</p>    <h2>当前环境</h2>    <ol>     <li>Mac OS 10.11.x</li>     <li>Docker >= 1.12</li>    </ol>    <h2>目录</h2>    <ul>     <li>基本概念</li>     <li>安装</li>     <li>使用场景</li>     <li>分配策略</li>     <li>高可用</li>     <li>总结</li>    </ul>    <h2>基本概念</h2>    <h3>技术说明</h3>    <ul>     <li>Docker Engine:作为 Docker 镜像构建与容器化启动的工作引擎;</li>     <li>Docker Machine:安装与管理 Docker Engine 的工具;</li>     <li>Docker Swarm:是 Docker 自1.12后自带的集群技术,将多个独立的 Docker Engine 利用 Swarm 技术进行集群化管理;</li>    </ul>    <h3>原理</h3>    <p>简单来讲,Docker 集群的实现是通过 Docker Machine 在多主机或虚拟机上创建多个 Docker Engine,在利用 Docker Swarm 以某个 Engine 作为集群的初始管理节点,其他 Engine 以管理或工作节点的方式加入,形成完成的集群环境。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/15f09555e92a98285893362f53c09325.png"></p>    <h2>安装(本次演示在单台 Mac 上进行)</h2>    <h3>创建 Docker Engine</h3>    <p>使用 docker-machine 命令创建 docker 工作引擎。</p>    <p>参数说明:</p>    <p>-d:设置 Docker Engine 驱动(Mac 下默认是 virtualbox)</p>    <p>--virtualbox-boot2docker-url:设置驱动地址( <em>如果默认驱动下载很慢,可以更改国内的下载路径</em> )</p>    <p>下面创建4个引擎,1个集群管理者和3个工作者: ??</p>    <pre>  docker-machine create -d virtualbox manager1  docker-machine create -d virtualbox worker1  docker-machine create -d virtualbox worker2  docker-machine create -d virtualbox worker3</pre>    <p>查看运行结果(docker-machine ls):</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/1ee2f677b0d390b7d68446715a880b72.png"></p>    <h3>初始化集群</h3>    <ul>     <li>连接 manager1</li>    </ul>    <pre>  eval $(docker-machine env manager1)</pre>    <p>查看运行结果:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/a81be8066d0679b747d8526ca8a0c92a.png"></p>    <ul>     <li>创建 swarm</li>    </ul>    <pre>  docker swarm init --advertise-addr 192.168.99.100</pre>    <p>参数说明:</p>    <p>--advertise-addr:设置管理节点的对外IP,供集群中的其他节点访问;</p>    <p>命令说明:</p>    <p>该命令会创建一个新的 swarm,以当前节点作为 swarm 的管理节点。同时生成2个 token (manager/worker)供其他节点加入使用( <em>查询token命令 docker swarm join-token</em> )。</p>    <p>查看集群节点状况(docker node ls):</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/f488d8b8401a77729811129d725a471f.png"></p>    <h3>加入工作节点</h3>    <pre>  # 连接 worker1  eval $(docker-machine env worker1)    # 加入 swarm  docker swarm join \  --token WORKER_TOKEN \  192.168.99.100:2377</pre>    <p>同上,将其余两个以 worker 身份加入</p>    <p>查看集群节点状况( <em>仅可在管理节点下查看</em> ):</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/2d91f1101f2e81d90b35cb4088f70e86.png"></p>    <h3>移除节点</h3>    <p>如果想要移除集群下的某个节点,可在该节点环境下,执行该命令:</p>    <pre>  $ eval $(docker-machine env worker3)    # 当前环境在 worker3 上  docker swarm leave</pre>    <p>查看集群节点状况</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/618cd5c56264db00c6e684e301b659bd.png"></p>    <h3>重新加入集群</h3>    <pre>  # 加入 swarm  docker swarm join \  --token WORKER_TOKEN \  192.168.99.100:2377</pre>    <p>查看集群节点状况</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/e6baf518e56af044adf2daa68ad17fec.png"></p>    <h3>移除无效节点</h3>    <pre>  docker node rm INVALID_ID</pre>    <p>查看集群节点状况</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/4551970eb24cedc3734700ec36f7b1d8.png"></p>    <h2>使用场景</h2>    <p>关于 swarm 集群的搭建已经完成了,接下来就是启动服务。启动服务的模式分为:replicated 和 global。</p>    <p>replicated(默认方式):先在一个 node 节点上创建一个服务,通过复制的方式进行扩展,这中间涉及扩展的策略。</p>    <p>global:在每个 node 节点上都会创建一个服务,像 Registrator(自动注册服务) 就很适合用这种方式执行。</p>    <h3>以 gobal 方式创建 nginx 服务</h3>    <pre>  docker service create --mode=global --name=web nginx</pre>    <p>查看服务启动情况(每个节点都起了一个 web 服务):</p>    <p><img src="https://simg.open-open.com/show/eaf1da031b89534bd7a729875250c156.png"></p>    <h3>以 replicated 方式创建 nginx 服务</h3>    <ul>     <li>创建一个 nginx 服务</li>    </ul>    <pre>  docker service create --name=web nginx</pre>    <p>查看服务启动情况:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/064026cd8184af943500b98d3e827286.png"></p>    <ul>     <li>将服务依次扩展至5个</li>    </ul>    <pre>  docker service scale nginx=2</pre>    <p>查看服务启动情况</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/e4c73d13b19ee8fdf5f34ff8aeab54c8.png"></p>    <pre>  docker service scale nginx=3</pre>    <p>查看服务启动情况</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/0785f8cc50c1da5d78dfe6d538d1cba9.png"></p>    <pre>  docker service scale nginx=4</pre>    <p>查看服务启动情况</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/9e5e7ae6e0e9a237306397eb5501f2ae.png"></p>    <pre>  docker service scale nginx=5</pre>    <p>查看服务启动情况</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/b4edfcf3e7576ba140fc43f885712d96.png"></p>    <h2>扩展分配策略</h2>    <p>从服务的扩展可以看出,其中存在了一定的分配策略。这里采用的是默认的 Spread 策略。下面简单描述下最常用的2种 Spread 与 BinPack。 </p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/6362c586d5f9740e1fb532d78fca3894.png"></p>    <ul>     <li> <p>Spread:依据节点个数进行平均分配。</p>      <ul>       <li>优势:在容器使用资源相对一致的情况下,整体资源使用在每个节点上做了平均的分配;</li>       <li>不足:若每个容器所占资源相差很大,那么节点的资源使用率将存在明显差异,导致资源使用的浪费;</li>      </ul> </li>     <li> <p>BinPack:尽可能的使用一个节点的资源,在节点资源不足的情况下,更换使用节点。</p>      <ul>       <li>优势:节点资源能得到充分使用;</li>       <li>不足:单节点的负重较高,而且每个节点性能未必都一样,可能会分重CPU或重磁盘读写等。</li>      </ul> </li>    </ul>    <p>真实场景还是得依据具体的业务来合理使用分配策略。特殊情况,还需要搭配使用 filters、affinity 来具体选择节点。 </p>    <h2>高可用</h2>    <p>服务的启动都是通过 manager 节点将启动服务分发给 worker 节点,而且服务的管理也是由manager节点来控制的。</p>    <ul>     <li> <p>manager 节点的可用性:我们可以设置多个 manager 节点。当 primary manager 挂掉后,secondary managers 中会选举一个作为 primary manager,以保证服务的高可用性。</p> </li>     <li> <p>服务高可用:服务如果启动失败,或中途异常中止,会进行自动重启。保障了扩展服务的可用性。</p> </li>    </ul>    <h2>总结</h2>    <p>本文主要讲述了如何使用 Docker Swarm 来做 docker 的集群管理。其中包括了集群部署、服务的启动、扩展,以及常用的分配策略。</p>    <p>swarm 在 docker 1.12开始被集成进了docker中。相比之前版本,以 docker run swarm create 启动的方式,现节点与节点之间是通过内置的 DNS 发现机制进行通信,使用更为便捷。</p>    <p>最后也提一下,使用 k8s 做容器集群管理的也在多数。这里不讨论两者的好坏,如果还没用 k8s 的可以考虑使用 swarm,毕竟目前是docker 内置的服务。</p>    <p> </p>    <p>来自:https://github.com/jasonGeng88/blog/blob/master/201704/docker_swarm.md</p>    <p> </p>