在之前的工作中,我一直使用docker run命令,单独启动container,再加入overlay网络,以实现部署工作。这种方式看似直接,但是随着服务包含的container个数越来越多,docker命令也就越来越多,由此带来许多重复工作。

在官网上看到,docker-compose可以执行container编排(容器编排),尤其是compose file -v3版本加入了许多功能,可以方便地把服务中的container部署在单个docker节点或者多个swarm节点上。考虑到目前的使用情况,我们确实到了需要使用docker高级特性的阶段,所以进行实践。

分享一个示例:https://hackernoon.com/deploy-docker-compose-v3-to-swarm-mode-cluster-4159e9cca712#.lyx2e8fd9

上面的例子描述了,如何使用compose file v3和swarm,构建一个投票系统。与本文的区别:实例中运用了docker stack deploy在多个docker swarm节点上部署应用服务;本文采用docker-compose up,分别在两台docker节点上面部署应用容器。

1. 使用docker-compose,进行container编排

docker-compose是容器编排的利器,那么我们应该如何使用呢?

1.1 业务需求

我们的业务:在两台docker主机上,分别建立一组服务。简单起见,我把docker节点命名为nodeDB和nodeService。顾名思义,我们要在nodeDB上面建立database服务(部署oracle),在nodeService上部署应用容器。容器之间的跨主机通信就是通过swarm的overlay网络完成。

1.2 编写dockerfile

FROM 172.100.1.15:5000/oracle11g_server_v3

RUN mkdir /frs/
COPY /cafisFRSDB/ /frs/
COPY /cafisFRSDB/listener.ora /app/oracle/11.2.0/network/admin/

CMD ["/bin/bash", "/frs/startup.sh"]

dockerfile内容很简单,就是copy文件;CMD就是在启动container时,执行shell脚本(启动oracle服务和实例,实现业务逻辑)。

1.3 编写docker-compose.yml

version: '3'

services:
  frs_orasvr:
    build:
      context: ./frsDB
      dockerfile: Dockerfile
    image: frs_orasvr_img:v1
    container_name: frs_orasvr
    hostname: frs_orasvr
    ports:
      - "1521:1521"
    volumes:
      - /DATA/compose_frs/frsDB/cafisFRSDB/:/frs
    networks:
      - qrtSwamComposeNet

networks:
  qrtSwamComposeNet:
    driver: overlay

注意几个内容:

  • networks: 在compose file v3中,docker允许通过networks关键字,定义一个基于 docker0网桥的subnet,然后把我们的服务加到这个subnet中,这样实现了服务之间的隔离。一旦不需要这组服务,我们可以通过命令docker-compose down卸载服务和对应的subnet,不会对其他服务造成影响。

  • build: 通过build命令,我们可以指定加载哪个dockerfile。我们可以把base image定制为自己的image,这些定制化的步骤可以用dockerfile记录下来。docker image和dockerfile都可在开发人员之间共享。如果image过大不便其他人员pull拉取,我们可以共享dockerfile,使他人在本地构建image。

  • 其他docker-compose文件指令可参见compose语法。

1.4 启动docker服务

现在我们到docker-compose.yml文件所在的目录,启动服务

# cd /parh/to/docker-compose.yml

# docker-compose up

# docker-compose ps      // 检查服务是否启动

检查网络

# docker network ls

NETWORK ID          NAME                      DRIVER              SCOPE
p729h9nw2mxo        composefrs_qrtSwamComposeNet   overlay          swarm
efd78e72a392        bridge                    bridge              local
e08545f73ee1        docker_gwbridge           bridge              local
60fb66247b73        host                      host                local
2th1f3svyriy        ingress                   overlay             swarm
1527c9d992e8        kj66be_net                bridge              local
c060dea57803        kj66interchange_default   bridge              local
c7d9e786b990        none                      null                local

检查imge

# docker image ls

REPOSITORY    TAG     IMAGE ID      CREATED        SIZE
frs_orasvr_img  v1  6e774eb7ee64  2 hours ago    207MB
<none>        <none>  e0f9577e8ef7  2 hours ago    207MB

compose运行image,生成container,并且调用shell脚本

# docker ps

伸缩容器

# docker-compose up --scale harbor-adminserver=2     

// 需要指定对应容器的副本个数

到此,我们在nodeDB上面的工作就完成了。

1. 5 启动NodeService服务

NodeService的docker-compose.yml我们要在这个host (swarm node) 部署服务,服务中的container需要与之前node上面oracle服务通信。直接上code (简单起见,只列出了services 中的一个 container)

version: '3'

services:
  frs_ftsoft:
    build:
      context: ./ftsoft
      dockerfile: Dockerfile
    image: frs_ftsoft_img:v1
    networks:
      - composefrs_qrtSwamComposeNet
    container_name: frs_ftsoft
    hostname: frs_ftsoft
    mac_address: xx:xx:xx:xx:xx:xx
    volumes:
     - /data/CabisSvr/DockerFrs/ftsoft:/frs

networks:
  composefrs_qrtSwamComposeNet:
    external: true

Compose文件中使用的dockerfile内容与上个差不多,在这里就不多说了。

注意:

  • 由于之前在nodeDB的compose file里已经创建了网络,我们这里需要指定为external:true (不需要在创建了),在container里面加入即可。

  • 我们直接运行docker-compose up会报错,内容大致为找不到指定网络。这是由于之前在nodeDB上面创建的network不会自动在新的node上显示(官方说法),所以我们需要先在nodeService上面运行一个container,让其加入网络“composefrs_qrtSwamComposeNet”,例如:

# docker run -d --name=mybusybox --network=composefrs_qrtSwamComposeNet busybox /bin/sh

之后,我们便可以在nodeService上看到composefrs_qrtSwamComposeNet网络,此时再运行docker-compose up就好了。

2. 使用docker swarm,进行stack编排

在nodeDB和nodeService节点上,通过运行两次docker-compose up命令,我们实现了手动在不同的docker节点上运行容器。

用docker stack的方式部署nodeDB

# cd /path/to/docker-compose.yml

# docker stack deploy -c docker-compose.yml stack_name

# docker stack ls

# docker service ls

# docker service scale service_name=10

同理,对于nodeService使用相同的方法。

第二种方式最大好处是在多台docker swarm节点(swarm集群,不用关心应用容器在哪个docker swarm节点上,集群节点易于扩充)上完成部署(传说中的一键部署),最终服务以service端口映射宿主机端口的方式,展现给外部用户。

3. 参考文章

https://www.cnblogs.com/atuotuo/p/6588331.html

https://blog.csdn.net/pmlpml/article/details/53786575?locationNum=1&fps=1

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐