Docker 进阶篇03 — Compose

前言

本章,您将学习 Docker Compose 的相关内容。

Docker Compose:Docker 公司官方的开源项目之一,负责并实现对 Docker 容器集群的快速编排,其作用类似于现实生活中管理项目的项目经理。

您可以使用 Docker Compose 管理多个容器实例,让它们组成一个大型应用或项目。在使用 Docker Compose 之前,您需要定义一个 YAML 格式的配置文件,其内容为 容器之间的调用关系,后续使用单个命令就能快速启动或关闭这些容器实例。

Q:什么是容器编排?

「对多个容器实例进行部署、管理、监控的一种自动化流程技术」

由这门技术衍生出相关的容器编排工具,常见的有:

  • Kubermetes - 对于那些大型的复杂项目,K8S 是一个不错的选择
  • Docker Compose 或 Docker Swarm - 对于单个主机的、简单的、小型的开发环境而言,它是一个不错的选择
  • Mesos
提示
请不要将 Dockerfile 与 Docker Compose 混淆!**Dockerfile** 用来构建 Docker 镜像的文本文件,其由一条又一条构建镜像所需的指令和参数构成。**Docker Compose** - 用来管理容器实例的工具,需要先定义 YAML 配置文件才可以被使用。一个服务于镜像,一个服务于容器实例。

了解 YAML 格式的语法规范

语法规范有:

  • 在规范写法上,开头行以 "---" 开头,结尾行以 "…" 结尾。有时,开头行的 "---" 与结尾行的 "..." 可以被省略,但推荐不要省略它们。
  • "#" 开头的代表注释行
  • 缩进不能用 TAB 键(因文本编辑器的不同,一个 TAB 等于两个或四个空格,所以并不是说完全不能使用 TAB 键);
  • 相同级别的缩进必须一样或者说对齐;
  • 文本内容严格区分大小写,键值对(key/value)也是一样的要求;
  • 文件的扩展名为 yml 或者 yaml;
  • 键值对用 ":" 表示,在":"后面需要加一个空格;
  • 数组(列表)用 "-" 表示,也需要在 "-" 后面加一个空格;
  • 单引号不转义特殊字符,即只会输出字符串本身,例如 text: 'line1 \n line2' 这样的书写并不会换行,双引号会对一些特殊的字符进行转义,例如 text: "line1 \n line2" 会换行

YAML 数据类型

对象 - 也被称为字典(Dictionary)或映射(mapping),它是键值对的集合
数组 - 也被称为列表(list),一组按照次序排列的值
纯量(scalars) - 单个且不可再分的值

不同的数据类型之间可以相互嵌套混用。

对象的写法:

---
# 第一种写法
key1: value1
key2: value2
key3: value3

# 第二种写法
{key1: "value1",key2: "value2",key3: "value3"}
...

数组的写法:

---
# 第一种写法
- value1
- value2
- value3

# 第二种写法
[value1,value2,value3]
...

YAML 在线语法检测工具 —— https://onlineyamltools.com/validate-yaml

Docker Compose

安装 Docker Compose

当初使用官方的 Docker 存储库已经安装了 Docker Compose(dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin)。

Shell > docker compose version
Docker Compose version v2.27.0

Docker Compose 中的概念

配置文件 - 通常为 compose.yaml 或 docker-compose.yaml,对配置文件的名称没有特别的要求
服务(service) - 指一个又一个的容器实例
项目(project) - 由一组关联的容器实例组成的完整业务单元,需要在 YAML 配置文件中定义

Docker Compose 使用步骤

  1. 首先通过 Dockerfile 构建出实际需要的镜像,请参阅前面的内容
  2. 编写 YAML 配置文件,定义所需要的容器实例以及它们的关联关系
  3. 使用 docker compose up 命令创建并启动所有的容器实例

docker compose 命令

该命令的用法为 —— docker compose [option] COMMAND

COMMAND 可以是:

  • build - 构建或重新构建 service
  • config - 检查 YAML 配置文件的语法
  • cp - 在本地文件系统与 service 之间复制文件或目录
  • create - 针对 servcie 创建容器
  • down - 停止并移除由 docker compose up 命令创建的容器、网络和数据卷,相当于刷新。
  • events - 从容器中接受实时事件
  • exec - 进入到容器实例的内部
  • images - 列出创建容器所使用的镜像
  • kill - 用于停止正在运行中的 service 容器
  • logs - 查看 service 容器的日志输出
  • ls - 列出正在运行的 compose 项目
  • pause - 暂停运行中的 service 容器
  • port - 显示某个容器端口所映射的公共端口
  • ps - 列出所有被管理容器实例的状态
  • pull - 拉取 service 所依赖的镜像
  • push - 推送 service 所依赖的镜像
  • restart - 重启项目中的 service
  • rm - 删除所有停止状态的 service 容器,默认情况下,不会删除容器挂载的数据卷。
  • run - 在指定的 service 上执行一个命令
  • scale - 扩大或缩小 service 容器实例的数量
  • start - 启动管理的 service 容器
  • stats - 查看 service 容器占用资源的情况
  • stop - 停止项目中的 service
  • top - 显示正在运行的进程
  • up - 创建并启动 service 容器
  • version - 查看版本

针对单个 COMMAND,您也可以使用 docker compose COMMAND --help 查阅更多的帮助信息,比如 —— docker compose up --help

Compose 书写规范

前面提到,我们需要定义一个 YAML 格式的配置文件,这只是格式上的要求,但对于具体文件内容而言,需要使用各种各样的 元素(有些中文资料中也称 关键字字段参数属性)。

名称顶层元素(Name top-level element)

元素有:

  • name - 定义项目的名称

服务顶层元素(Services top-level elements)

常见元素有:

  • services - 定义所有的 service 信息,其下一级的 key 即表示第一个 service 的名称。

  • attach - 是否收集 services 的日志,默认值为 true

  • cgroup - 指定要加入哪一个 cgroup 命名空间,值可以是:

    • host
    • private
  • command - 使用该元素的值来覆盖镜像中的默认命令(例如 Dockerfile 当中的 CMD 指令)

  • container_name - 使用自定义的容器实例名称,其值为字符串。请注意!该字符串需要唯一

  • depends_on - 指定 servcie 之间的启动顺序与依赖关系

  • dns - 容器实例要使用的自定义 DNS,可以是单个值,也可以是列表值,例如

    dns: 8.8.8.8
    
    dns:
      - 8.8.8.8
      - 9.9.9.9
  • env_file - 指定环境变量文件并向容器传递变量。变量文件的说明:

    • 文件名称以 .env 后缀作为文件标识
    • 变量文件应该为相对路径
    • 以 # 开头的表示注释行
    • 格式为 VAR=value,变量名称需要大写
    • 双引号值支持常见的特殊字符转义,包括\t\r\n
  • environment - 指定环境变量。当为容器同时使用变量文件与 environment 元素时,enviriment 元素优先生效。支持两种语法:

    ---
    # 映射语法
    environment:
      RACK_ENV: development
      SHOW: "true"
      USER_INPUT:
    
    # 数组语法
    environment:
        - RACK_ENV=development
        - SHOW=true
        - USER_INPUT
    ...
  • group_add - 指定 service 运行的容器应该加入的一个或多个预先存在的组,比如:

    services:
        myservice:
        image: myimage
        group_add:
          - mail

    该元素仅针对 GNU/Linux 生效,需要注意的是该组必须预先存在于 docker 容器上。

  • hostname - 设置容器的主机名

  • image - 指定镜像

  • init - 是否在容器内运行一个 init 进程(PID 为1),该进程可以转发信号并获取子进程的状态。

  • labels - 为 service 设置 docker 容器的元数据。书写形式可以是数组或映射,例如:

    # 数组
    labels:
      - "com.example.description=Accounting webapp"
      - "com.example.department=Finance"
      - "com.example.label-with-empty-value"
    
    # 映射
    labels:
      com.example.description: "Accounting webapp"
      com.example.department: "Finance"
      com.example.label-with-empty-value: ""
  • logging - 配置 service 的日志。例如:

    services:
      myweb:
        image: nginx:latest
        logging:
          driver: json-file
          options:
            max-size: "20m"
            max-file: "3"

    driver 可以是 json-file、syslog、journald 等,不同的 driver 可以使用不同的 options,参阅这里 —— https://docs.docker.com/config/containers/logging/configure/#configure-the-default-logging-driver

  • network_mode - 设置 service 容器的网络模式,关于 docker 网络,请参阅上一篇文章

  • networks- 定义 service 容器添加到的网络,网络部分参阅下面的 网络顶层元素(Networks top-level elements)

  • aliases - 为 service 设置别名,您可以为同一个 service 设置多个别名,但是请注意!别名仅在同一个网络中生效,另外,不能为不同的 service 设置相同的别名。

  • ports - 建立宿主机与容器实例之间的端口映射关系,与 docker run 命令中的 -p 选项相同(冒号左边为宿主机的端口或端口范围,冒号右边为容器实例的端口或端口范围)。示例写法:

    ports:
      - "3000"  # 暴露容器实例的 3000 端口
      - "3000-3005"  # 暴露容器实例的 3000 到 3005 端口
      - "8000:8000"
      - "9090-9091:8080-8081"
      - "49100:22"
      - "8000-9000:80"
      - "127.0.0.1:8001:8001"
      - "127.0.0.1:5000-5010:5000-5010"
      - "6060:6060/udp"
  • privileged - 与 docker run 中的 --privileged=true 一样,表示容器内的 root 是真正意义上 root 用户。

  • read_only - 设置容器数据卷的权限,关于数据卷的基础内容,请参阅前面的文章

  • restart - 设置容器实例的重启策略,与 docker run 中的 --restart 选项一样,其值可以是 no、always、on-failure[:max-retries]、unless-stopped

    restart: "no"
    restart: always
    restart: on-failure
    restart: on-failure:3
    restart: unless-stopped
  • sysctls - 与 docker run 中的 --sysctl 选项一样,用来给容器实例设置 Linux 内核的参数。比如您要在容器实例中开启 ipv4 的转发功能。

    services:
      my_service:
        image: my_image
        sysctls:
          - net.ipv4.ip_forward=1
  • volumes - 设置数据卷(数据卷:一种将容器内的数据持久化备份到宿主机的方式,也就是目录映射或文件映射)。

    services:
      backend:
        image: example/backend
        volumes:
          - type: bind
            source: /var/run/postgres/postgres.sock
            target: /var/run/postgres/postgres.sock
          - type: bind
            source: /host/dir/
            target: /container/dir/
            read_only: false
  • volumes_from - 继承来自于其他容器的数据卷规则,也就是 docker run 当中的 --volumes-from 选项

网络顶层元素(Networks top-level elements)

网络能够使 service 相互之间进行通信。默认情况下,compose 会为您的应用程序设置一个单独的网络,service 的每个容器都会加入该默认网络,加入之后,各个容器既可以通过网络进行相互访问,也可以通过 service 的名称进行发现。

基本示例如下所示,在这里我们定义了 mynetwork 这个网络,并且 service1service2 都加入或连接到了该网络中。

---
services:
  service1:
    image: service1image
    networks:
      - mynetwork

  service2:
    image: service2image
    networks:
      - mynetwork

networks:
  mynetwork:
...

高级示例如下所示,我们还可以定义网络相关的 driver 、子网等。

---
services:
  service1:
    image: service1image
    networks:
      mynetwork:
        aliases:
          - alias1
          - alias2

networks:
  mynetwork:
    driver: customdriver
    ipam:
      config:
        - subnet: 172.16.0.0/24
...

在这个例子中,service1 使用了 mynetwork 这个网络,且该网络在该 service 上有两个别名。

相关的元素(属性):

  • driver - 值可以是 bridge、host、none 等
  • driver_opts - driver 相关的选项
  • enable_ipv6 - 是否开启 IPv6
  • ipam - 自定义网络配置管理,这是一个由具有多个可选属性的键值对组成。
    • driver
    • config - 配置元素列表
      • subnet - 定义子网(网段)
      • ip_range
      • gateway - IPv4 或 IPv6 的网关
      • aux_addresses - 主机名与 IP 地址的映射关系
  • options
---
networks:
  mynet1:
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
          ip_range: 172.28.5.0/24
          gateway: 172.28.5.254
          aux_addresses:
            host1: 172.28.1.5
            host2: 172.28.1.6
            host3: 172.28.1.7
      options:
        foo: bar
        baz: "0"
...

数据卷顶层元素(Volumes top-level elements)

示例如下所示:

---
services:
  webapp:
    image: my-webapp:latest
    volumes:
      - type: volume
        source: my_data_volume
        target: /app/data

volumes:
  my_data_volume:
...

数据类型为 volume 而不是 bind ,Docker Compose 会自动管理管理名称为 my_data_volume 的卷。

相关的元素(属性):

  • driver - 指定应该使用哪个数据卷驱动
  • driver_opts - 相关数据卷驱动的选项

配置顶层元素(Configs top-level elements)

我们可以为相应的 service 引入外部的配置文件

相关元素(属性):

  • file - 指定配置文件,必须为相对路径
  • external - 表示这个配置文件是外部管理的,它不由 Docker Compose 创建、管理或删除

通过相对路径的方式查找配置文件:

---
services:
  myhttpd:
    image: httpd:latest
    configs:
      - http_config

configs:
  http_config:
    file: ./httpd.conf
...

机密底层元素(Secrets top-level elements)

这部分主要定义一些安全相关的内容,比如用户的凭证(密码和令牌等)。

---
services:
  myservice:
    image: myimage
    secrets:
      - my_secret

secrets:
  my_secret:
    file: ./my_secret.txt
...
Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇