Docker - 使用Swarm和compose部署服务(containers)

前言

 

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

 

在官网上看到了通过 docker-compose 可以执行container的编排,尤其是compose files -- V3版本,加入的许多功能可以方便我们将服务中的contain部署在单独的docker host 或者多个 hosts (swarm 节点) 上,于是考虑到目前对于 docker 的使用情况,确实也到了进行高级特性的尝试阶段,于是乎,走起!

 

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

上面的说的是如何使用compose V3 + swarm 构建一个猫狗投票系统,官方的例子,描述的很详细,有兴趣的童鞋可以研究一下。。。我在这里部署的方式也是使用了类似的方法,区别之处在与:实例中运用了“docker stack deploy”命令在多个host上面部署,而我使用的是“docker-compose up” 分别在两个host上面启动与部署服务。 

 

准备工作

首先是通过 Swarm 创建 nodes,并且创建Overlay网络模式. 我在这里就不在赘述,大家可以参看我之前的随笔或者利用万能的互联网找到答案。

我这里使用的Docker engine 和 Docker-compose 版本如下:

 

Docker-compose

众所周知,compose 就是 docker提供给我们用来进行编排的利器,那么我们应该如何使用她呢?

在解析docker-compose.yml之前,我想先说明一下我的业务,在熟悉业务之后,我们再来看看具体的"code".

业务需求:我们要在两个host (swarm node)上面分别建立一组服务,为了简单起见,我将nodes命名为nodeDB和nodeService;顾名思义,我们就是要在nodeDB上面建立database的服务(我这里是部署oracle server),在nodeService上面部署我们的程序(containers). 而 containers 之间的通信就是通过Swarm的Overlay网络来完成的。

 

NodeDB的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

这里请注意几个内容:

1. networks: 在 compose file V3中, 允许我们通过networks关键字定义一个基于 Docker0 网络的 subnet。 然后将我们的服务添加到这个subnet中。这样做的好处实现了服务之间的隔离,一旦我们不需要这组服务了,我们可以通过命令“docker-compose down” 卸载服务和对应的subnet,他不会对其他的服务造成影响。

 

2. build: 我们可以通过build命令来指定加载那个Dockerfile。 Dockerfile 提供给我们一种方式将通用的dockr image 定制化成为自己的image,这些定制化的步骤就可以以Dockerfile的方式记录下来。例如,我之前从docker 仓库里pull 下来一个image, 我们叫他baseImage,之后在此基础上进行了我的定制化生成myImage,如果需要在其他机器上面使用myImage,之前的做法吧myImage提交到私有仓库,在需要的时候pull下来,但是如果不同的地方需要不同的myImage (v1,v2,v3...),就有可能造成Image泛滥。现在我们通过Dockerfile的方式记录自己的定制过程,就会方便许多。

 

OK,啰嗦了一大堆。。。现在我们再来看看我们的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服务和实例(业务逻辑需求)。 

 

现在我们cd到docker-compose.yml文件所在的目录,输入命令 “docker-compose up”,命令执行完成后我们可以看到

1. 建立网络 composefrs_qrtSwarmComposeNet 

 

2. 通过 Dockerfile 生成 imge

 

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

 

 

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

 

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 的内容和之前差不多,就不在这里多说了。

 

注意:

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

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

 

例如 “docker run -itd --name=mybusybox --network=composefrs_qrtSwamComposeNet busybox /bin/sh”

 

之后我们便可以在nodeService上面能够查看到 composefrs_qrtSwamComposeNet 网络,此时再运行“docker-compose up”就OK了。这点还是有点坑的

 

结论

OK,通过在nodeDB和nodeService上运行两次 " docker-compose up ",命令,我们实现了在不同的hosts节点上运行containers,最终将他们以service的方式展现给外部用户。

 

PS,我还尝试过用docker stack deploy的方式进行部署,使用它最大的好处就是可以再一台机器上完成部署(传说中的一键部署),但是由于其中的种种限制(例如必须保证需要部署的service中使用的image必须提前存在于指定机器或者私有仓库,且不能使用Dockerfile临时编译; 不能指定conainer的IP,Mac 等等。。。),最终未能如愿,希望在 docker 之后的版本里能够改善吧。

 

posted @ 2017-03-20 13:48  TonyZhang24  阅读(20269)  评论(0编辑  收藏  举报