DockerCompose笔记

背景

看了docker大概教程之后.会有感觉,就这?
和实际开发中使用感觉相去甚远.
遂看相关的docker compose.

介绍

Docker-Compose是Docker官方的开源项目,
负责对Docker容器集群的快速编排.
(本质上是把需要在命令行中执行的多条命令放在一个文件中,
甚至低级一些,写一个脚本,定义好各种函数和操作也可以实现同样效果)

而docker-compose则使用了特别的yaml语法,(配置文件名为docker-compose.yml)
相比shell脚本

  • 更加容易理解
  • 可以省去许多重复的代码
  • 方便管理依赖关系(决定谁先启动谁后启动)

只不过似乎yaml的标准一直没有明确标准,语法版本也在一升再升(版本一览).

使用GUI方式来完成规则控制也可以,只不过GUI和版本管理的天然冲突谁来解决呢.

容器管理的层次

为了方便管理,抽象出了不同的层次

  • project
  • service
  • container

project

运行目录下的所有文件

  • docker-compose.yaml,
  • extends文件
  • 环境变量文件等

组成一个工程

service

一个工程中可包含多个服务
一个服务中定义了要运行的容器的镜像,参数,依赖

使用举例

比如要使用WordPress和MySQL这两个docker来启动一个静态网页服务,
使用命令行的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
docker container run \
-d \
--rm \
--name wordpressdb \
--env MYSQL_ROOT_PASSWORD=123456 \ # 定义数据库root用户的密码
--env MYSQL_DATABASE=wordpress \ # 定义好数据库名
mysql:5.7; # 使用mysql官方5.7版本的docker镜像

docker container run \
-d \
--rm \
--name wordpress \
--env WORDPRESS_DB_PASSWORD=123456 \ # 定义连接数据库的参数
--link wordpressdb:mysql \ # link表示要连接的docker名为wordpressdb,连接方式是mysql
-v wordpress:/var/www/html \ # 将本地wordpress文件夹下的html网页共享至docker中WordPress的工作目录
wordpress; # 使用wordpress官方的docker镜像

等效的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
services:
mysql: # 名为mysql的service
image: mysql:5.7 # image 指定镜像
environment: # 相当于docker run的 -e 参数
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
web: # 名为web的服务
image: wordpress # 指定镜像
links:
- mysql # 相当于docker run的 --link 参数
environment:
- WORDPRESS_DB_PASSWORD=123456
ports: # 相当于使用 -p 127.0.0.3:8080:80
- "127.0.0.3:8080:80"
working_dir: /var/www/html # 相当于使用 run cd /var/www/html
volumes:
- wordpress:/var/www/html # 相当于 -v ./wordpress:/var/www/html

使用

1
2
3
4
docker-compose up -d # 创建并启动这些containers,-d与docker run的-d相同含义
docker-compose down # 会自动删除这些containers
docker-compose stop # 停止
docker-compose start # 启动containers

其他配置和说明

样例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# yaml 配置实例
version: '3' # 指定docker-compose配置文件语法版本,目前最新到3.9
services:
web:
build: . # 除了直接使用某个镜像,还可能会自己build,要求项目里有Dockerfile,build出的image会有默认名字,文件夹名_service名
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes: # 暂时不清楚含义
logvolume01: {}

接下来主要写一些与build同级的配置项

build

除了指定一个 ., build还可以继续补充说明

1
2
3
4
5
6
7
8
9
10
build:
context: ./dir # 指定上下文路径
dockerfile: Dockerfile-alternate # 指定Dockerfile名
args: # 可能在Dockerfile中使用了一个名为buildno的变量
buildno: 1
labels: # 覆盖Dockerfile中内容?
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
target: prod # 多层构建?

command

用来覆盖容器启动的默认命令

container~name~

指定启动后容器的名称

depends~on~

用于指定依赖关系,
被依赖的,更底层一些的项目会

  • 先启动
  • 最后停止
1
2
3
4
5
6
7
8
9
10
11
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres

比如这里的web服务,依赖db和redis,就要求db和redis首先启动.

expose

暴露端口,但不被宿主机访问,只供被连接的服务访问

env~file~

用于指定环境变量文件,可以是一个,可以是多个

logging

日志记录配置

1
2
3
4
5
6
7
8
9
10
logging:
driver: json-file # 可选 json-file, syslog, none
options:
max-size: "200k" # 单个文件大小为200k
max-file: "10" # 最多10个文件

logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"

restart

重启策略,如果遇错或其他原因关闭了,是否需要重启

  • no 不要重启
  • always 总要重启
  • on-failure 非正常退出时重启
  • unless-stopped 如果手动关闭就不重启,其他情况重启

TODO secrets

存储敏感数据

1
2
3
4
5
6
7
8
9
10
11
12
13
version: "3.1"
services:

mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret # 变量使用?
secrets:
- my_secret # 变量声明?

secrets:
my_secret:
file: ./my_secret.txt # 变量赋值?

TODO 部署相关

deploy与build同级,但设置项比较多.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3.7"
services:
redis:
image: redis:alpine
deploy:
mode: replicated
replicas: 6
endpoint_mode: dnsrr
labels:
description: "This redis service label"
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s

TODO mode

服务提供的模式,可选

  • replicated 复制
  • global 全局

?

replicas

mode为replicated时,指定节点数量

endpoint~mode~

访问集群服务的方式

  • vip,集群对外有个虚拟的ip,所有的请求通过虚拟的ip到达集群
  • dnsrr,轮询,请求会轮询集群的ip列表

labels

为服务设置标签,
怎么用?

resources

配置资源限制,reservations表示预留,或者说最低?limits表示最大使用
可以配置cpus(没有用百分制单位),和memory

restart~policy~

下属还有具体配置

  1. condition

    • none
    • on-failure
    • any(默认值)
  2. delay

    默认值0,立即重启

  3. max~attempts~

    默认一直重试

  4. window

    重启超时时间,默认0

rollback~config~

更新失败后如何回滚服务

  1. parallelism

    一次回滚的容器数,如果为0表示全部.

  2. delay

    容器组回滚之间的等待时间,默认0s

  3. failure~action~

    回滚失败策略

    • continue 假装没有发生
    • pause 停下(默认值)
  4. monitor

    更新后观察是否成功的观察期,默认0s

  5. max~failureratio~

    回滚期间容忍的故障率,默认为0

  6. order

    回滚顺序策略

    • stop-first 串行回滚(默认值)
    • start-first 并行回滚

update~config~

如何更新服务

  1. parallelism

    一次更新的容器数,设置为0表示全部,设置为10表示每次10个直到完成

  2. delay

  3. failure~action~

  4. monitor

  5. max~failureratio~

  6. order

其他

devices

dns

extra~hosts~

entrypoint

healthcheck

network~mode~

security~opt~

stop~graceperiod~

stop~signal~

sysctls

tmpfs

ulimits

感受

没有使用过集群做过实际操作,要理解真的比较难

参考

  1. 知乎的介绍
  2. 阮一峰关于使用多个docker的介绍
  3. 菜鸟,出奇得有现实意义