docker-compose进阶

笔者在前文《Docker Compose 简介》和《Dcoker Compose 原理》两篇文章中分别介绍了 docker compose 的基本概念以及实现原理。本文咱们将继续探索 docker compose,并经过 demo 介绍一些主要的用法。 
说明:本文的演示环境为 ubuntu 16.04。html

应用多个 compose 配置文件

docker-compose 命令默认使用的配置文件是当前目录中的 docker-compose.yml 文件,固然咱们能够经过 -f 选项指定一个其它名称的配置文件,好比:nginx

$ docker-compose -f docker-compose-dev.yml up

更酷的是咱们能够添加多个 -f 选项,docker-compose 会自动合并它们,固然也会根据前后顺序把一些重复的配置项覆盖掉。 下面咱们来演示一个常见的使用场景,先建立一个名称为 docker-compose-base.yml 的配置文件,其内容以下:web

version: '3'
services:
  web:
    build: .
  redis:
    image: "redis:latest"

而后再建立名称为 docker-compose-dev.yml 的配置文件:redis

version: '3'
services:
  web:
    ports:
     - "5000:5000"

下面的命令会同时应用这两个配置文件:docker

$ docker-compose -f docker-compose-base.yml -f docker-compose-dev.yml config

config 命令不会执行真正的操做,而是显示 docker-compose 程序解析到的配置文件内容:数据库

很显然,咱们指定的两个配置文件的内容被合并了。接下来咱们再来看看配置文件覆盖的状况。新建立一个名为 docker-compose-prod.yml 的配置文件,编辑其内容以下:json

复制代码
version: '3'
services:
  web:
    ports:
     - "80:5000"
  redis:
    image: "redis:alpine"
复制代码

而后执行下面的命令:ubuntu

$ docker-compose -f docker-compose-base.yml -f docker-compose-prod.yml config

此次 docker-compose-prod.yml 文件中的 image 设置覆盖了 docker-compose-base.yml 文件中的设置,而且映射的端口也改为了 80:5000。
就像 demo 中演示的那样,咱们能够经过屡次指定 -f 选项的方式配置不一样的环境,而且共用一份基础的配置文件。后端

其实 docker-compse 还默认还支持一种合并、覆盖配置文件的写法,就是使用约定的文件名称 docker-compose.yml 和 docker-compose.override.yml。下面咱们把 docker-compose-base.yml 文件更名为 docker-compose.yml,把 docker-compose-prod.yml 文件更名为 docker-compose.override.yml,并直接执行不带 -f 选项的命令:安全

$ docker-compose config

结果和前面是同样的,docker-compose 自动合并了配置文件 docker-compose.yml 和 docker-compose.override.yml。这种方式虽然省去了指定 -f 选项的麻烦但其缺点也是很明显的,就是没法指定更多不一样的应用场景。

使用 network

Docker 提供的 network 功能可以对容器进行网络上的隔离,下面的 demo 中咱们建立三个 service 和两个虚拟网络(注意,该 demo 主要是演示 network 的用法,因此笔者并无配置 proxy service 中的 nginx):

复制代码
version: '3'
services:
  proxy:
    image: nginx
    ports:
      - "80:80"
    networks:
      - frantnet
  webapp:
    build: .
    networks:
      - frantnet
      - endnet
  redis:
    image: redis
    networks:
      - endnet
networks:
  frantnet:
  endnet:
复制代码

其中的 proxy 和 webapp 链接到网络 frantnet 上,webapp 和 redis 链接在了 endnet 上(请使用《Docker Compose 简介》一文中介绍的 web 应用和 Dockerfile 来建立 webapp service)。请使用下面的命令来启动应用:

$ docker-compose -p testnet -f docker-compose-net.yml up -d

从上图咱们能够看到该命令一共建立了两个 network 和 三个容器。而后咱们检查一下这三个容器的网络链接状态。先从 testnet_webapp_1 中 ping 另外的两个容器:

由于 webapp 服务同时链接到了 frantnet 和 endnet 两个网络中,因此它能够同时链接这两个网络中的其它容器(proxy 和 redis)。接下来再看看容器 proxy 和 redis 是否能够直接连通,咱们从容器 testnet_redis_1 中 ping proxy(注意,执行这个操做前须要在容器  testnet_redis_1 中经过 apt-get update && apt-get install iputils-ping 命令安装 ping 命令):

没法从容器 testnet_redis_1 中 ping 通 proxy 容器,这也就说明咱们经过不一样的虚拟网络实现了容器网络之间的隔离,从而在最大程度上去保护后端网络的安全。

按顺序启动容器

默认状况下 compose 启动容器的顺序是不肯定的,可是有些场景下咱们但愿可以控制容器的启动顺序,好比应该让运行数据库的程序先启动。咱们能够经过 depends_on 来解决有依赖关系的容器的启动顺序问题,看下面的 demo:

复制代码
version: '3'
services:
  proxy:
    image: nginx
    ports:
      - "80:80"
    depends_on:
      - webapp
      - redis
  webapp:
    build: .
    depends_on:
      - redis
  redis:
    image: redis
复制代码

启动应用:

不管咱们执行多少次这样的启动操做,这三个容器的启动顺序都是不变的。若是不该用 depends_on,每次执行 up 命令容器的启动顺序可能都是不同的。
须要注意的是 depends_on 只是解决了控制容器启动顺序的问题,若是一个容器的启动时间很是长,后面的容器并不会等待它完成启动。若是要解决这类问题(等待容器完成启动并开始提供服务),须要使用 wait-for-it 等工具。

配置数据卷(volume)

数据卷是处理容器中的持久化数据的主要方式,在 compose 中咱们能够经过两种方式来指定数据卷:

  • 使用命名的数据卷
  • 直接指定主机上的路径来建立数据卷

下面的 demo 演示了这两种数据卷的配置方式:

复制代码
version: "3.2"
services:
  web:
    image: nginx:alpine
    volumes:
      - type: volume
        source: mydata
        target: /data
      - type: bind
        source: ./nginx/logs
        target: /var/log/nginx
  jenkins:
    image: jenkins/jenkins:lts
    volumes:
      - jenkins_home:/var/jenkins_home
      - mydata:/data
volumes:
  mydata:
  jenkins_home:
复制代码

在这个例子中咱们一共建立了三个数据卷,分别是两个命名的数据卷 jenkins_home 和 mydata:

其中的 jenkins_home 数据卷是给 jenkins 保存数据的。若是要在多个容器之间共享数据卷,就必须在顶级的 volumes 节点中定义这个数据卷,好比 mydata 数据卷,它被 web 和 jenkins service 共享了。好比咱们在 web service 中的 mydata 数据卷中建立一个名为 hello 的文件,该文件会同时出如今 jenkins service 中:

咱们还建立了一个 bind 类型的 volume 在当前目录下的 nginx/logs 目录下保存 nginx 的日志:

配置日志驱动

咱们还能够经过 logging 节点为 service 指定日志驱动及其相关的选项:

复制代码
version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
        max-file: "10"
  redis:
    image: "redis:latest"
复制代码

上面的代码指定日志驱动为 json-file,存储日志的最大文件 size 为 200k,最多存储 10 这样大的文件。

在 compose file 文件中应用模板

从版本 3.4 开始,能够在 compose file 文件中使用 extension fields,其实咱们能够简单的把它理解为能够重用的代码模板。模板的定义必须以 x- 开头,而后以 & 开头的字符串为模板命名,以后就能够以 * 加上模板的名称引用模板:

复制代码
version: '3.4'
x-logging:
  &default-logging
  driver: json-file
  options:
    max-size: "200k"
    max-file: "10"

services:
  web:
    build: .
    ports:
     - "5000:5000"
    logging: *default-logging
  redis:
    image: "redis:latest"
    logging: *default-logging
复制代码

运行下面的命令看看模板替换的状况:

$ docker-compose -p template -f docker-compose-template.yml config

上图显示全部对模板的引用都被替换成了模板的内容。

总结

Docker compose 是一件强有力的效率工具,本文只是介绍了一些常见的用法。若是你还想掌握更多内容,请参考 compose file 的官方文档。

参考:
Compose file version 3 reference
Docker Compose from development to production
Networking in Compose
Control startup order in Compose
3 Docker Compose features for improving team development workflow

做者: sparkdev
本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利。
相关文章
相关标签/搜索