1

本篇教程会介绍如何使用docker swarm进行容器的编排与分发friendlyhello:v4,这一服务可以通过浏览器访问,获取当前节点的Hostname,最终效果如下:

Screen Shot 2019-09-03 at 10.04.24 AM.png

STEP 1: 创建虚拟机

为了模拟集群环境,我们创建3个虚拟机,1个作为manager节点、另外2个则是worker节点,我自己的mac是8g内存,虽然有些捉急,但3个vm还是撑得住的

$ docker-machine create manager
$ docker-machine create worker-1
$ docker-machine create worker-2

Screen Shot 2019-09-03 at 9.20.51 AM.png

然后分别进入这三台虚拟机(请开三个terminal来操作):

$ docker-machine ssh manager
$ docker-machine ssh worker-1
$ docker-machine ssh worker-2

Screen Shot 2019-09-03 at 9.29.41 AM.png

STEP 2: 初始化集群

首先确认一下每个vm的IP:

$ ifconfig

例如,我现在三个ip分别是:

  • manager: 192.168.99.112
  • worker-1: 192.168.99.113
  • worker-2: 192.168.99.114

然后在manager里,执行:

$ docker swarm init --addvertise-addr <你的manager节点的ip>

# 我自己的命令:
$ docker swarm init --addvertise-addr 192.168.99.112

完成后,复制输出的加入swarm集群的命令,在两个worker里分别执行一下,最后效果如下就说明成功了:

Screen Shot 2019-09-03 at 9.30.53 AM.png

STEP 3: 创建friendlyhello:v4服务

我们先在当前目录下直接创建两个文件,app.py Dockerfile,并加入如下代码:

  • app.py

    from flask import Flask
    from redis import Redis, RedisError
    import os
    import socket
    
    # Connect to Redis
    redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
    
    app = Flask(__name__)
    
    @app.route("/")
    def hello():
        try:
            visits = redis.incr("counter")
        except RedisError:
            visits = "<i>cannot connect to Redis, counter disabled</i>"
    
        html = "<b>HostName:</b> {host_name}<br/>" \
               "<b>Hostname:</b> {hostname}<br/>" \
               "<b>Visits:</b> {visits}"
        return html.format(host_name=os.getenv("HOSTNAME", "UNKNOWN"),
                           hostname=socket.gethostname(), visits=visits)
    
    if __name__ == "__main__":
        app.run(host='0.0.0.0', port=5000)
  • Dockerfile

    FROM python:3.7-slim
    
    WORKDIR /app
    
    COPY . /app
    
    RUN pip install flask redis -i https://mirrors.aliyun.com/pypi/simple  --trusted-host mirrors.aliyun.com 
    EXPOSE 5000
    
    CMD ["python", "app.py"]

    Screen Shot 2019-09-03 at 9.34.05 AM.png

接着构建image

$ docker build -t friendlyhello:v4 .

Screen Shot 2019-09-03 at 9.35.14 AM.png

然后通过docker service create来创建服务,--replicas 3参数表示创建3个副本:

$ docker service create --replicas 3 -p 5000:5000 --name friendly friendlyhello:v4

Screen Shot 2019-09-03 at 9.36.24 AM.png

成功以后,我们就可以看到这一服务的task们了:

$ docker service ps friendly

Screen Shot 2019-09-03 at 9.39.09 AM.png

但是,我们发现只有manager节点的task启动了,2个worker节点都表示没有镜像,所以接下来我们就需要去做分发

STEP 4: 快速分发镜像到所有节点

我们先缩个容:

$ docker service scale friendly=1

Screen Shot 2019-09-03 at 9.40.35 AM.png

为了高效分发,我们不用docker hub,而是自己部署一个registry服务:

$ docker service create --name registry --publish 5555:5000 registry:2

看看成功了没:

$ docker service ps registry

Screen Shot 2019-09-03 at 9.42.54 AM.png

OK,接下来我们来把friendlyhello:v4镜像给推送到registry,在此之前,我们先创建一个配置文件,加入配置,否则可能会出现https相关问题:

$ vi /etc/docker/daemon.json

写入:

{"insecure-registries": ["<你的manager的ip>:5555"]}

// 我的配置:
{"insecure-registries": ["192.168.99.112:555"]}

Screen Shot 2019-09-03 at 9.45.41 AM.png

接着重启一下docker:

$ sudo /etc/init.d/docker restart

重启后,我们就可以重新打tag然后pushregistry了:

$ docker tag friendlyhello:v4 <你的manager的ip>:5555/friendlyhello:v4
$ docker push <你的manager的ip>:5555/friendlyhello:v4

# 我的命令:
$ docker tag friendlyhello:v4 192.168.99.112:5555/friendlyhello:v4
$ docker push 192.168.99.112:5555/friendlyhello:v4

Screen Shot 2019-09-03 at 9.50.10 AM.png

如果这里出现了奇奇怪怪的问题,试试等个几秒重新执行一下

接着,分别到worker-1worker-2里,加入一个一样的daemon.json:

$ vi /etc/docker/daemon.json

Screen Shot 2019-09-03 at 9.51.58 AM.png

别忘了添加完配置后重启一下

重启后,就可以pull下我们需要的那个镜像了:

$ docker pull 192.168.99.112:5555/friendlyhello:v4
$ docker tag 192.168.99.112:5555/friendlyhello:v4 friendlyhello:v4

Screen Shot 2019-09-03 at 9.54.59 AM.png

如果又出现了奇奇怪怪的问题,可以试试在manager节点再重新push一下

接着在manager节点扩容:

$ docker service scale friendly=3

Screen Shot 2019-09-03 at 9.56.02 AM.png

这下3个节点的task就都成功跑起来了:

$ docker service ps friendly

Screen Shot 2019-09-03 at 9.56.35 AM.png

可以通过浏览器访问看看:

Screen Shot 2019-09-03 at 9.59.57 AM.png

部署是没什么问题了,不过我们还需要让它显示所使用的node的名字,这需要加入环境变量。

我们先关了现在的服务:

$ docker service rm friendly

再重新创建,同时加入新的参数:

$ docker service create --replicas 3 -p 5000:5000 --name friendly3 -e HOSTNAME="{{.Node.Hostname}}" --hostname="{{.Node.Hostname}}-{{.Node.ID}}-{{.Service.Name}}" friendlyhello:v4

Screen Shot 2019-09-03 at 10.03.46 AM.png

再来访问看看:

Screen Shot 2019-09-03 at 10.04.24 AM.png

STEP 5: 用Portainer可视化管理Swarm集群

回到manager节点,现在来通过docker stack部署Portainer

$ curl -L https://downloads.portainer.io/portainer-agent-stack.yml -o portainer-agent-stack.yml
$ docker stack deploy --compose-file=portainer-agent-stack.yml portainer

完成后,我们可以通过:9000端口来访问Portainer

Screen Shot 2019-09-03 at 3.10.54 PM.png

这里有丰富的功能,可以方便我们可视化地操作swarm集群

Screen Shot 2019-09-03 at 3.11.01 PM.png

Screen Shot 2019-09-03 at 3.11.48 PM.png

Screen Shot 2019-09-03 at 3.11.07 PM.png


Ron_You
196 声望3 粉丝

一个普普通通的大学生。