hansonwang99
V2EX  ›  Docker

Docker Swarm 集群初探

  •  
  •   hansonwang99 ·
    hansonwang99 · Mar 7, 2018 · 3199 views
    This topic created in 3062 days ago, the information mentioned may be changed or developed.

    Desktop


    前言

    相信 Docker 技术大家都有所了解,单个 Docker 能发挥的作用毕竟有限,也不便于管理,所以 Docker 得组集群来使用才能发挥强大的技术优势。既然要组集群那就涉及诸如 Docker 的资源调度、管理等等一系列问题。目前涉及 Docker 集群的三个主要的技术无外乎 Swarm、Kubernetes、Mesos 三种。从本文开始作者将会一一实践这几种主要的 Docker 集群技术,话不多说,现在开始。

    注意:作者的 kubernetes 相关实践在此


    环境准备

    • Mac OS X 10.13.2
    • Docker 17.09.1-ce-mac42 (21090)
    • virtualbox (虚拟集群中节点时需要)
    • boot2docker v1.8.0 (在虚拟节点中起 docker 环境时需要)

    环境搭建

    节点规划如下:

    集群节点规划图

    我们需要 4 个节点( 1 个 master + 3 个 slave ),由于没有真实地 4 台物理机,所以下文中是靠docker-machinevirtualbox以及boot2docker来虚拟出 4 个独立 IP 地址的带 docker 环境的节点,大家注意!

    环境安装:

    • Docker 环境安装:

    Tips: 以前 Mac 上一般是使用boot2docker这个专门为 OS X 上运行 Docker 而开发的一个轻量级的虚拟主机管理工具来安装 docker,现在boot2docker这种安装方式官方已经 deprecated 了(当然下文中还是需要boot2docker.iso的镜像来帮助我们在虚拟的节点上起 docker 环境),可以直接下载 docker 的 dmg 安装包双击进行安装即可

    我们选择 docker CE 版安装即可,下载链接如下: https://store.docker.com/search?type=edition&offering=community

    注意:选择官方 docker dmg 包安装完成以后,docker-machine已经天然地集成于其中了,该工具在下文中创建虚拟节点时需要,它是一个可以在虚拟主机节点上安装 docker engine 的工具

    • virtualbox 安装

    由于我们搭建集群需要具备多个不同 IP 地址的节点,然而我们手上仅一台电脑,所以需要借助 virtualbox 来虚拟出多个不同 IP 地址的节点供我们使用需要

    去官方下载 virtualbox 的 dmg 安装包,双击安装即可: https://www.virtualbox.org/

    • boot2docker 安装 Boot2Docker 是一个专为 Docker 而设计的轻量级 Linux 发型包,解决 Windows 或者 OS X 用户不能安装 Docker 的问题。Boot2Docker 完全运行于内存中,体积小,启动快。Boot2Docker 需要运行在 VirtualBox 中。

    我使用的是 brew 这个 mac 上的包管理器安装的,非常方便,只需一行命令: brew install boot2docker

    除此之外我们还需要下载 boot2docker.iso 镜像在后文中进行使用: https://github.com/boot2docker/boot2docker/releases/tag/v17.07.0-ce 我们先把boot2docker.iso下好后面备用


    Docker Swarm 集群实验

    先创建 4 个虚拟节点( 1 个 master + 3 个 slave )

    首先要将之前下载的boot2docker.iso放到/Users/你的用户名 /.docker/machine/cache/目录下,然后执行如下命令:

    docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso master
    docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave1
    docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave2
    docker-machine create --virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso slave3
    

    注意:上面若不指定 boot2docker 的路径:--virtualbox-boot2docker-url ~/.docker/machine/cache/boot2docker.iso,直接执行docker-machine create master创建节点时,可能会报No default Boot2Docker ISO found locally, downloading the latest release...这种错误!所以最好自己指定 boot2docker.iso 镜像路径

    docker-machine 命令创建虚拟机过程细节如下: docker-machine 命令创建虚拟机过程

    创建完 4 个节点以后,可以用docker-machine ls命令查看一下各个节点的情况,可以看到自动为其分配了独立的 IP 地址: docker-machine ls 查看虚拟节点创建情况

    ssh 接入虚拟节点

    开启 4 个独立的 terminal 终端,分别执行:

    docker-machine ssh master
    docker-machine ssh slave1
    docker-machine ssh slave2
    docker-machine ssh slave3
    

    执行后的效果如下图: 3 个 slave1 个 master 概览.jpg

    接下来在 master 上初始化一个 docker swarm 集群

    执行命令:

    docker swarm init --advertise-addr 192.168.99.100
    

    效果如下: 在 master 节点上初始化集群

    上述命令执行成功后,提示中会告知用户在 slave 节点上执行命令 docker swarm join --token SWMTKN-1-1uzft9zcrd5cl7eva4gr4ptgrs1gc252483ey19xfphcuxc8ta-evsmmj7b7kleh7yoezjutzuu2 192.168.99.100:2377 可以加入到该集群中,把命令都告诉你了,你说智不只能!

    将 3 个 slave 节点加入集群

    分别去三个 slave 上,输入上面提示中的命令:

    docker swarm join --token SWMTKN-1-1uzft9zcrd5cl7eva4gr4ptgrs1gc252483ey19xfphcuxc8ta-evsmmj7b7kleh7yoezjutzuu2 192.168.99.100:2377
    

    执行效果如下: master 上初始化集群以及 3 个 slave 加入集群

    注意:如果忘了 docker swarm join 命令中的 token 命令的话,可以使用命令docker swarm join-token worker来 get 之

    好,到此为止应该说 docker swarm 集群的搭建工作已经完成了,那下面在这个集群上做点实际的任务吧!

    开始在 master 节点上创建服务

    我们计划在该 docker 集群上部署高可用的 nginx 容器任务来作为演示: 在 master 节点上执行如下命令来创建名为 mynginx 的 service,让其有 2 份 nginx 容器副本分配到集群中去,起在 8080 端口: docker service create --replicas 2 -d -p 8080:80 --name mynginx registry.docker-cn.com/library/nginx 然后使用如下两条命令查看效果:

    docker service ls
    docker service ps mynginx
    

    执行效果如下: 在 master 节点上刚创建 mynginx service

    此处有两点需要注意:

    1. 我们使用了registry.docker-cn.com/library/nginx作为加速镜像,不然可能在 slave 上 pull 镜像的时候 timeout
    2. 注意此处创建了 service 之后并不是 nginx 容器立马都在 slave 上起起来了,是需要等一段时间的(如,我等了近 8 分钟),因为在 slave 上还要去 pull nginx 镜像,再启动 nginx 容器等,没有那么快

    等待若干分钟以后,我们再看效果,发现此时任务顺利地分发到 slave1 和 slave2 上了:

    经过若干分钟后在 master 上查看 service 的效果

    分别用浏览器访问: http://192.168.99.101:8080 和 http://192.168.99.102:8080,会得到如下结果: 192.168.99.101 ( slave1 )上 nginx 容器访问结果

    192.168.99.102 ( slave2 )上 nginx 容器访问结果

    成功访问到了 slave 节点中起起来的 nginx 服务!

    此时分别去 slave1 和 slave2 上查看容器运行情况,结果如下: slave1 和 slave2 上查看容器运行情况

    进一步实验:扩容 service 中的任务

    我们想将 nginx 容器平滑地扩容到 3 份,在 master 上执行:

    docker service scale mynginx=3
    

    然后在 master 上查看 service,发现新增的一个容器任务分配到 slave3 上了,当然此时 slave3 上正在 preparing: 扩容为 3 份后任务被分到 slave3 上).jpg

    等若干分钟后在 master 上再次查看 service,发现 slave3 上的 nginx 容器任务成功启动了:

    成功扩容之后 master 节点上看集群信息

    去 slave3 节点上 docker ps 看一下,发现容器确实启动了: 扩容到 slave3 后 slave3 上的 docker ps 信息

    ####进一步实验:集群中 service 高可用 目前有 3 个运行的 nginx 容器保证服务的可用性,如果其中一个容器意外关闭将会是什么情况?接下来就来模拟

    我们关闭 slave1 上此时正在运行着的 nginx 容器,看服务有什么变化: 关掉 slave1 上的 nginx 容器

    此时去 master 节点上查看信息发现,被关掉的 nginx 被分配到 master 上重启了:

    关闭了 slave1 后,在 master 节点上恢复了 nginx 服务

    此时我又关闭 master 节点上启动的 nginx 容器,发现刚关闭不久后,nginx 容器又重新在 master 上恢复了:

    再次关闭 master 上的 ngix,结果在 master 上全部重启.jpg

    接下来我们来将 slave3 宕机(宕机和前文的关闭 nginx 容器不同,此处模仿的是物理宕机),我们在控制台中使用 docker-machine stop 来模拟宕机动作: 将 slave3 从集群中断开

    此时去 master 上查看 service 信息发现 slave3 宕机以后,nginx 任务又重启与 slave1 上来保持高可用:

    将 slave3 宕机后 nginx 重启在 slave1 上

    最后来把狠的,我们将 slave1,slave2,slave3 全部从集群中断开: 将所有节点全部宕机.jpg

    结果去 master 上查看 service 信息,发现 3 个容器副本全部迁移到 master 之上了:

    3 个 slave 全部宕机后任务全部重启在 master 上

    此时在 master 上执行docker ps查看容器信息如下:运行着 3 个 nginx 容器: slave 全部宕机后在 master 节点上看到的 nginx 容器进程

    总而言之,无论怎么操作集群都能保持制定数量的容器副本来实现高可用!


    [干货] 总结一下上文中的常用命令

    • 创建虚拟主机节点
    docker-machine create 虚拟主机名
    
    • 查看虚拟机节点信息
    docker-machine ls
    
    • 停止虚拟主机节点
    docker-machine stop 虚拟主机名
    
    • 删除虚拟主机节点
    docker-machine rm 虚拟主机名
    
    • 初始化 docker swarm 集群
    docker swarm init --advertise-addr master 的 IP 地址
    
    • slave 节点加入集群
    docker swarm join --token [token] [master 的 IP]:[master 的端口]
    
    • slave 节点主动离开集群
    docker swarm leave
    
    • 在 master 上获取加入集群的 token
    docker swarm join-token worker
    
    • master 上创建 service 举例:
    docker service create --replicas 2 -d -p 8080:80 --name 服务名 镜像名
    
    • master 上查看 service 信息
    docker service ls
    docker service ps 你所创建的服务的 ID
    
    • 在 master 上删除 service
    docker service rm 服务名
    
    • 在 master 上进行服务扩容
    docker service scale 你的 service name=你要的副本数目
    

    参考文献


    后记

    想要看作者关于 kubernetes 的相关实践? 请戳这里

    作者更多的原创文章在此

    mahone3297
        1
    mahone3297  
       Mar 7, 2018
    * 可以编写 docker-compose.yml ,然后用 docker stack deploy 直接一键部署
    * docker 的 load balance 是怎样的?我发现,用 nginx replicas=3 的话,你刷新,他每次直接轮询 n1,n2,n3 (假设 3 个 node ),而是 n1 处理了好多请求,才到 n2,n2 也是处理了好多请求,才到 n3.不知道这个策略是怎样的,请教。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2773 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 12:57 · PVG 20:57 · LAX 05:57 · JFK 08:57
    ♥ Do have faith in what you're doing.