-
容器编排
如果使用前面的知识来部署一个网站,我们需要先启动数据库容器,然后再启动应用容器,最后可能还要启动反代理容器, 这样才算完整地部署一个Web应用。这需妥使用三条命令才能部署,操作起来很麻烦,而且不能把三个容器统一起来管理,就连三条命令都要自己动手保存起来,那么有没有什么工具可以统一管理多个互相关联的容器呢?
工具有不少,如docker compose,Docker Compose原本是Docker社区的一个基于Python语言编写的容器编排工具,后来被Docker项目组合并。
简单来说,Docker Compose是一个用来组装、管理多容器应用的工具,它可以根据配直文件自动构建、管理、编排一组容器,极大地方便了用户对多容器应用的操作。
-
安装Docker Compose
Docker Compos巳使用Python语言编写,因此从一开始它就是全平台支持的, 而且release文件一个二进制执行文件,因此可以很轻松地安装到各个平台中。
-
二进制安装
下载docker-compose
curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
授权
chmod +x /usr/local/bin/docker-compose
查看版本
docker-compose version
此外还有pip安装方式不再细说。
-
Docker Compose命令
学习Docker Compose 当然不能忽视最基本的启动参数。 Docker Compose 命令是 dockercompose。
Docker Compose默认解析当前目录的docker-compose.yml文件,DockerCompose的命令有些类似DockerClient的子命令,使用docker-compose -h即可查看
-
指定配置文件
下面先看Commands中常用的参数。
这个参数是 -f,它是用来指定DockerCompose配置文件的。该参数可以使用多次,例如:
docker-compose -f docker-compose.yml -f docker-compose admin.yml
如果两份配置文件有同名的服务,Docker Compose只会解析执行后面的配置文件。例如在docker-compose.yml中有一个服务叫作webapp:
在docker-compose admin.yml也有一个叫作webapp的服务:
Docker Compose会执行后面的webapp配置,-f选项是可选的,如果不使用该选项,默认会解析当前目录下的docker-compose.yml文件。
-
指定项目名称
Docker Compose启动容器时会默认地把当前的目录名称设置为容器名称的 前缀,例如在web文件夹下启动容器,配置文件中有两个服务分别是app和db, 启动的容器名称默认是 web_db_1和web_app_l,如果想要指定容器项目名称(就是web这个前缀),可以使用-p参数:
docker-compose -p myapp up
想要完全指定名称可以在配置文件指定。
-
Compose环境变量
在Docker Compose中有一个环境配置文件 .env,这是一个隐藏文件,文件中可以设定一些Docker Compose的环境变量。
COMPOSE_PROJECT_NAME:这个变量用来定义使用Compose启动容器时的名称,作用与-p参数相同。
COMPOSE_FILE:指定默认的配置文件名称,默认是docker-compose.yml,作用类似于-f参数。
DOCKER_HOST:指定Docker client连接Docker daemon的地址,默认是unix:///v ar/run/docker.sock。
如果是远程操作,可以使用上面的 -tls*选项,要确保指令传输过程加密,因为 有时候启动命令中会有明文密码。
小技巧:操作Docker或者Compose时如何避免在Shell环境的历史记录中暴露密码呢?可以通过间接输出密码的方式,例如以docker run -e PASSWORD=$(cat pass.txt)这样的方式输入命令,同理,Compose可以在配置文件中使用这一 Shell语句的特性,或者像下面这样:
解析执行的时候会.env的变量置换到yml文件中
-
build:构建服务镜像
Docker Compose提供了与DockerClient类似的构建命令,与DockerBuild不同, dockercompose.yml不只是个启动配置,有时还包括构建定义,例如:
在上面的docker-compose.yml中执行docker-compose build命令时会自动创建mysql与ui两个镜像,默认构建的镜像名称是myapp_myapp和myapp_ui上面在设置Dockerfile路径的同时还可以指定Dockerfile的上下文路径,这是Dockerclient做不到的。
在docker-compose.yml里面定义构建镜像时要注意一定要把Dockerfile写好,因为Docker Compose实际上是通过docker-compose.yml读取信息解析后发给Docker Client执行的。在docker-compose.yml中可以使用相对路径。
在docker-compose.yml中通常包含了多个容器构建,启动配置,默认情况下使用docker-compose build时构建docker-compose.yml里面的所有镜像。
但是有时候我们只是想构建其中一个容器的镜像,这时可以指定构建容器的名称, 例如:
docker-compose build ui
这个命令适用于重构部分镜像使用,避免重构所有的镜像。
选项:
--build arg key=val 设置服务的生成时间变量。
--compress 使用gzip压缩构建上下文。
--force-rm 强制rm始终移除中间容器。
-m、 --memory MEM 内存设置生成容器的内存限制。
--no-cache 生成映像时不使用缓存。
--no-rm 成功生成后不删除中间容器
--parallel 构建并行映像。
--progress string 设置进度输出的类型(自动、普通、tty)。
--pull 始终尝试提取较新版本的图像。
-q, --quiet 不要把任何东西打印到STDOUT上
--force-rm和--no-cache都是属于在构建过程中自动清理缓存的选项, 我们知道,构建过程实际上是后台运行一个容器在执行Dockerfile的命令,这其中会产生中间容器,使用—force-rm选项会在构建结束时删除这些容器,而如果构建失败的话,则Docker会在本地保留上一个临时容器,该容器保存了直至失败那条命令前面的构建内容,也就是我们说的构建缓存,使用--no-cache会在构建过程中自动删除构建缓存,所以上面这两个选项都不推荐使用。
此外还有一个选项就是-pull选项,默认情况下Docker Compose会在启动容器的时候查看本地是否有该镜像,如果有就直接使用本地已存在的镜像,使用一pull之后即使本地有该镜像,也会执行该pull命令拉取镜像,这样可以确保每次启动的容器都是基于最新的镜像启动的。
-
bundle:生成DAB包
从docker-compose.yml文件中生成一个分布式应用程序包(DAB),这个概念涉及分布式应用,在这不进行细说,简单地说就是生成了一个.dab文件,然后使用docker deploy部署。
此命令在20版本已经丢弃
-
config:检查配置语法
这个命令用来检查docker-compsoe.yml文件是否有语法问题,如果有问题会返回错误的原因:
以下是各个参数解释:
将图像标记固定到摘要。
不要插入环境变量。
只验证配置,不打印任何东西
打印配置文件名称,每行一个。
打印服务名称,每行一个。
打印卷名,每行一个。
打印服务配置哈希,每行一个。为指定服务的列表设置"service1,service2"
或者使用通配符显示所有服务。
-
create:创建服务容器
这个命令与Docker Create类似,使用docker-compose create会创建所有服务需要的容器,但是不会运行。
这个命令将丢弃,改为up命令了。
-
down:清理项目
这个命令与后面的up命令相对应,down可以停止容器并删除包括容器、 网络、数据卷等内容。也就是说,只要是up命令创建的东西,使用down都可以删除。此外,如果网络、数据卷等资源正在被其他服务使用,down会跳过这些组件。例如:
与docker rm命令类似,docker-compose down也可以通过-v和--rmi来指定删除的内容。
默认情况下,down命令只会删除定义的服务运行的容器,以及网络。通过指定-v参数会删除数据卷,指定--rmi可以删除与服务相关的镜像,此外,使用-remove-orphans还可以删除与服务相关、但是没有在配置文件中重定义的容器。
-
events:查看事件
这个命令实际上就是对docker events的整合,通过这个命令可以看到与配置文件定义的服务的相关事件:
使用--json选项可以格式化输出,更容易阅读
-
exec:进入服务容器
这个命令和docker exec类似,可以进入容器执行命令,不同的是docker compose exec后面是服务名称而不是容器名称。
-
kill:杀死服务容器
使用kill命令,默认会杀死项目下所有服务的容器,如果指定服务名称可以杀死指定服务下的容器。不可以杀死指定容器名称:
-
logs:查看服务容器日志
这个命令用于查看项目日志, 默认这些日志包含了全部容器的日志, 输出时会用不同的颜色标示,指定服务名称可以查看指定服务的日志:
-
pause:暂停服务容器
暂停项目服务可以使用这个命令,默认会停止全部的服务容器的进程,类似于使用docker pause的效果,如果你需要停止指定的服务,可以在后面指明服务名称。
-
port:查看服务容器端口状态
在Docker Compose中port命令不如Docker Client中的port命令那么灵活,在Docker Compose中使用port命令,你不仅需要指定服务名称,还需要指定服务容器暴露的端口才可以查看该端口在宿主机中的映射。
-
ps/images:查看容器与镜像
该命令的用途与docker ps类似,使用docker-compose ps可以查看正在运行的服务容器。
-
pull:拉取项目镜像
使用docker-compose pull可以拉取多个镜像,因为在一份docker-compose.yml文件中通常有多个服务, 每个服务都要有一个镜像作为镜像基础。
在DockerCompose所有的子命令中都可以使用-f这个参数,因此在pull操作时也可以指定多个配置文件,如果服务名相同,后来者会覆盖前者,pull操作只会在拉取后出现服务所需要的镜像:
-
push:推送项目镜像
在一些项目中,镜像并不是基于现成的Docker镜像运行的,而是在第-次启动的时候自动创建的。因此在项目中有新构建的镜像时,可以使用push将项目的服务镜像推送到仓库中:
-
restart:重启服务容器
在DockerCompose中可以像DockerClient一样操作容器, 所以当然也包括重启服务容器,restart 默认会重启项目下的全部服务容器。
如果用户指定服务名称,可以重启指定的服务容器。
-
rm:删除项目容器
使用rm命令当然可以删除服务容器,Docker Compose的rm实际上就是对配置文件解析后向Docker Client发送rm的API请求,因此Client的参数在Compose这里也大都适用,例如-v是删除服务容器的数据卷。
-f是强制删除服务容器,与Docker client不同的是,Compose不允许强制删除正在运行的容器,因此必须是停止或者杀死容器之后才能执行删除容器的操作。 使用docker-compose rm操作时默认会提示是否真的删除容器:
而使用-f参数之后会直接删除而不会询问。
-
run:执行一次性命令
与Docker client不同的是,Compose并没有给run命令太多的可选参数。 Compose的run命令与 Docker client的run命令不一样。 使用docker-compose run命令只能对一个服务的容器运行一个一次性的命令。例如,启动一个容器的 bash的命令:
docker-compose run app bash
使用run命令运行容器时,创建的容器不属于项目中的服务,而是作为一个独立的容器,例如下面项目有两个服务,app和db,app依赖db 服务,现在需要使用app的配置来临时执行一条一次性的命令,这时候就需要用run命令来运行一个app容器了:
docker-compose run -d app ./script.sh
使用run命令执行时创建的容器不属于项目服务的一部分,容器名字表明这是一个使用run命令启动的一次性容器。执行删除时也不像上面的rm命令一样必须要停止容器才可以删除,而是直接删除的:
如果同时启动多个一次性容器,则会生成多个run标志的容器:
但是使用ps命令查看服务时,是看不到这些容器信息的:
使用rm -f命令时会直接删除所有一次性容器:
这个命令会使用配置文件里面定义的配置来启动容器。这意昧着启动容器具有相同的数据卷、链接映射和配置,不过有两点不同。
-
run会覆盖配置文件中的运行命令,例如容器默认CMD是bash,使用docker-compose run app python之后Python会覆盖bash命令。
-
run命令不会解析执行配置文件中的端口映射定义,这可以有效地防止端口占用等问题,如果你需要在run命令中执行端口映射,请加上—service-ports参数,或者手动指定端口映射,和Docker Client一样使用-p参数
上面提到一个—no-deps参数,这是一个取消容器关联的参数,例如有一个项目, 项目内有两个服务,其中一个是应用容器(app),另一个是数据库(db),应用容器依赖数据库容器,如果使用 docker-compose run app bash来运行一个 次性命令,会默认启动数据库容器,如果不需要这种关联就需要添加--no-deps参数。
到底什么时候需要使用run命令呢?一个简单的例子就是备份数据库,我们知道如果将服务写到配置文件中就会解析执行,因此备份数据库的配置文件通常要独立开来,这个时候就有两个配置文件了,如下面的例子:
在docker-compose.yml中定义了web和db两个服务:
然后在docker-compose.backup. yml中定义一个备份服务,内容如下:
再然后使用run命令来运行这次备份任务,这是一个一次性命令,使用-f加入两个配置文件才可以完成备份任务,这样就把备份配置与运行配置分开来了。
-
-
scale:设置服务容器数量
这个命令已经放弃,未来会删除,作为替代,这个命令变成了up命令的一个参数,通常web服务为了保证高可用和负载均衡,会在后端启动多个服务,以确保应用不会因为其中后端服务崩溃而无法访问。
-
start:启动服务容器
-
stop:停止服务容器
-
top:查看进程状态
查看容器内部运行的进程
docker-compose top SERVICE命令表示后面接的是服务名称而不是容器名称,服务名称可以是多个,如果不写则默认输出全部的服务信息。
top命令是非交互式的,PID表示进程在宿主机中的ID编号,PPID是父级进程D编号,C表示在容器内部的PID。通常,C的值为l的那个进程是容器的核心进程。
-
unpause:取消暂停
用pause的时候,会锁定容器进程,这时候需要使用unpause来取消暂停才可以继续操作容器。
同样默认是针对项目全部的服务,可以指定服务名称来操作。无论是pause还是unpause都需要容器处于运行状态才能操作,话得说回来,不运行的容器也用不着暂停。
-
up:启动项目
最后,up命令可以说是压轴出场的命令,这个命令与down相对应,使用up命令的时候会从配置文件读取解析各项定义,然后发给 Docker Client执行,up可以创建包括服务容器、数据卷、网络等一系列组件。
Compose的up命令包括构建、创建(重新创建)、启动和连接服务容器。直接使用docker-composeup命令可以聚合全部的容器信息,每个容器输出的内容会用不同的颜色区分,当按快捷键 Ctrl+C时,会停止所有容器的输出。
如果想让项目在后台运行就需要添加-d参数,这样服务就会在后台运行,通过docker-compose ps可以查看容器运行状态,logs可以看到所有容器的日志。
下面以一个例子来说明
首先去https://github.com/vegasbrianc/docker-compose-demo下载项目
这里需要上外网,拉取镜像的时候可能需要设置以下本机dns地址,8.8.8.8
我们启动5个whoami服务
我们删除一个whoami容器看看
发现第一个whoami容器消失了,但还是有4个whoami提供服务。所以仍然可以正常提供服务。
-
Compose配置文件
Docker Compose是使用YML文件来定义多个容器关系的,因此掌握docker-compose.yml文件的写法才能更好地书写配置文件,以方便管理多容器应用。
Docker Compose实际上是把YML文件解析成原生的 Docker命令然后执行的,它通过定义解析容器依赖关系来按顺序启动容器。
-
配置文件基础
Compose配置文件是一个YML格式的文件它定义了包括服务(容器)、网络、数据卷在内的一系列项目组件。Compose配置文件的默认路径是./docker-compose.yml。
使用配置文件定义的服务在启动时就像使用Docker Client的docker run一样,同样的配置文件重定义的网络、数据卷也相当于在Docker Client中使用docker network create和docker volume create一样。实际上,Compose并不会真正地操作容器,它管理容器的办法就是解析配置文件的定义,然后发送给Docker Client。
Compose配置文件中定义的每个服务部必须通过image标签指定镜像或build标签来执行构建(上下文中存在Dockerfile)。其实配置文件的写法与Docker Client中的命令有异曲同工之妙。就像在docker run中一样,使用Compose
时,Dockerfile中的命令依然有效,不必在docker-compose.yml文件中重新设定。
例如,在Dockerfile中定义的变量可以在docker-compose.yml文件中使用,就像Shell脚本的写法样,形如${EXTERNAL_PORT}即可。
Compose配置文件有多个版本,建议按照最新配置文件写法。
-
基础配置
下面看一份简单的docker-compose.yml文件:
可以看到一份标准配置文件应该包含version、services、 networks三大部分,其中最关键的就是services和networks两个部分,下面先来看services的书写规则。
-
image
在services标签下的第二级标签是web,这个名字是用户自己定义的,它就是服务名称。
image则是指定服务的镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取这个镜像。
例如下面这些格式都是可以的 :
image:redis
image:ubuntu:16.04
-
build
服务除了可以基于指定的镜像,还可以基于一份Dockerfile,在使用up启动之时执行构建任务,这个构建标签就是build,它可以指定Dockerfile 所在文件夹的路径。Compose将会利用它自动构建这个镜像,然后使用这个镜像启动服务容器。
build: /path/to/build/dir
也可以是相对路径,只要上下文确定就可以读取Dockerfile
build:./dir
设定上下文根目录,然后以该目录为准指定Dockerfile。
注意:build是一个目录,如果你要指定Dockerfile文件,需要在 build标签的子级标签中使用dockerfile标签指定,如上面的例子。
如果你同时指定image和build两个标签,那么Compose会构建镜像并且把镜像命名为image 后面的那个名字。
build: ./dir
image: webapp:tag
既然可以在 docker-compose.yml中定义构建任务,那么一定少不了arg 这个标签,还记得 Dockerfile中的ARG 命令吧,它可以在构建过程中指定环境变量,但是在构建成功后取消,在 docker-compose.yml文件中也支持这样的写法:
下面这种写法也可以,更适合阅读
与ENV不同的是,ARG是允许空值的。例如:
这样,构建过程可以向它们赋值 。
在v3.2中,添加了一个新的标签CACHE FROM,通过指定构建缓存,类似于docker build
--cache-from命令
在v3.3版本中,补充了LABELS标签,与Dockerfile中的LABEL命令相同。
同时,把以前独立的capabilities标签(cap_add与cap_drop)移入build中,需要注意的是这个配置会在Swarm中失效,因为集群调度的权限由Swarm控制。
注意:YAML的布尔值(true, false, yes,no, on, off)必须要用引号引起来(单引号、双引号均可),否则会当成字符串解析的。
-
command
使用command可以覆盖容器启动后默认执行的命令。
command: bundle exec thin -p 3000
也可以写成类似Dockerfile中的格式
command: [bundle, exec, thin, -p, 3000]
-
configs
这个命令其实就是docker config,通过设置config文件,在集群部署时可以方便地调度配置文件,这是Swarm的亮点之一,与之匹配使用的通常还有docker secret等命令,Docker通过抽象配置、密钥等文件,把烦琐的文件复制工作变成了可管理的集群资源。
配置中的config 可以是任何形式的配置文件,在上面的配置文件中,我们设置了两个配置文件,其中my_config指定了一个值就是./my_config.txt,另一个my_ other_ config则使用了external 的标签,这表示它引用的是外部的配置文件,这个外部配置文件必须事先通过docker config create的方式创建,否则这个docker-compose.yaml是无法启动的。
source:Docker中存在的配置的名称
target:容器内部的目标路径
uid/gid:指定配置文件存放时的用户归属
mode:指定配置文件的权限
-
cgroup_parent
为容器指定一个可选的父cgroup:
cgroup_parent: m-executor-abcd
少数情况用到,并且对swarm集群无效
6.container_name
前面说过Compose 的容器名称格式是:
<项目名称><服务名称><序号>
虽然可以自定义项目名称、服务名称,但是如果你想完全控制容器的命名,可以使用这个标签指定:
container_name: app
这样,容器的名字就指定为app了。需要注意的是,在容器编排过程中并不建议使用指定的容器名,因为在伸缩服务规模时,命名是由Docker控制的,如果人为设定名称有可能导致命名冲突或者命名不规范而造成管理困难。
当然如果启动服务没有弹性伸缩的打算,自定义容器名称显然更容易管理。
7.deploy
这个命令仅在使用docker stack部署到群集时生效,也就是说,docker-compose up和docker-compose run等命令无效。
子选项解释如下:
MODE与REPLICAS
deploy部署的容器有两种情况,一种是global,另一种是replicated,这两种模式是冲突的,只能二选一:
或者
因为replicated是默认的。所以可以不写mode子选项。
UPDATE_CONFIG
配置服务应如何更新。该子选项常用于配置滚动更新。
parallelism:每次更新的容器数量
delay:更新一组容器时等待的时间
failure_action: 如果更新失败,后续操作是continue或pause(默认为pause)。
monitor_failure_ratio:允许更新过程中更新失败的最大容器数量。
RESOURCES
配置资源约束,主要是指硬件资源,把以前单独的选项放到deploy中有助于在Swarm集群中调整容器硬件资源的利用。主要包括:cpu shares, cpu quota, cpuset, mem limit, memswap_limit,mem_swappiness等。
都是单个值,所以一目了然,用法与docker run参数一致。设置limits可以有效地避免因为内存不足导致节点失联的情况。
RESTART_POLICY
在重启策略中可以配置在容器退出时如何重新启动容器。
condition:可选值有none、on-failure与any(默认为 any)。
delay:在每次尝试重新启动时要等待多长时间,指定一个时间值(默认值为0)。
max attempts:尝试重新启动一个容器最多可以多少次(默认为永不放弃)。
window:设置容器重新启动之后,等待多长时间才能确定容器启动成功,时间单位是秒(默认为立即判定)。
总结一下,Deploy不支持的选项有:buil d、cgroup_parent、container_name、 devices、dns、dns_search、 tmpfs、extemal_links、links、network_mode、sec urity_opt、stop_signal、sysctls、 usems_mode。说白了,就是集群不支持的Deploy都不支持。
8.devices
设备映射列表,使用与—device一致
devices:
-
-
"/dev/tty/USB0:/dev/ttyUSB0"
9.depends_on
在使用Compose 时,最大的好处就是减少使用烦琐的启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下地启动容器,必然会因为容器依赖问题而启动失败。
例如在没有启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况,我们需要加入一个标签,就是depends_on,这个标签解决了容器的依赖和启动先后的问题
例如下面容器会先启动redis和db两个服务,最后才启动web服务:
需要注意的是,默认情况下使用docker-compose up web这样的方式启动web服务时,也会启动redis和db两个服务,因为在配置文件中定义了依赖关系。
10.dns
dns和--dns参数有一样的用途,格式如下
dns: 8.8.8.8
也可以是一个列表
此外dns search的配置也类似,自定义DNS搜索域,可以是单个值或列表:
11.tmpfs
将临时目录挂载到容器内部中,具有类似于run的参数一样的效果
12.entrypoint
在Dockedile中有一个ENTRYPOINT命令,用于指定接入点,在前面己对比过它与CMD的区别。
在docker-compose.yml中可以定义接入点,覆盖Dockerfile中的定义:
entrypoint: /code/entrypoint.sh
格式和Docker类似,不过,还可以写成这样:
13.env_file
还记得前面提到的.env文件吧,这个文件可以设置Compose的变量。而在docker-compose.yml中可以定义一个专门存放变量的文件。
如果通过docker-compose -f FILE指定配置文件,则在env_file中路径会使用配置文件路径。
如果有变量名称与environment命令冲突,则以后者为准。格式如下:
env_file: . env
或者根据docker- compose.yml 设置多个:
需要注意的是,这里所说的环境变量是对宿主机的Compose而言的,如果在配置文件中有build操作,这些变量并不会进入构建过程中,如果要在构建中使用变量,还是首选前面讲的arg标签。
14.environment
environment与上面的env_file标签完全不同,反而和arg有几分类似,这个标签的作用是设置镜像变量,它可以将变量保存到镜像里面,也就是说,启动的容器也会包含这些变量设置,这是与arg最大的不同。
一般arg标签的变量仅用在构建过程中;而environment和Dockerfile中的ENV命令一样,会把变量一直保存在镜像和容器中,类似于docker run -e的效果:
15.expose
这个标签与Dockerfile中的EXPOSE命令一样,用于指定暴露的端口,但只是作为一种参考,实际上docker-compose.yml 的端口映射还得用ports这样的标签:
16.external_links
在使用Docker过程中,会有许多单独使用docker run启动的容器,为了使Compose能够连接这些不在docker-compose.yml中定义的容器,我们需要一个特殊的标签,就是external_links,它可以让Compose项目里面的容器连接到那些项目配置外部的容器(前提是外部容器中必须至少有一个容器是连接到与项目内服务同一个网络里面的)。
格式如下:
17.extra_hosts
添加主机名的标签,就是往:/etc/hosts文件中添加一些记录,与Docker client的--add-host类似:
启动之后,查看容器内部的hosts
18.healthcheack
healthchecks前面已经介绍过了一个用于检查容器运行状态的命令,与在Compose选项中用法一样。
interval指定间隔时间,test就是一条命令或者某种可以返回心跳信息的工具,三种写法都是可以的:
如果镜像构建时设置了健康检查,你可以关闭:
19.labels
向容器添加元数据,和Dockerfile的LABEL命令是一个意思,格式如下:
20.links
还记得上面的depends_on吧,那个标签是解决启动顺序的问题,这个标签是解决容器连接的问题,与Docker client的link有一样的效果,会连接到其他服务的容器中。
格式如下
使用别名将会自动地在服务容器中的/etc/hosts里创建。例如
相应的环境变量也将会被创建。
21.logging
这个标签用于配置日志服务。格式如下:
默认的driver是json-file。只有json-file和journald可以通过docker-compose logs显示日志,其他方式有其他的日志查看方式,但目前Compose不支持。对于可选值可以使用 options指定。
官方文档为:https://docs.docker.com/engine/admin/logging/overview/
22.network_mode
网络模式,与Docker client的—net参数类似,只是相对多了一个service:[service name]的格式。
23.networks
加入网络,这是一个顶级的选项,与服务、版本等选项同级。
上面是一个典型的网络配置例子,其中设置了两个网络,一个是新的new网络,另一个是旧的legacy网络,这种场景常见于服务升级时应用来不及调整或者前后端分离的场合。不同的服务可以位于不同的网络中。同时使用aliases选项,可以把同一个服务映射到不同的网络中,而且连接名称不一样。这里的aliases与--link的用法类似。
24.PID
pid: "host"
将 PID 模式设置为主机 PID 模式,跟主机系统共享进程命名空间。容器使用这个标签将能够访问和操纵其他容器和宿主机的名称空间。
25.ports
映射端口的标签。
使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口。
注意:当使用HOST:CONTAINER格式来映射端口时,如果你使用的容器端口小于60你可能会得到错误的结果,因为YAML将会解析xx:yy这种数字格式为60进制。所以建议采用字符串格式。
26.secret
为每个服务配置独立的secrets,支持两种不同的语法变体,用法与config一致。
配置与config是同一个模板,所以详情可参看上面的config章节。
27.security_opt
为每个容器覆盖默认的标签。简单来说,就是管理全部服务的标签,比如设置全部服务的user标签值为USER。
28.stop_signal
设置另一个信号来停止容器。在默认情况下是使用SIGTERM停止容器。设置另一个信号可以使用stop signal标签。
stop_signal: SIGUSR1
29.volumes
挂载一个目录或者一个已存在的数据卷容器,可以直接使用[HOST:CONTAINER]这样的格式,或者使用[HOST:CONTAINER:ro]这样的格式,后者对于容器来说, 数据卷是只读的,这样可以有效地保护宿主机的文件系统。
Compose的数据卷指定路径可以是相对路径,使用.或者..来指定相对目录。数据卷的格式可以是如下的多种形式:
30.volumes_from
从其他容器或者服务挂载数据卷,可选的参数是:ro或者:rw,前者表示容器只读,后者表示容器对数据卷是可读可写的。默认情况下是可读可写的。
31.extends
这个标签可以扩展另一个服务,扩展内容可以来自当前文件,也可以来自其他文件,在相同服务的情况下,后来者会有选择地覆盖原有配置。
用户可以在任何地方使用这个标签,只要标签内容包含file和service两个值就可以了。file的值可以是相对或者绝对路径,如果不指fille的值,那么Compose会读取当前YML文件的信息。
32.其它
还有下列这些标签:cpu_shares,cpu_quota, cpuset, domainname, hostname, ipc, mac_address, mem_limit, memswap_limit, privileged, read_only, restart, shm_size, stdin_open,tty, user, working dir, credential_ spec。
上面这些都是一个单值的标签,类似于使用docker run的效果。
-
网络配置
compose可以指定自定义网络,而不是使用默认的应用网络,这允许用户创建更复杂的拓扑结构和指定自定义网络的驱动程序和选项。
以下面配置文件为例,proxy服务位于项目的前端网络,app属于中间件, 位于前端Proxy和后端db之间,所以app需要与前后端两个网络中的容器通信:
除了配置默认网络之外,还可以使用已经存在的网络,与前面的networks 标签类似,可以在service同级标签中设置networks覆盖全部服务容器。例如:
-
配置拓展
前面的基础配置中介绍过一个标签extends,网络拓展中介绍了external标签,这两个都属于Compose配置文件中的一个拓展部分。
Compsoe配置扩展有两种方法,第一种方法是使用-f参数添加多个配置文件,在前面经介绍过了,第二种方法是使用extends标签,在Compose配置文件中可以使用该标签来扩展指定的服务。
关于第一种-f参数,其实Compose默认情况下不仅会读取docker-compose.yml这个文件,还会读取一个叫作docker-compose.override.yml的文件(如果存在的话),后者表示默认覆盖前者的配置,两者的名称在.env文件中可以定义。
举个例子:
下面是docker-compose.yml的内容,在文件中定义了两个服务(默认不填写,version 会按照Compsoe版本自动补充),分别是web和db:
然后,在同目录下的docker-compose.override.yml文件中定义了两个服务名称相同的服务,但是服务内的定义并不相同,此时docker-compose.override.yml的配置会选择性地覆盖上面配置的定义。
所谓选择性覆盖配置是指有冲突时以后面的配置为准, 无冲突时两者合并。例如上面两份配置文件选择性覆盖合并以后,实际内容是:
如果使用了-f参数指定多份配置文件,Compose将不会读取docker-compose.override.yml文件。
而第二个方法就是使用extends标签,这个标签原则上可以放在配置文件的任何地方,但是我们一般把它放到服务定义子级中,例如:
启动时Compose会从common-services.yml文件中读取拓展定义
这时候启动只需要指定docker-compose.yml即可,不必使用-f再指定common-services.yml文件。在同一个配置文件中还可以对同项目的服务做扩展,例如:
在上面的配置中,important_web基于web服务扩展,重新设置了cpu_shares的值,而web服务扩展自common-services.yml的webapp。
最后是关于配置覆盖的注意要点,前面提到过配置是选择覆盖的,例如command标签,Compose会把镜像Dockerfile中的定义与默认配置对比,如果不同则用默认配置的值覆盖Dockerfile的值,如果有扩展配置文件,那么以扩展配置文件的值为准,例如:
这是单值标签的情况,包含此种情况的标签还有image、mem-limit等。但在多值标签中又有不同,以expose标签为例:
除了expose,还有一些标签也是这样的,例如ports、expose、external_links、dns、dns_search、tmpfs等。
除了合并定义的情况还有产生定义冲突的情况,例如environment标签:
可以看到:在合并的基础上,Compose会把冲突的值处理,以后来定义的值为准。