DOCKER 07:docker swarm

docker compose 主要用于单机容器编排,docker swarm 则用于跨主机容器编排。

docker compose 需要单独下载执行脚本,docker swarm 系统自带无需安装。

docker swarm 属于需要了解得东西,毕竟生产中大多选择还是 Kubernetes(K8S)。

说明:

在 docker swarm 中包含了两个角色,Manager 和 Worker。Manager 是一个集群的核心,起着调度作用,建议部署多节点,且节点数量为奇数,防止脑裂。

在 Mnager 之间通信方式采取的是 Raft 进行数据信息同步,Worker 则是工作节点。

 

 

docker swarm 创建

 

这里准备了 4 台虚拟机:192.168.200.101(Manager),192.168.200.102-104(Worker)

首先在 4 台机器上都安装配置启动好 docker。

1. 101 Manager 节点初始化:

docker swarm init --advertise-addr=192.168.200.101

结果如图:

注意:红色部分将是其它节点加入该集群的依据,要保存好!

 

2. 在 102-104 节点上面执行该命令加入集群:

docker swarm join --token SWMTKN-1-4ht8hjdp73jrkguh7ux8e5uneq2mm1ovi91oko5a8vpearh5ss-8wn5u0kf9jxd0xj6wg29wq3bq 192.168.200.101:2377

结果如下:

可以看到接入集群成功,并且是作为 worker 存在!

 

3. 查看集群节点情况:

docker node ls

结果如图:

从这里也可以发现主机名不一致的重要性。

此时,docker 集群中所有对于容器的处理命令都应该在 Manager 节点上面执行,再由 Manager 分发调度到各个 Worker 节点。

 

几种加节点常见的报错:

1. 节点加错了想删除,去该节点执行退出集群:

docker swarm leave --force

但是这并会在 Manager 节点上面删除该节点,只是将节点状态换成 Down:

重新加入该节点则会新增一个:

可以 Manager 节点上手动删除 Down 的节点:

docker node rm pdfimxsip775w7pz9hhonzatd

再度查看:

 

2. 加入集群时候报错:Error response from daemon: error while validating Root CA Certificate: x509: certificate has expired or is not yet valid

原因为几台机器的时间可能不一致,可以使用 ntp 同步时间后再度添加。

 

3. 加入等待很久没反应,报错:connect: no route to host

可能是防火墙没有关闭导致网络不通,关闭防火墙再试。

 

 

docker swarm 操作

 

在 docker swarm 中,容器都是 service,所以 docker swarm 的操作都是 docker service xxx 操作。

注意:所以操作都是在 Manager 节点执行的。

1. 创建一个 service:

docker service create --name b1 busybox /bin/sh -c "while true;do sleep 3000;done"

执行方式和 docker run 其实差不多。

 

2. 查看运行的容器:

docker service ls

结果如图:

查看运行的容器中最重要的就是这个副本数,可以知道该容器运行了几个。

 

3. 查看容器运行在那个具体节点:

docker service ps b1

结果如图:

可以看到运行在了 node 1 节点上。而这个 node 1 节点也是 Manager 本身。

 

4. 删除容器测试:

docker container rm -f f190b31bbc90

此时再度查看:

可以看到再度启动了一个容器顶替了删掉的那个。

这就看出了 swarm 的好处,它运行的容器是被 service 管理的,只要 service 不删除,下面的容器你删除之后还是能够自动重建。

 

5. 删除 service:

docker service rm b1

结果如图:

 

 

docker swarm 实战

 

再开始之前先删除掉多余的网络,volume 干扰。

其中两个是 docker swarm 需要用到的网络,在构建的时候已经自动生成。

 

1. 创建本次实战的专属 overlay 网络,为了和其它服务网络隔离:

docker network create -d overlay wordpress-overlay

结果如图:

 

2. 通过 docker swarm 创建 mysql 数据库:

docker service create --name wordpress-db --env MYSQL_ROOT_PASSWORD=123456 --env MYSQL_DATABASE=wordpress --network wordpress-overlay --mount type=volume,source=wordpress-db-data,destination=/var/lib/mysql mysql:5.7

结果如图:

 

3. 创建 wordpress:

docker service create --name wordpress-web -p 8000:80 --network wordpress-overlay --env WORDPRESS_DB_PASSWORD=123456 --env WORDPRESS_DB_HOST=wordpress-db wordpress

结果如图:

可以看到此时 wordpress 的服务被调度到了 node-02 节点上面。

 

4. 访问测试:

Manager 节点 IP 访问:

Worker 节点访问:

发现集群内所有节点的 IP 通过制定的端口都能访问到该服务。

 

5. 集群扩容:

当业务量上来的时候,单节点的服务器已经带不动了,就可以运行多借点的 WEB。

docker service scale wordpress-web=3

结果如图:

可以看到其余节点也被分配到了 web 服务。

 

关于为啥一个集群节点运行了 web 服务器所以节点的 IP 都能访问的原理:Routing mesh

1. 当一个 service 访问另外一个 service 的时候,容器之间采用的是 overlay 网络。

2. 当外部访问容器服务,其实是访问到 LVS 上面的虚拟 IP,这个 IP 和服务做了绑定,并实现了负载均衡。所以无论哪个 IP 进来,都是通过 gwbridge 网络调度到指定网络名称空间,最终都能到达 LVS 调度器。

 

 

docker swarm 中的 docker-compose.yml

 

和单机运行一样,docker swarm 运行多个复杂关系的容器的时候每次都需要手动敲命令,那显然是不合理的,所以它也引入了 docker-compose 文件。

https://docs.docker.com/compose/compose-file/

删除掉之前的 wordpress 项目,这次试用 docker-compose 来定义:

version: "3"

# 容器
services:
  # 数据库
  wordpress-db-demo:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: wordpress
    networks:
      - wordpress-overlay-demo
    volumes:
      - wordpress-db-data-demo:/var/lib/mysql
    deploy:
      mode: global
      placement:
        constraints:
          # 指定运行的节点
          - node.role == manager

  # web
  wordpress-web-demo:
    image: wordpress
    ports:
      - 8000:80
    environment:
      WORDPRESS_DB_PASSWORD: 123456
      WORDPRESS_DB_HOST: wordpress-db-demo
    depends_on:
      - wordpress-db-demo
    networks:
      - wordpress-overlay-demo
    deploy:
      mode: replicated
      replicas: 3
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      update_config:
        parallelism: 2
        delay: 10s
      placement:
        constraints:
          - node.role == worker

volumes:
  wordpress-db-data-demo:

networks:
  wordpress-overlay-demo:
    driver: overlay

相较于 docker 直接使用的 docker-compose 配置,在 docker swarm 中多了 deploy 字段。

该字段一般用于定义运行规则,如运行的类型,指定节点,运行的数量,重启规则等等。

执行运行改配置:

docker stack deploy wordpress --compose-file=docker-compose.yml

注意,在使用 docker-compose 配置的时候需要使用 stack 命令,而不再是 service 和 swarm 命令。

查看运行的容器信息:

1. 查看运行了哪些 stack:

docker stack ls

 

2. 查看指定 stack 运行的节点信息:

docker stack services wordpress

 

3. 查看容器运行的具体节点:

docker stack ps wordpress

结果如下:

当然删除同理!

 

 

服务灰度更新

 

1. 在所以节点上面都新增目录,app.py,Dockerfile:

mkdir flask-update-demo
cd flask-update-demo/

app.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return "Version 1.0\n"
if __name__=="__main__":
    app.run(host="0.0.0.0", port=5000)

Dockerfile:

FROM python:2.7
LABEL author="Dylan" mail="1214966109@qq.com"
RUN pip install flask
COPY app.py /app/
WORKDIR /app/
EXPOSE 5000
CMD ["python", "app.py"]

 

2. 将 Dockerfile 构建成镜像:

docker build -t dylan/flask-update-demo:v1.0 .

 

3. 将 app.py 中 Version 改为 2.0 再度构建镜像:

docker build -t dylan/flask-update-demo:v2.0 .

结果如图:

 

4. 此时部署 v1 版本:

docker network create -d overlay flask-overlay-demo
docker service create --name flask-demo -p 8000:5000 --network flask-overlay-demo dylan/flask-update-demo:v1.0 

此时新开窗口访问测试:

sh -c "while true;do curl 127.0.0.1:8000 && sleep 1;done"

结果如图:

 

5. 扩容升级:

docker service scale flask-demo=3
docker service update --image dylan/flask-update-demo:v2.0 flask-demo

结果如图:

可以发现升级过程中两个版本并排运行:

升级完成后版本统一!

 

6. 版本回滚:

docker service rollback flask-demo

结果如图:

再次回到两个版本并排运行:

最终回滚完成!

以上就是  docker swarm 需要了解的内容,也是对于 docker 自带的容器编排需要了解的内容。不需要刻意去记,了解这些特征即可。

毕竟,学习这些的目的其实还是为了学习 Kubernetes 做准备。

 

posted @ 2020-03-02 11:41  Dy1an  阅读(126)  评论(0编辑  收藏