在之前的一文中介绍了使用Docker Compose来在单个Docker主机上部署多个服务(每个服务会创建一个容器)

本文介绍Swarm模式和多主机上如何部署。

Docker Stack和Docker Compose的对比

Stack和Compose类似,都使用Compose文件,也都是基于服务进行构建,然后使用docker stack deploy完成部署和管理,

使用Docker Compose时,YAML文件中services配置中不能使用deploy,只有在swarm模式下才会有用,因此基于swarm模式的Docker Stack可以使用deploy来配置集群服务。可选的参数可以参考:https://www.runoob.com/docker/docker-compose.html

其次Docker Compose中service可以使用build配置参数,来使用项目目录中的Dockfile编译一个镜像,并创建容器,但是Docker Stack则不支持编译镜像,只能使用image配置参数指定镜像,因此在部署Stack之前,所有的镜像都要先编译完成。

Docker Stack部署

实验环境:本次集群搭建基于两个腾讯云CVM服务器,安装的是CentOS 7.X,安装了宝塔面板(方便安装软件,如Docker),安全组放通TCP 2377端口,并都关闭防火墙。

查看防火墙状态
firewall-cmd --state

停止firewall
systemctl stop firewalld.service

禁止firewall开机启动
systemctl disable firewalld.service 

使用Docker官网介绍的getting-started应用

1. 初始化管理节点

在一个Docker主机节点上初始化管理节点:docker swarm init

2. 添加Worker节点

在另一个Docker主机节点上使用 docker swarm join --token命令加入Swarm集群,成为Worker节点。

3. 在Manager节点上查看swarm集群节点信息

[root@VM_0_8_centos ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
4fke7k5jiqukexauemoa8ek1r     VM-0-3-centos       Ready               Active                                  19.03.12
au7ybr304x2qwd5enc1zgop3e *   VM_0_8_centos       Ready               Active              Leader              19.03.12

4. 编写docker-stack.yml文件

添加docker-stack.yml文件,里面定义了网络,deploy部署约束,使得app服务运行在管理节点上,mysql服务运行在Worker节点上。

其中的第一个app服务使用的镜像是上一篇博客中创建并上传到Docker Hub的,这里是在管理节点登陆了我的Docker Hub账号,然后拉取了该镜像

version: "3.8"

services:
  app:
    image: cyc97/getting-started:latest
    ports:
      - 3000:3000
    working_dir: /app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos
    deploy:
      replicas: 1
      placement:
        constraints:
          - 'node.role == worker'
    networks:
      - tencent-cvm-tunnel

  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos
    deploy:
      replicas: 1
      placement:
        constraints:
          - 'node.role == manager'
    networks:
      - tencent-cvm-tunnel

volumes:
  todo-mysql-data:
  
networks: 
  tencent-cvm-tunnel:
 
 

5. 运行部署命令

在管理节点,进入项目目录,运行部署命令,指定stack文件和部署的stack项目名称

docker stack deploy -c docker-stack.yml startedstack

[root@VM_0_8_centos app]# docker stack deploy -c docker-stack.yml startedstack
Creating network startedstack_tencent-cvm-tunnel
Creating service startedstack_app
Creating service startedstack_mysql
[root@VM_0_8_centos app]# docker stack ls
NAME                SERVICES            ORCHESTRATOR
startedstack        2                   Swarm

6. 查看Swarm集群中的Stack详情

docker stack ps startedstack查看当前Stack的详细信息,

[root@VM_0_8_centos ~]# docker stack ps startedstack
ID                  NAME                   IMAGE                          NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
qb73assy6d88        startedstack_mysql.1   mysql:5.7                      VM_0_8_centos       Running             Running 13 minutes ago   
txu1b1yah3jn        startedstack_app.1     cyc97/getting-started:latest   VM-0-3-centos       Running             Running 10 minutes ago  

如果发现某个服务没有启动,可以使用docker service logs startedstack_app查看该服务的日志:

startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | yarn install v1.22.4
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | info No lockfile found.
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | [1/4] Resolving packages...
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | [2/4] Fetching packages...
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | [3/4] Linking dependencies...
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | [4/4] Building fresh packages...
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | success Saved lockfile.
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | Done in 0.06s.
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | yarn run v1.22.4
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
startedstack_app.1.tdtq0ozgeoyy@VM-0-3-centos    | error Couldn't find a package.json file in "/app"

报错是在/app目录下没有找到package.json,这是一开始的YAML文件编写有误导致的,直接使用了docker-compose.yml文件里的设置,主要还是对Stack文件中各参数配置还不熟悉。

我们可以使用docker service ls查看当前集群内的服务部署情况:

[root@VM_0_8_centos ~]# docker service ls
ID                  NAME                 MODE                REPLICAS            IMAGE                          PORTS
kokc451q0tkq        startedstack_app     replicated          1/1                 cyc97/getting-started:latest   *:3000->3000/tcp
84jzrwxdthbn        startedstack_mysql   replicated          1/1                 mysql:5.7  

7. 测试应用

由于我们在docker-stack.yml*文件中配置的端口是3000,所以需要在腾讯云CVM上设置安全组,放行TCP 3000端口

请输入图片描述

可以使用Swarm集群内任意节点的IP加端口号来访问应用,因为前面的Stack YAML文件中,定义了-p 3000:3000,这会在所有Swarm节点创建一个入站模式的端口映射。即使某个节点上并未运行服务的副本,依然可以进入该页面,因为所有节点都配置有映射,会将请求转发给运行有服务副本的节点。

请输入图片描述

后续

本次Swarm集群部署中未涉及密钥、数据加密等操作,《深入浅出Docker》一书中的例子包含了更多的配置信息,可以参考使用Docker Stack部署应用

更多的命令可以参考:

Docker官方文档

Reference documentation

如果觉得我的文章对你有用,请随意赞赏