Docker Swarm集群初探

作者: CodeSheep | 来源:发表于2018-01-04 18:37 被阅读616次
    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的相关实践?
    请戳这里

    作者更多的原创文章在此


    CodeSheep

    相关文章

      网友评论

      • 开发者头条_程序员必装的App:感谢分享!已推荐到《开发者头条》:https://toutiao.io/posts/7cleyz 欢迎点赞支持!使用开发者头条 App 搜索 264797 即可订阅《CodeSheep》
        CodeSheep:@开发者头条_程序员必装的App 感谢推荐
      • 玲珑骰9023:666
        CodeSheep:@玲珑骰9023 666
      • resolvewang:兄弟,swarm的master如何做高可用呢?这里貌似HA全是模拟的minion挂掉的情况
        sjyu_eadd:@resolvewang 正常,毕竟现在k8s一统天下了,学容器难免要学k8s,不过对照比较学习也好😀
        resolvewang:@sjyu_eadd 感谢告知,我去了解下。现在转到k8s上了,哈哈哈
        sjyu_eadd:@resolvewang master的高可用,可以使用docker swarm promote/demote命令将master和slave角色之间进行切换,貌似还挺方便
      • 04f6412dddc7:virtualbox 可以换成 vmvare 吗?
        李伟:貌似docker-machine不支持vmware,不过你可以手动创建虚拟机
        CodeSheep:@请叫我浮夸哥 这个我也没尝试过,不知道是否兼容,你可以试验看看

      本文标题:Docker Swarm集群初探

      本文链接:https://www.haomeiwen.com/subject/xihrnxtx.html