ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Docker入门与实战——Docker Compose(多容器应用管理)

Docker入门与实战——Docker Compose(多容器应用管理)

Docker Compose(多容器应用管理)

    • 1、安装与卸载
      • 1.1、pip安装
      • 1.2、二进制包
      • 1.3、卸载
    • 2、Compose模板文件
      • 2.1、build
      • 2.2、cap_add,cap_drop
      • 2.3、cgroup_parent
      • 2.4、command
      • 2.5、configs
      • 2.6、container_name
      • 2.7、credential_spec
      • 2.8、depends_on
      • 2.9、deploy
      • 2.10、devices
      • 2.11、dns
      • 2.12、dns_search
      • 2.13、entrypoint
      • 2.14、env_file
      • 2.15、environment
      • 2.16、expose
      • 2.17、extends
      • 2.18、external_links
      • 2.19、extra_hosts
      • 2.20、healthcheck
      • 2.21、image
      • 2.22、init
      • 2.23、isolation
      • 2.24、labels
      • 2.25、25.links
      • 2.26、logging
      • 2.27、network_mode
      • 2.28、networks
      • 2.29、pid
      • 2.30、ports
      • 2.31、profile
      • 2.32、restart
      • 2.33、secrets
      • 2.34、security_opt
      • 2.35、stop_grace_period
      • 2.36、stop_signal
      • 2.37、sysctls
      • 2.38、tmpfs
      • 2.39、ulimits
      • 2.40、userns_mode
      • 2.41、volumes
      • 2.42、其他指令
      • 2.43、读取环境变量
      • 2.44、扩展特性
    • 3、Compose命令说明
      • 3.1、命令对象与格式
      • 3.2、命令选项
      • 3.3、命令使用说明
        • 3.3.1、build
        • 3.3.2、config
        • 3.3.3、down
        • 3.3.4、events
        • 3.3.5、exec
        • 3.3.6、help
        • 3.3.7、images
        • 3.3.8、kill
        • 3.3.9、logs
        • 3.3.10、pause
        • 3.3.11、port
        • 3.3.12、ps
        • 3.3.13、pull
        • 3.3.14、push
        • 3.3.15、restart
        • 3.3.16、rm
        • 3.3.17、run
        • 3.3.18、scale
        • 3.3.19、start
        • 3.3.20、stop
        • 3.3.21、top
        • 3.3.22、unpause
        • 3.3.23、up
        • 3.3.24、version
    • 4、Compose环境变量
      • 4.1、Compose中定义的环境变量
      • 4.2、在Compose文件中使用环境变量
      • 4.3、Compose应用案例一:Web负载均衡
        • 4.3.1、web子目录
        • 4.3.2、haproxy目录
        • 4.3.3、docker-compose.yml
        • 4.3.4、运行compose项目
      • 4.4、Compose应用案例二:大数据Spark集群
        • 4.4.1、准备工作
        • 4.4.2、启动集群
        • 4.4.3、执行应用

在微服务架构下,一个服务通常由多个应用程序组成,因此对多应用程序的管理成了一个普遍需求。在Docker应用场景中,用户需要灵活地对各种容器资源进行定义和管理。

Compose是Docker官方的多应用程序管理工具,其重要性不言而喻。使用Compose,用户简单编写一个模板文件,就可以轻松管理由多个应用程序组成的容器集群。

本章将深入介绍Compose项目,包括如何安装、卸载Compose,如何编写模板文件以及如何使用命令和环境变量,并结合具体案例展示如何使用Compose来管理多个应用容器。

Compose项目是Docker官方的开源项目,旨在创建和管理基于Docker容器的多应用服务,定位为“定义和运行多个Docker容器的应用”​,其前身是开源项目Fig。从功能上看,它类似于OpenStack中的Heat。Compose的源代码目前托管在docker/compose上,这是一个由社区支持的项目。

本书第一部分已经介绍了使用Dockerfile可以很方便地定义单独的应用容器,但在实际工作中,经常需要多个容器协同工作来完成某项任务。例如,要实现一个Web项目,需要用到Web服务容器、数据库服务容器,甚至还要用到前端的负载均衡容器等。

Compose恰好能够满足这种需求。用户可以使用一个单独的docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器,形成一个服务栈。

Compose中有几个重要的概念:

  • 任务(Task):一个容器被称为一个任务。任务拥有独一无二的ID,在同一个服务中的多个任务序号依次递增。
  • 服务(Service):某个相同应用镜像的容器副本集合,一个服务可以横向扩展为多个容器实例。
  • 服务栈(Stack):由多个服务组成,相互配合完成特定业务,如Web应用服务、数据库服务共同构成Web服务栈。通常一个docker-compose.yml模板文件定义了一个服务栈。

Compose的默认管理对象是服务栈,通过子命令对栈中的多个服务进行便捷的生命周期管理。

Compose项目通过调用Docker服务提供的API来管理容器。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose进行编排管理。

1、安装与卸载

Compose是由Python编写的项目,因此在使用之前,需要在系统中安装Python环境。此外,为了使Compose正常运行,系统还需要安装Docker引擎。关于Docker引擎的安装方法,请参考本书之前的章节。

对于Linux环境,大部分系统的自带软件仓库中都包含了Compose。对于MacOS或Windows系统,DockerDesktop中已经包含了Compose,通常用户直接安装Compose即可,无须进行额外操作。

如果要单独安装Compose,可以选择使用Python的pip工具进行安装,也可以直接下载已经编译好的二进制安装包。前者会安装相关依赖包,适合本地环境下的安装使用;后者则对系统环境的影响较小,更适合在云计算场景中使用。

1.1、pip安装

这种方式是将Compose当作一个Python应用从PyPI源中安装。执行安装命令:

安装成功后,可以查看docker-compose命令的基本用法:

1.2、二进制包

官方定义、编译好的二进制包可以在https://github.com/docker/compose/releases页面找到。

下载这些二进制文件后,直接将其放到执行路径下,并添加执行权限即可。例如,通过如下命令,下载指定版本${VERSION}的Compose文件,并添加可执行权限:

可以使用docker-compose version命令来查看版本信息,以测试是否安装成功:

1.3、卸载

如果是通过二进制包方式安装的,那么删除二进制文件即可,命令如下:

如果是通过Python的pip工具安装的,则可以执行如下命令删除:

2、Compose模板文件

模板文件是使用Compose的核心,涉及的指令关键字也比较多。但读者无须过于担心,大部分指令与docker [container] create | run相关参数的含义类似。

默认模板文件的名称为docker-compose.yml,格式为YAML,目前最新的版本为V3。

Compose已经不支持最早的V1版本的模板文件。它的文件结构十分简单,每个顶级元素为服务名称,次级元素为服务容器的配置信息,例如:

后来的V2和V3版本扩展了Compose的语法,同时尽量保持与旧版本兼容,除了可以声明网络、存储、配置和秘密信息外,添加了版本信息,需要将所有服务放到services根下面。目前,基于V2和V3的语法,Compose还推出了新的模板规范。

新的规范中支持使用name来命名整个项目,每个项目中可以包括多个服务。例如,将上面V1版本的示例改写为新的规范,并启用资源限制,内容如下:


注意每个服务都必须通过image指令指定镜像或build指令(需要Dockerfile)等来自动构建生成镜像。

如果使用build指令,在Dockerfile中设置的选项(例如CMD、EXPOSE、VOLUME、ENV等)将会自动被获取,无须在docker-compose.yml中再次设置。

下面以目前最流行的V3版本为例,分别介绍模板文件中各个服务配置指令的用法。

2.1、build

build指令用于指定Dockerfile所在文件夹的路径(可以是绝对路径,或者相对docker-compose.yml文件的路径)​。Compose将会利用它自动构建应用镜像,然后使用这个镜像。例如:

build指令还可以指定创建镜像的上下文、Dockerfile路径、标签、shm大小、参数、缓存来源和目标等。例如:

2.2、cap_add,cap_drop

cap_add和cap_drop指令用于指定容器的内核能力(capacity)分配,在Swarm模式下会被忽略。例如,让容器拥有所有能力,可以指定为:

去掉NET_ADMIN能力,可以指定为:

2.3、cgroup_parent

cgroup_parent指令用于指定父cgroup组,意味着将继承该组的资源限制,目前不支持在Swarm模式中使用。例如,创建一个cgroup组,名称为cgroups_1:

2.4、command

command是覆盖容器启动后默认执行的命令,可以为字符串格式或JSON数组格式。例如:

或者:

2.5、configs

在Docker Swarm模式下,可以通过configs指令来管理和访问非敏感的配置信息,支持从文件读取或外部读取。例如:

2.6、container_name

container_name指令用于指定容器名称。默认将会使用“项目名称_服务名称_序号”这样的格式。目前不支持在Swarm模式中使用。例如:

需要注意,指定容器名称后,该服务将无法进行扩展,因为Docker不允许多个容器实例重名。

2.7、credential_spec

credential_spec指令用于配置托管服务账户的凭据规范,仅用于使用Windows容器的服务。credential_spec必须以file://<file-name>或registry://<value-name>格式提供。

在使用file:时,引用文件必须存在于Docker数据目录中的CredentialSpecs子目录中。例如:

使用registry:时,从主机上的Windows注册表项HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs中读取引用文件。

2.8、depends_on

depends_on指令用于指定多个服务之间的依赖关系。启动时,会先启动被依赖服务。例如可以指定依赖于db服务:

2.9、deploy

deploy指令用于指定部署和运行时的容器相关配置。该指令只在Swarm模式下生效,且只支持docker stackdeploy命令部署。例如:

deploy命令中包括endpoint_mode、labels、mode、placement、replicas、resources、restart_policy、update_config等配置项。

  • (1)endpoint_mode
    endpoint_mode指定服务端点模式,包括两种类型:

    • vip:Swarm分配一个前端的虚拟地址,客户端通过给定地址访问服务,无须关心后端的应用容器个数。
    • dnsrr:Swarm分配一个域名给服务,用户访问域名时会按照轮流顺序返回容器地址。例如:
  • (2)labels
    labels指定服务的标签。注意,标签信息不会影响到服务内的容器。例如:

  • (3)mode
    mode定义容器副本模式,可以为:

    • global:每个Swarm节点上只有一个该应用容器。
    • replicated:整个集群中存在指定份数的应用容器副本,为默认值。

    例如,指定集群中Web应用保持3个副本:

  • (4)placement
    placement定义容器放置的限制(constraint)和配置(preference):限制可以指定只有符合要求的节点才能运行该应用容器;配置可以指定容器的分配策略。

    例如,指定集群中Web应用容器只存在于高安全的节点上,并且在带有zone标签的节点上均匀分配:

  • (5)replicas
    当容器副本模式为默认的replicated时,replicas用于指定副本的个数。

  • (6)resources
    resources用于指定使用资源的限制,包括CPU、内存资源等。例如,指定应用使用的CPU份额为10%~25%,内存为200~500MB:

  • (7)restart_policy
    restart_policy用于指定容器重启的策略。例如,指定重启策略为失败时重启,等待2s,重启最多尝试3次,检测状态的等待时间为10s:

  • (8)update_config
    有些情况下需要对容器内容进行更新,可以使用update_config设置升级参数,包括每次升级多少个容器(parallelism)、升级的延迟(delay)、升级失败后的行动(failure_action)、检测升级后状态的等待时间(monitor)、升级后容忍的最大失败比例(max_failure_ratio)、升级顺序(order)等。例如,指定每次更新两个容器,更新等待时间为10s,先停止旧容器再升级:

2.10、devices

devices用于指定设备映射关系,不支持Swarm模式。例如:

2.11、dns

dns用于自定义DNS服务器。可以是一个值,也可以是一个列表,例如:

2.12、dns_search

dns_search用于配置DNS搜索域,可以是一个值,也可以是一个列表:

2.13、entrypoint

entrypoint用于覆盖容器中默认的入口命令。注意,这样也会取消镜像中指定的入口命令和默认启动命令。例如,覆盖为新的入口命令:

2.14、env_file

env_file用于从文件中获取环境变量,可以为单独的文件路径或列表。如果通过docker-compose-f FILE方式来指定Compose模板文件,则env_file中变量的路径会基于模板文件路径。如果变量名称与environment指令冲突,则按照惯例,以后者为准:

环境变量文件中每一行必须符合格式,支持以#开头的注释行:

2.15、environment

environment用于设置环境变量,可以使用数组或字典两种格式。只给定名称的变量会自动获取运行于Compose主机上对应变量的值,可以用来防止泄露不必要的数据。例如:

或者:

注意,如果变量名称或者值中用到true|false、yes|no等表达布尔含义的词汇,最好放到引号里,避免YAML自动解析某些内容为对应的布尔语义。

网址http://yaml.org/type/bool.html中给出了这些特定
词汇,包括:

2.16、expose

expose用于暴露端口,但不映射到宿主机,只被连接的服务访问,仅可以指定内部端口为参数:

2.17、extends

extends用于基于其他模板文件进行扩展,仅支持V2版本。例如,已经有了一个webapp服务,定义一个基础模板文件为common.yml:

再编写一个新的development.yml文件,使用common.yml中的webapp服务进行扩展:

后者会自动继承common.yml中的webapp服务及环境变量定义。

使用extends时需要注意: - 要避免出现循环依赖,例如A依赖B,B依赖C,C反过来依赖A的情况。 - extends不会继承links和volumes_from中定义的容器和数据卷资源。 一般地,推荐在基础模板中只定义一些可以共享的镜像和环境变量,在扩展模板中具体指定应用变量、链接、数据卷等信息。

2.18、external_links

external_links用于链接到docker-compose.yml外部的容器,甚至并非Compose管理的外部容器。参数格式与links类似:

2.19、extra_hosts

extra_hosts类似Docker中的–add-host参数,指定额外的host名称映射信息。例如:

上述指令会在启动后的服务容器中的/etc/hosts文件中添加如下两条条目:

2.20、healthcheck

healthcheck用于指定检测应用健康状态的机制,包括检测方法(test)、间隔(interval)、超时(timeout)、重试次数(retries)、启动等待时间(start_period)等。

例如,指定检测方法为访问8080端口,间隔为30s,超时为15s,重试3次,启动后等待30s再做检查:

2.21、image

image用于指定镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取这个镜像。例如:

2.22、init

init用于在容器内运行一个init进程,以转发信号和回收进程。例如:

2.23、isolation

isolation用于配置容器隔离的机制,包括default、process和hyperv。

2.24、labels

labels用于为容器添加Docker元数据(metadata)信息。例如,可以为容器添加辅助说明信息:


2.25、25.links

links用于链接到其他服务中的容器。使用“服务名称”​(同时作为别名)或“服务名称:服务别名”(SERVICE:ALIAS)格式均可:

使用的别名将会自动在服务容器中的/etc/hosts里创建。例如:

被链接容器中相应的环境变量也将被创建。

注意links命令属于旧的用法,可能在后续版本中被移除。

2.26、logging

logging用于进行与日志相关的配置,包括一系列子配置:

  • (1)logging.driver
    类似Docker中的–log-driver参数,logging.driver用于指定日志驱动类型。目前支持三种日志驱动类型:
  • (2)logging.options
    logging.options为日志驱动的相关参数。例如:

    或

2.27、network_mode

network_mode用于设置网络模式,使用与docker client的–net参数一样的值:

2.28、networks

networks表示所加入的网络。需要在顶级的networks字段中定义具体的网络信息。例如,指定Web服务的网络为web_net,并添加服务在网络中的别名为web_app:

2.29、pid

pid用于设置与主机系统共享进程命名空间。打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程ID来相互访问和操作:

2.30、ports

ports用于暴露端口信息。可以使用“宿主:容器”(HOST:CONTAINER)格式,或者仅仅指定容器的端口(宿主将会随机选择端口)​:

注意当使用HOST:CONTAINER格式来映射端口时,如果使用的容器端口小于60并且没放到引号里,可能会得到错误结果,因为YAML会自动解析xx:yy这种数字格式为六十进制。为避免出现这种问题,建议对数字串都采用引号包括起来的字符串格式。

2.31、profile

profile可用于筛选出一组服务,从Docker Compose1.28.0开始支持。它允许开发者在docker-compose.yml文件中为每个服务定义一个或多个profile,从而实现在不同的环境或情况下启动不同的服务集合。

定义服务的profile之后,用户可以使用–profile选项来指定要应用哪些profile。例如,下面的模板文件中定义了多个服务,frontend服务属于prod profile,phpmyadmin服务属于test profile,backend和db服务不属于任何profile,意味着始终启动:

可以通过以下命令来启动带有test profile和不带任何profile的服务:

同样地,用户也可以使用–profile选项来指定在执行docker-compose down命令时要停止哪些profile中的服务。

2.32、restart

restart用于指定重启策略,可以为no(不重启)​、always(总是)​、on-failure(失败时)​、unless-stopped(除非停止)​。注意,在Swarm模式下要使用restart_policy。在生产环境中推荐配置为always或者unless-stopped。例如:

2.33、secrets

secrets用于配置应用的秘密数据,可以指定秘密来源、挂载后名称、权限等。例如:

2.34、security_opt

security_opt用于指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等)​。例如,配置标签的用户名和角色名:

2.35、stop_grace_period

stop_grace_period用于指定应用停止时,容器的优雅停止期限。过期后则通过SIGKILL强制退出,默认值为10s。

2.36、stop_signal

stop_signal用于指定停止容器的信号,默认值为SIGTERM。

2.37、sysctls

sysctls用于配置容器内的内核参数,Swarm模式中不支持。例如,指定连接数为4096和开启TCP的syncookies:

2.38、tmpfs

tmpfs用于挂载若干临时文件系统到容器内。例如:

2.39、ulimits

ulimits用于指定容器的ulimits限制值。例如,指定最大进程数为65535,指定文件句柄数为20000(软限制,应用时可以随时修改,不能超过硬限制)和40000(系统硬限制,只有root用户才可以提高该值)​:

2.40、userns_mode

userns_mode用于指定用户命名空间模式,Swarm模式中不支持。例如,使用主机上的用户命名空间:

2.41、volumes

volumes用于设置数据卷所挂载的路径,可以设置宿主机路径(HOST:CONTAINER)或加上访问模式(HOST:CONTAINER:ro)。volumes支持driver、driver_opts、external、labels、name等子配置。该指令中的路径支持相对路径。例如:

或者可以使用更详细的语法格式:

2.42、其他指令

此外,还有domainname、hostname、ipc、mac_address、privileged、read_only、shm_size、stdin_open、tty、user、working_dir等指令,指令功能基本与docker-run中对应参数的功能一致。例如,指定容器中的工作目录:


或者在指定容器中搜索域名、主机名、mac地址等:

使用以下指令,允许在容器中运行一些特权命令:

2.43、读取环境变量

从1.5.0版本开始,Compose模板文件支持动态读取主机的系统环境变量。例如,下面的Compose文件将从运行它的环境中读取变量${MONGO_VERSION}的值(不指定时则采用默认值3.2)​,并写入执行的指令中:

如果直接执行docker-compose up,则会启动一个mongo:6.2镜像的容器;如果执行MONGO_VERSION=6.0 docker-compose up,则会启动一个mongo:6.0镜像的容器。

2.44、扩展特性

从3.4版本开始,Compose还支持用户自定义的扩展字段。利用YAML语法里的锚点引用功能来引用自定义字段内容。例如:

3、Compose命令说明

3.1、命令对象与格式

对于Compose来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别说明,命令对象将是项目,这意味着项目中所有服务都会受到命令影响。

执行docker-compose [COMMAND] --help或者docker-compose help[COMMAND]可以查看具体某个命令的使用格式。

Compose命令的基本的使用格式如下:

3.2、命令选项

  • -f,--file FILE:指定使用的Compose模板文件,默认为docker-compose.yml,可以多次指定。
  • -p,--project-name NAME:指定项目名称,默认将使用所在目录名称作为项目名。
  • --profile NAME:指定启用的配置。
  • -c,--context NAME:指定启用的上下文的名称。
  • --verbose:输出更多调试信息。
  • --log-level LEVEL:设置日志级别(DEBUG、INFO、WARNING、ERROR、CRITICAL)。
  • --ansi(never|always|auto):控制何时打印ANSI控制字符。
  • -v,--version:打印版本并退出。
  • -H,--host HOST:指定所操作的Docker服务地址。
  • --tls:启用TLS,如果指定为-tlsverify,则默认开启。
  • --tlscacert CA_PATH:信任的TLS CA的证书。
  • --tlscert CLIENT_CERT_PATH:客户端使用的TLS证书。
  • --tlskey TLS_KEY_PATH:TLS的私钥文件路径。
  • --tlsverify:使用TLS校验连接对方。
  • --skip-hostname-check:不使用TLS证书校验对方的主机名。
  • --project-directory PATH:指定工作目录,默认为Compose文件所在路径;
  • -env-file PATH':指定额外的环境变量文件。

3.3、命令使用说明

3.3.1、build

命令格式为docker-composebuild [options]​[SERVICE...]​。

该命令用于构建(重新构建)项目中的服务容器。服务容器一旦构建,将会带上一个标记名,例如对于Web项目中 的一个db容器,可能是web_db。可以随时在项目目录下运行docker-compose build命令来重新构建服务。

选项包括:

  • --build-arg key=val:设置构建时的变量。
  • --compress:使用gzip压缩构建的上下文。
  • -m,--memory MEM:设置构建容器的内存上限。
  • --no-cache:构建镜像过程中不使用Cache(这将加长构建过程)​。
  • --no-rm:不删除构建过程中的临时容器。
  • --pull:始终尝试通过pull来获取更新版本的镜像。
  • --parallel:并行构建镜像。
  • --progress string:设置进度输出类型(auto、plain、tty)。
  • -q,--quiet:不输出到标准输出。
3.3.2、config

命令格式为docker-compose config [options]​,用于校验和查看Compose文件的配置信息。支持的选项包括:

  • -resolve-image-digests:为镜像添加对应的摘要信息。
  • -no-interpolate:不修改环境变量。
  • -q,-quiet:只检验格式正确与否,不输出内容。
  • -profiles:输出使用的配置名称。
  • -services:输出Compose中所有的服务信息。
  • -volumes:输出Compose中所有的挂载卷信息。
  • -hash="*":输出服务配置的hash值。
3.3.3、down

命令格式为docker-compose down [options]​,用于停止服务栈,并删除相关资源,包括容器、挂载卷、网络、创建镜像等。默认情况下只清除所创建的容器和网络资源。支持的选项包括:

  • -rmi type:指定删除镜像的类型,包括all(所有镜像)​,local(仅本地)​。
  • -v,-volumes:删除挂载数据卷。
  • -remove-orphans:清除孤儿容器,即未在Compose服务中定义的容器。
  • -t,-timeout TIMEOUT:指定超时时间,默认为10s。
3.3.4、events

命令格式为docker-composeevents [options]​[SERVICE...]​,用于实时监控容器的事件信息。支持的选项为:-json,表示以Json对象流格式输出事件信息。

3.3.5、exec

命令格式为docker-compose exec [options]​[-eKEY=VAL...] SERVICE COMMAND [ARGS...]​,用于在一个运行中的容器内执行给定命令。支持的选项包括:

  • -d:在后台运行命令。
  • -privileged:以特权角色运行命令。
  • -u,-user USER:以给定用户身份运行命令。
  • -T:不分配TTY伪终端,默认情况下会打开。
  • -index=index:当服务有多个容器实例时指定容器索引,默认为第一个。
  • -e,-env KEY=VAL:设置环境变量。
  • -w,-workdir:指定执行命令时的工作目录。
3.3.6、help

获得一个命令的帮助。

3.3.7、images

命令格式为docker-compose images[options]​[SERVICE...]​,用于列出服务所创建的镜像。支持的选项为-q,表示仅显示镜像的ID。

3.3.8、kill

命令格式为docker-compose kill [options]​[SERVICE...]​,该命令通过发送SIGKILL信号来强制停止服务容器,支持通过-s参数指定发送的信号,例如通过如下指令发送SIGINT信号。

$docker-composekill-s SIGINT
3.3.9、logs

命令格式为docker-compose logs [options]​[SERVICE...]​,用于查看服务容器的输出。默认情况下,docker-compose将对不同的服务输出使用不同的颜色来区分。可以通过–no-color来关闭颜色。

该命令在调试问题时十分有用。支持的选项为:

  • -no-color:关闭彩色输出。
  • -f,-follow:持续跟踪输出日志消息。
  • -t,-timestamps:显示时间戳信息。
  • -tail="all":仅显示指定行数的最新日志消息。
  • -no-log-prefix:日志输出不打印前缀。
3.3.10、pause

命令格式为docker-compose pause [SERVICE...]​,用于暂停一个服务容器。

3.3.11、port

命令格式为docker-compose port [options] SERVICE PRIVATE_PORT,用于打印某个容器端口所映射的公共端口。支持的选项为:

  • --protocol=proto:指定端口协议,如TCP(默认值)或者UDP。
  • --index=index:如果同一服务存在多个容器,指定命令对象容器的序号(默认为1)​。
3.3.12、ps

命令格式为docker-compose ps [options]​[SERVICE...]​,用于列出项目中目前的所有容器。支持的选项为:

  • -q:只打印容器的ID信息。
  • -services:显示服务。
  • -filter KEY=VAL:过滤显示的服务。
  • -a,-all:输出包括处于停止状态的容器。
3.3.13、pull

命令格式为docker-compose pull [options]​[SERVICE...]​,用于拉取服务依赖的镜像。支持的选项为:

  • --ignore-pull-failures:忽略拉取镜像过程中的错误。
  • --no-parallel:禁用并行拉取。
  • -q,--quiet:拉取时不打印进度信息。
  • --include-deps:拉取作为依赖项声明的服务。
3.3.14、push

命令格式为docker-compose push [options]​[SERVICE...]​,用于推送服务创建的镜像到镜像仓库。支持的选项为–ignore-push-failures,表示忽略推送镜像过程中的错误。

3.3.15、restart

命令格式为docker-compose restart [options]​[SERVICE...]​,用于重启项目中的服务。支持的选项为-t,–timeout TIMEOUT,用于指定重启前停止容器的超时(默认为10s)​。

3.3.16、rm

命令格式为docker-compose rm [options]​[SERVICE...]​,用于删除所有(停止状态的)服务容器。推荐先执行docker-compose stop命令来停止容器。支持的选项为:

  • -f,--force:强制直接删除,包括非停止状态的容器。一 般尽量不要使用该选项。
  • -s,--stop:删除之前先停止容器。
  • -v:删除容器所挂载的数据卷。
3.3.17、run

命令格式为docker-compose run[options]​[-p PORT...]​[-e KEY=VAL...]SERVICE[COMMAND]​[ARGS...]​,用于在指定服务上执行一个命令,例如:

这将会启动一个ubuntu服务容器,并执行pingdocker.com命令。

默认情况下,如果存在关联,则所有关联的服务将会自动被启动,除非这些服务已经在运行中。该命令类似启动容 器后运行指定的命令,相关卷、链接等都将会按照配置自动创建。二者有两个不同点:

  • 给定命令将会覆盖原有的自动运行命令。
  • 不会自动创建端口,以避免冲突。

如果不希望自动启动关联的容器,可以使用–no-deps选项,例如:

将不会启动Web容器所关联的其他容器。

支持的选项为:

  • -d:后台运行容器。
  • --name NAME:为容器指定一个名字。
  • --entrypoint CMD:覆盖默认的容器启动指令。
  • -e KEY=VAL:设置环境变量值,可多次使用选项来设置多个环境变量。
  • -l,--label KEY=VAL:指定标签。
  • -u,--user="":指定运行容器的用户名或者uid。
  • --no-deps:不自动启动关联的服务容器。
  • --rm:运行命令后自动删除容器,d模式下将忽略。
  • -p,--publish=[​]​:映射容器端口到本地主机。
  • --service-ports:配置服务端口并映射到本地主机。
  • --use-aliases:使用服务的网络别名。
  • -v,--volume=[​]​:绑定挂载卷。
  • -T:不分配伪tty,意味着依赖tty的指令将无法运行。
3.3.18、scale

命令格式为docker-compose scale[options]​[SERVICE=NUM...]​,用于设置指定服务运行的容器个数。可以通过service=num的参数来设置数量。例如:

这将启动3个容器运行web服务,2个容器运行db服务。

一般地,当指定数目多于该服务当前实际运行的容器数目时,将新创建并启动容器;反之,将停止容器。

支持的选项为-t,–timeout TIMEOUT,表示停止容器时的超时(默认为10s)​。

3.3.19、start

命令格式为docker-compose start [SERVICE...]​,用于启动已经存在的服务容器。

3.3.20、stop

命令格式为docker-compose stop [options]​[SERVICE...]​,用于停止已经处于运行状态的容器,但不删除它。通过docker-compose start可以再次启动这些容器。

支持的选项为-t,–timeout TIMEOUT,表示停止容器时的超时(默认为10s)​。

3.3.21、top

命令格式为docker-compose top [SERVICE...]​,用于显示 服务栈中正在运行的进程信息。

3.3.22、unpause

命令格式为docker-compose unpause[SERVICE...]​,用于恢复处于暂停状态中的服务。

3.3.23、up

命令格式为docker-compose up[options]​[SERVICE...]​。该命令十分强大,它将尝试自动完成包括构建镜像、​(重新)创建服务、启动服务,并关联服务相关容器的一系列操作。

链接的服务都将会被自动启动,除非已经处于运行状态。可以说,大部分情况下都可以直接通过该命令来启动一个项目。

默认情况下,docker-compose up启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便地进行调试。当通过Ctrl-C停止命令时,所有容器将会停止。

如果使用docker-compose up -d,将会在后台启动并运行所有容器。一般推荐在生产环境下使用该选项。

默认情况下,如果服务容器已经存在,docker-composeup将会尝试停止容器,然后重新创建(保持使用volumes-from挂载的卷)​,以保证新启动的服务匹配docker-compose.yml文件的最新内容。如果用户不希望容器被停止并重新创建,可以使用docker-compose up–no-recreate。这样将只会启动处于停止状态的容器,而忽略已经运行的服务。如果用户只想重新部署某个服务,可以使用docker-compose up--no-deps-d <SERVICE_NAME>来重新创建服务并在后台停止旧服务,启动新服务,并不会影响到其所依赖的服务。

支持的选项为:

  • -d:在后台运行服务容器。
  • -no-color:不使用颜色来区分不同的服务的控制台输出。
  • -quiet-pull:拉取镜像时不显示进度信息。
  • -no-deps:不启动服务所链接的容器。
  • -force-recreate:强制重新创建容器,不能与–no-recreate同时使用。
  • -no-recreate:如果容器已经存在了,则不重新创建,不能与–force-recreate同时使用。
  • -no-build:不自动构建缺失的服务镜像。
  • -no-start:创建服务后不启动它们。
  • -build:在启动容器之前构建镜像。
  • -abort-on-container-exit:当有容器停止时中止整个服务,与-d选项冲突。
  • -attach-dependencies:附加到依赖的容器。
  • t,--timeout TIMEOUT:停止容器时的超时(默认为10s)​,与-d选项冲突。
  • V,--renew-anon-volumes:重新创建匿名卷,而不是从先前的容器中获取数据。
  • -remove-orphans:删除服务中未定义的孤儿容器。
  • -exit-code-from SERVICE:退出时返回指定服务容器的退出符。
  • -scale SERVICE=NUM:扩展指定服务实例到指定数目。
  • -no-log-prefix:在日志中不打印前缀。
3.3.24、version

命令格式为docker-compose version,用于输出版本信息。

4、Compose环境变量

除了命令行参数和环境变量文件外,还可以使用环境变量来配置Compose的行为。Compose中定义了一系列环境变量,这些变量以COMPOSE_为前缀。

4.1、Compose中定义的环境变量

  • 1.COMPOSE_PROJECT_NAME
    设置Compose的项目名称,默认是当前工作目录(docker-compose.yml文件所在目录)的名字。

    Compose会在每一个启动的容器前添加项目名称。例如一个名称为proj的项目,其中的一个Web容器,名称可能为proj_web_1。

  • 2.COMPOSE_FILE
    设置要使用的docker-compose.yml的路径。如果不指定,默认会先查找当前工作目录下是否存在docker-compose.yml文件,如果找不到,则继续查找上层目录。

  • 3.COMPOSE_PROFILES
    定义执行compose up时的配置文件,这些配置文件可以覆盖和补充Compose文件中定义的服务的属性,例如环境变量、镜像、命令等。

    指定配置文件时,标记了对应配置文件的服务和没有带任何配置文件标记的服务会被compose up执行。

  • 4.COMPOSE_CONVERT_WINDOWS_PATHS
    将挂载卷的Windows路径风格转换为UNIX路径风格。

  • 5.COMPOSE_PATH_SEPARATOR
    指定COMPOSE_FILE环境变量中的路径间隔符。

  • 6.COMPOSE_IGNORE_ORPHANS
    指定是否忽略孤儿容器。

  • 7.COMPOSE_PARALLEL_LIMIT
    设置Compose可以执行进程的并发数。

4.2、在Compose文件中使用环境变量

Compose已经支持从环境变量中读取内容,最简单的做法类似Shell语法,使用"${VAR}",如下所示:

当执行Compose的环境中存在VERSION=1.0环境变量定义时,上述指令实际上等价于:

环境变量也可以写入路径下的.env文件中,如VERSION=1.0,同样会被Compose自动读取。

另外,Compose也支持设置变量的默认值,例如:

  • ${VAR:-default}:当${VAR}未定义或为空值时,采用default值;
  • ${VAR-default}:当${VAR}未定义时,采用default值。

4.3、Compose应用案例一:Web负载均衡

负载均衡器+Web应用是十分经典的应用结构。

下面,笔者将创建一个该结构的Web项目:一个Haproxy作为负载均衡器,后端挂载三个Web容器。

首先创建一个haproxy_web目录,作为项目工作目录,并在其中分别创建两个子目录:web和haproxy。

4.3.1、web子目录

在web子目录下将放置所需Web应用代码和Dockerfile,一会将生成需要的Web镜像。

这里用Python程序来实现一个简单的Web应用,该应用能响应HTTP请求,返回的页面将打印出访问者的IP和响应请求的后端容器的IP。

  • (1)index.py
    编写一个index.py作为服务器文件,代码为:


  • (2)index.html
    生成一个临时的index.html文件,其内容会被index.py来更新。生成一个临时的healthcheck.html文件,供HAProxy进行健康检查时使用。
  • (3)Dockerfile
    生成一个Dockerfile,部署该Web应用,内容为:
4.3.2、haproxy目录

该目录将配置haproxy镜像。在其中生成一个haproxy.cfg文件,内容为:

4.3.3、docker-compose.yml

在haproxy_web目录下编写一个docker-compose.yml文件,该文件是Compose使用的主模板文件,其中,指定启动3个Web容器(weba、webb、webc),以及1个haproxy容器:

4.3.4、运行compose项目

现在haproxy_web目录应该显示为下面的样子:

在该目录下执行sudo docker-compose up命令,控制台会整合打印出所有容器的输出信息:

此时通过浏览器访问本地的80端口,会获取到页面信息,如图所示。

页面信息经过Haproxy自动转发到后端的某个Web容器上,刷新页面,可以观察到访问的容器地址的变化。访问本地70端口,可以查看到Haproxy的统计信息,如图所示。

查看本地的镜像,会发现Compose自动创建的haproxyweb_weba,haproxyweb_webb,haproxyweb_webc镜像:


当然,还可以进一步使用consul等方案来实现服务自动发现,这样就可以不用手动指定后端的Web容器了,更为灵活。

4.4、Compose应用案例二:大数据Spark集群

Spark是由Berkeley开发的分布式计算框架。相对于Hadoop,Spark可以缓存中间结果到内存,提高某些需要迭代计算的场景的效率,因此它受到广泛关注。

如果用户只熟悉Hadoop,也不必担心。Spark的很多设计理念和用法都与Hadoop保持一致或相似,并且在使用上完全兼容HDFS。但是,Spark的安装并不容易,它需要安装包括Java、Scala、HDFS等多个依赖。

使用Docker Compose可以快速在本地搭建一套Spark环境,方便大家开发Spark应用或者将其扩展到生产环境中。

4.4.1、准备工作

这里,笔者采用热门的sequenceiq/docker-spark镜像,这个镜像已经安装了对Spark的完整依赖。由于镜像比较大(2 GB以上)​,推荐先下载镜像到本地:

  • (1)docker-compose.yml文件
    首先新建一个spark_cluster目录,并在其中创建一个docker-compose.yml文件。文件内容如下:


    docker-compose.yml中定义了两种类型的服务:master和worker。master类型的服务容器将负责管理操作,worker则负责具体处理。

  • (2)master服务
    master服务映射了好几组端口到本地,功能分别为:

    • 4040:Spark运行任务时候提供Web界面观测任务的具体执行状况,包括执行到哪个阶段、在哪个executor上执行。
    • 8042:Hadoop的节点管理界面。
    • 7077:Spark主节点的监听端口,用户可以提交应用到这个端口,worker节点也可以通过这个端口连接到主节点构成集群。
    • 8080:Spark的监控界面,可以看到所有的worker、应用整体信息。
    • 8088:Hadoop集群的整体监控界面。

    下图中给出了master端口示例。

  • (3)worker服务
    类似master节点,启动后,执行了/usr/local/spark/sbin/start-slave.shspark://master:7077命令来配置自己为worker节点,然后通过ping来避免容器退出。注意,启动脚本后需要提供spark://master:7077参数来指定master节点地址。

    在8081端口提供的Web界面,可以看到该worker节点上任务的具体执行情况,如图所示。

4.4.2、启动集群

在spark_cluster目录下执行启动命令:

可以看到类似如下的输出:

docker-compose服务运行起来后,还可以用scale命令来动态扩展Spark的worker节点数,例如:

4.4.3、执行应用

Spark推荐用spark-submit命令来提交执行的命令,基本语法为:

例如,可以使用Spark自带样例中计算Pi的应用。

在master节点上执行命令:

最后的参数1000表示要计算的迭代次数为1000次。

在任务运行过程中,可以用浏览器访问4040端口,看到任务被分配到了两个worker节点上执行,如图所示。

计算过程中也会输出结果,如下所示:


RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进