Docker compose容器编排
1、Docker compose简介
docker-compose是docker的编排工具,用于定义和运行一个项目,该项目包含多个docker容器,在如今的微服务时代,一个项目会存在多个服务,使用docker一个个部署操作的话就会很麻烦,如果使用docker编排工具一键部署,统一管理就会便捷很多,同时也提高了开发,运维效率。
2、Docker-compose.yaml文件
2.1、文件格式
Docker Compose 的 YAML 文件包含 4 个一级 key:version、services、networks、volumes
version 是必须指定的,而且总是位于文件的第一行。它定义了 Compose 文件格式(主要是 API)的版本。注意,version 并非定义 Docker Compose 或 Docker 引擎的版本号。
services 用于定义不同的应用服务。上边的例子定义了两个服务:一个名为 lagou-mysql数据库服 务以及一个名为lagou-eureka的微服。Docker Compose 会将每个服务部署在各自的容器中。
networks 用于指引 Docker 创建新的网络。默认情况下,Docker Compose 会创建 bridge 网络。 这是一种单主机网络,只能够实现同一主机上容器的连接。当然,也可以使用 driver 属性来指定不 同的网络类型。
volumes 用于指引 Docker 来创建新的卷。
2.2、version段
版本信息,定义关乎于docker的兼容性,Compose 文件格式有3个版本,分别为1, 2.x 和 3.x
2.3、services段
定义不同的应用服务
2.3.1、image
image是指定服务的镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取镜像。 build和image二选一
services:
web: //配置服务标识(唯一编号)
image: nginx:1.20.1
2.3.2、build
服务除了可以基于指定的镜像,还可以基于一份Dockerfile,在使用up启动时执行构建任务,构建标签是build,可以指定Dockerfile所在文件夹的路径。Compose将会利用Dockerfile自动构建镜像,然后使用镜像启动服务容器。build和image二选一
可以指定绝对路径
build: /docker/compose/build/dir
也可以是相对路径,只要上下文确定就可以读取到Dockerfile。
build: ./dir
build:
context: ./
dockerfile: compose/build/dir/Dockerfile
context 上下文路径,可以是文件路径,也可以是到链接到 git 仓库的 url。当是相对路径时,它被解释为相对于 Compose 文件的位置。
dockerfile 指定构建镜像的 Dockerfile 文件名
args 构建参数,只能在构建过程中访问的环境变量
cache_from 缓存解析镜像列表
labels 设置构建镜像的元数据
network 设置网络容器连接,none 表示在构建期间禁用网络
shm_size 设置/dev/shm此构建容器的分区大小
target 多阶段构建,可以指定构建哪一层
2.3.2.1、context
context选项可以是Dockerfile的文件路径,也可以是到链接到git仓库的url,当提供的值是相对路径时,被解析为相对于撰写文件的路径,此目录也是发送到Docker守护进程的context
build:
context: ./dir
2.3.2.2、dockerfile
使用dockerfile文件来构建,必须指定构建路径
build:
context: .
dockerfile: Dockerfile-alternate
2.3.3、command
用于覆盖 Dockerfile 中的 CMD 指令内容,即启动该服务容器后立即运行的命令。如果 直接按照Dockerfile中的CMD指令内容执行即可,则compose文件中无需该command属性。
单行
command: tail -f /etc/hosts
多行一
command:
sh -c "nginx -t &&
nginx -g 'daemon off;'"
多行二
command:
- /bin/bash
- -c
- |
nginx -t
nginx -g "daemon off;"
2.3.4、container_name
Compose的容器名称格式是:<项目名称><服务名称><序号>
可以自定义项目名称、服务名称,但如果想完全控制容器的命名,可以使用标签指定:
container_name: web01_c1 //容器名称
2.3.5、depends_on
在使用Compose时,最大的好处就是少打启动命令,但一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没启动数据库容器的时候启动应用容器,应用容器会因为找不到数据库而退出。depends_on标签用于解决容器的依赖、启动先后的问题
version: '3'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
2.3.6、ports
一个列表。前面为暴露出的端口号,后面为容器中应用的端口号。如果仅设置了一个端 口号,那么这个端口号是容器中应用的端口号,其暴露到宿主机的端口号会被随机分配。
ports:
- 80:80 # 绑定容器的 80 端口到主机的 80 端口
- 9000:80 # 绑定容器的 80 端口到主机的 9000 端口
- "127.0.0.1:8001:8001" #绑定容器8001端口只能本地访问
- 443 # 绑定容器的 443 端口到主机的任意端口,容器启动时随机分配绑定的主机端口号
2.3.7、extra_hosts
添加主机名的标签,会在/etc/hosts文件中添加一些记录。
extra_hosts:
- "db1host:192.168.1.126"
- "db2host:192.168.1.211"
启动后查看容器内部hosts:
192.168.1.126 db1host
192.168.1.211 db2host
2.3.8、dns
自定义DNS服务器。可以是一个值,也可以是一个列表。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 114.114.114.114
2.3.8、expose
暴露端口,但不映射到宿主机,只允许能被连接的服务访问。仅可以指定内部端口为参数,如下所示:
expose:
- "3000"
- "8000"
2.3.9、links
链接到其它服务中的容器。使用服务名称(同时作为别名),或者服务名称:服务别名(如 SERVICE:ALIAS)
links:
- db
- db:database
- redis
2.3.10、PID
将PID模式设置为主机PID模式,跟主机系统共享进程命名空间。容器使用pid标签将能够访问和操纵其他容器和宿主机的名称空间。
pid: "host"
2.3.11、external_links
链接到 docker-compose.yml 外部的容器,甚至 并非 Compose 管理的容器。参数格式跟 links 类似。
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
2.3.12、environment
设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取它在 Compose 主机上的值,可以用来防止泄露不必要的数据。
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
2.3.13、env_file
从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过 docker-compose -f FILE 指定了模板文件,则 env_file 中路径会基于模板文件路径。
如果有变量名称与 environment 指令冲突,则以后者为准。
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
环境变量文件中每一行必须符合格式,支持 # 开头的注释行。
# common.env: Set Rails/Rack environment
RACK_ENV=development
2.3.15、extends
基于已有的服务进行扩展。例如我们已经有了一个 webapp 服务,模板文件为 common.yml。yaml资源复用
# development.yml
web:
extends:
file: common.yml
service: webapp
ports:
- "8000:8000"
links:
- db
environment:
- DEBUG=true
db:
image: postgres
后者会自动继承 common.yml 中的 webapp 服务及相关环节变量。
2.3.16、deploy
用于指定当前服务容器的部署设置。其下有一个常用属性 replicas,用于指定该服务启 动的容器的数量。即实现一个服务多个容器。一旦指定了 deploy:replicas,就不能再指定 container_name 属性了。因为各个启动的容器名称不能相同,而只能由系统自动生成.
services:
frontend:
image: awesome/webapp
deploy:
mode: replicated
replicas: 6
2.3.17、restart
重启策略
no在任何情况下都不会重启容器。当always指定时,容器总是重新启动。on-failure如果退出代码指示失败错误,则该策略会重新启动容器。unless-stopped总是重新启动容器,除非容器停止(手动或其他方式)。
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
2.3.18、sysctls
在容器中设置的内核参数,可以为数组或字典
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
2.3.19、tmpfs
在容器内挂载一个临时文件系统。可以是单个值或列表。
tmpfs: /run
tmpfs:
- /run
- /tmp
2.3.20、userns_mode
如果 Docker 守护程序配置了用户命名空间,则禁用此服务的用户命名空间。
userns_mode: "host"
2.3.21、ulimits
设置当前进程以及其子进程的资源使用量,覆盖容器的默认限制,可以单一地将限制值设为一个整数,也可以将soft/hard限制指定为映射
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
2.3.22、stop_grace_period
指定在尝试停止容器时等待多长时间。
在docker stop命令执行的时候,会先向容器中的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行。如果等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行kill掉进程。
在容器中的应用程序,可以选择忽略和不处理SIGTERM信号,不过一旦达到超时时间,程序就会被系统强行kill掉,因为SIGKILL信号是直接发往系统内核的,应用程序没有机会去处理它。
stop_grace_period: 1s
2.3.23、security_opt
为每个容器覆盖默认的标签。简单说来就是管理全部服务的标签,比如设置全部服务的 user 标签值为USER
security_opt:
- label:user:USER
- label:role:ROLE
2.3.24、logging
日志记录配置。
version: "3.9"
services:
some-service:
image: some-service
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
network_mode
2.3.25、labels
使用 Docker 标签将元数据添加到容器,可以使用数组或字典。与 Dockerfile 中的LABELS类似:
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: ""
2.3.26、init
在容器内运行一个 init 来转发信号和取得进程。将此选项设置true为服务启用此功能。
version: "3.9"
services:
web:
image: alpine:latest
init: true
2.3.27、healthcheck
配置运行的检查以确定此服务的容器是否“健康”。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
2.3.27、entrypoint
在 Dockerfile 中有一个指令叫做ENTRYPOINT指令,用于运行程序。在docker-compose.yml中可以定义覆盖 Dockerfile 中定义的 entrypoint:
entrypoint: /code/entrypoint.sh
entrypoint: ["php", "-d", "memory_limit=-1", "vendor/bin/phpunit"]
2.3.28、configs
为每个服务赋予相应的configs访问权限
简短语法,指定配置名称即可。以下示例授予redis服务访问my_config和my_other_configconfigs 的权限。
version: "3.9"
services:
redis:
image: redis:latest
deploy:
replicas: 1
configs:
- my_config
- my_other_config
configs:
my_config:
file: ./my_config.txt
my_other_config:
external: true
长语法
source:配置名称
target:要挂载文件的路径和名称
uid和gid:容器的数字 UID 或 GID
mode:挂载在服务的任务容器中的文件的权限,以八进制表示。例如,0444 代表可读。
以下示例在容器内设置configs名称为my_config ,路径为redis_config,将模式设置为0440(组可读)并将用户和组设置为103。该redis服务无权访问my_other_config配置。
version: "3.9"
services:
redis:
image: redis:latest
deploy:
replicas: 1
configs:
- source: my_config
target: /redis_config
uid: '103'
gid: '103'
mode: 0440
configs:
my_config:
file: ./my_config.txt
my_other_config:
external: true
一级configs详细配置:
file: 使用指定路径中的文件内容创建配置。
external: 如果设置为 true,则指定此配置已经创建。Docker 不会尝试创建它,如果它不存在, 会报错config not found。
name: Docker 中配置对象的名称。此字段可用于引用包含特殊字符的配置。
driver和driver_opts:自定义驱动程序的名称,以及作为键/值对传递的特定于驱动程序的选项。
template_driver:要使用的模板驱动程序的名称,它控制是否以及如何将配置负载作为模板。如果未设置驱动程序,则不使用模板。当前支持的唯一驱动程序是golang,它使用golang。
在下面例子中,my_first_config是通过confif_data文件内容创建的(就像 <stack_name>_my_first_config)部署堆栈时一样,并且my_second_config已经创建过。
configs:
my_first_config:
file: ./config_data
my_second_config:
external: true
当 Docker 中的配置名称与服务中存在的名称不同时,可以使用name进行配置。
configs:
my_first_config:
file: ./config_data
my_second_config:
external:
name: redis_config
2.3.29、volumes
卷挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
2.3.30、volumes_from
从另一个服务或容器挂载它的所有卷。
volumes_from:
- service_name
- container_name
2.4、networks段
networks 下的第一级属性—网络名称,并不是真正的网络名称,而仅仅是网络名称的一 部分。在真正生成网络后,其真正的网络名称格式为:当前 compose 文件所在目录名_ networks 下的第一级属性。 但如果设置了name属性,则网络名称即为这里指定的名称,不会出现名称再合成情况。
一级networks还有如下这些配置:
driver 指定该网络应使用哪个驱动程序。默认使用bridge单个主机上的网络,overlay代表跨多个节点的网络群
driver: overlay
host or none 使用主机的网络堆栈,或者不使用网络。相当于docker run --net=host或docker run --net=none。仅在使用docker stack命令时使用。如果您使用该docker-compose命令,请改用 network_mode。
driver_opts 将选项列表指定为键值对以传递给此网络的驱动程序
driver_opts:
foo: "bar"
baz: 1
attachable 仅在driver设置为 overlay时可用。如果设置为true,那么除了服务之外,独立容器也可以连接到此网络。
networks:
mynet1:
driver: overlay
attachable: true
enable_ipv6 在此网络上启用 IPv6 网络。
ipam 自定义 IPAM (IP地址管理)配置。
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
internal 默认情况下,Docker 会将桥接网络连接到它提供外部连接。如果要创建外部隔离的覆盖网络,可以将此选项设置为true。
labels 添加元数据
将元数据以标签的形式添加到容器中。可以使用数组或字典两种格式
labels:
com.example.description: "Financial transaction network"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Financial transaction network"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
external如果设置为true,则指定此网络是在 Compose 之外创建的。docker-compose up不会尝试创建它,如果它不存在,则会引发错误。在下面的例子中,proxy是通往外界的门户。
version: "3.9"
services:
proxy:
build: ./proxy
networks:
- outside
- default
app:
build: ./app
networks:
- default
networks:
outside:
external: true
name为此网络设置自定义名称。
version: "3.9"
networks:
network1:
name: my-app-net
name为该网络设置一个自定义名称。
version: "3.8"
networks:
network1:
name: my-app-net
可以和external配置项一起使用
version: "3.8"
networks:
network1:
external: true
name: my-app-net
2.4.1、net
设置网络模式。
net: "bridge"
net: "none"
net: "host"
2.4.2、driver
用于指定网络驱动,缺省驱动为 Bridge。
services:
app:
networks:
- app_bridge: #这里使用的并不是网络名称
networks:
app_bridge:
name: appBGnet # 这才是网络名称
driver: bridge
2.4.3、attachable
如果该属性设置为 true,则除了当前 compose 中定义的服务外,其它独立容器也可以 连接到此网络,并能与该网络中的服务及也连接到该网络的其它独立容器通信。缺省状态为 false。
2.4.4、network_mode
网络模式。使用与 docker 客户端–network相同,可以使用特殊形式service:[service name]。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
2.5、volumes段
2.5.1、driver
指定该数据卷所要使用的数据卷驱动。默认为Docker Engine中配置使用的无论哪种驱动,大多数情况下为local驱动。如果驱动不可用,则引擎会在docker-compose up尝试创建数据卷时返回一个错误.
driver: foobar
2.5.2、driver_opts
以键值对的形式指定用来传递给该数据卷所使用的数据卷驱动的列表选项。这些选项取决于数据卷驱动
volumes:
example:
driver_opts:
type: "nfs"
o: "addr=10.40.0.199,nolock,soft,rw"
device: ":/docker/example"
2.5.3、external
指定该数据卷是否是外部数据卷。如果设置为true,则指定该数据卷是在Compose外部创建的。由于docker-compose up不会尝试创建该数据卷,如果该数据卷不存在则会引发错误。在3.3及以下版本的Compose配置文件格式中,external配置项不能与包括driver、driver_opts和labels在内的其他数据卷配置项同时使用,在3.4及以上版本中则没有此限制。例如以下示例,Compose不会尝试创建一个名为[projectname]_data的数据卷,而是查找一个现存的被简单称为data的数据卷并将其挂载到db服务的容器中:
version: "3.8"
services:
db:
image: postgres
volumes:
- data:/var/lib/postgresql/data
volumes:
data:
external: true
通过external配置项下的name配置项可以指定数据卷的名称,该名称与Compose配置文件中用于引用数据卷的名称区分开来。例如:
volumes:
data:
external:
name: actual-name-of-volume
2.5.4、labels
将元数据以标签的形式添加到容器中。可以使用数组或字典两种格式。例如:
labels:
com.example.description: "Database volume"
com.example.department: "IT/Ops"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Database volume"
- "com.example.department=IT/Ops"
- "com.example.label-with-empty-value"
2.5.5、name
为该数据卷设置一个自定义名称。例如:
version: "3.8"
volumes:
data:
name: my-app-data
可以和external配置项一起使用。例如:
version: "3.8"
volumes:
data:
external: true
name: my-app-data
3、参考配置文件
version:"3" //指定compose版本,最好是3.0以上版本
services: //配置服务(容器)
httpd: //配置服务标识(唯一编号)
container_name: xxx //容器名称
image: httpd //配置容器镜像
build: //build和image二选一
context: . //上下文路径
dockerfile: Dockerfile
depends_on: //容器启动顺序,该容器依赖某个容器
- xxx
expose: //容器开放端口
- 80
ports: //配置容器映射端口号[数组]
- 80:80
volumes: //配置挂载卷
- db_data:/var/www/html
networks: //配置容器网络[数组]
- httpd_net //网络名称
privileged:"true"
command: xxxx //覆盖容器启动后默认执行的命令
entrypoint:xxxx //覆盖容器启动后默认执行的命令
networks: //为网络指定配置
httpd_net: //配置网络名称
driver: bridge //网络类型
volumes: //为卷指定配置
db_data:
driver: local