Docker-Compose学习笔记

  • Buddy-Deus
  • December 13, 2019
  1. 1. 概述
  2. 2. YML配置
    1. 2.1. 字节
    2. 2.2. 时间
    3. 2.3. version & 配置版本
    4. 2.4. networks & 网络配置
    5. 2.5. volumes & 挂载配置
    6. 2.6. services & 服务配置
    7. 2.7. services build、deploy & 服务配置 build、delploy
      1. 2.7.1. build & 构建打包
      2. 2.7.2. deploy & 部署
  3. 3. 命令操作
    1. 3.1. 启动与卸载
    2. 3.2. 构建、启动、重启、停止
    3. 3.3. 系统部署
  4. 4. 常用配置

最近在学习k8s,生生感受到k8s那种生产环境的严谨和扩容性。但反过来想了下对于小规模环境k8s显得太重了,所以重新学习了下docker-compose,特此记录下。

在现版本中docker的stack功能以兼容docker-compose功能,以下内容在不安装docker-compose时同样可以使用

概述

docker-compose是docker的一个命令行工具,通过yml配置文件,进行一键式的项目部署,并支持依赖检测等功能。

docker-compose只是一个命令行工具,所以必须手动安装docker环境,才可以确保运行正常

其主要分成两部分,yml配置、命令操作。总体来说使用非常简单

这里不得不吐槽下,docker项目组肯定对于docker-compose没有投入太多的维护经历,官方文档系统对于常用的 servicesservices.build 配置说的还是清楚的,但对于扩展配置 networksvolumes 这些就说的非常含糊。

YML配置

yml配置是整个docker-compose的核心

但他只是一个配置文件,所以可以放在任意一个地方,文件名随意,在命令操作有讲解如何引用。

个人建议,将yml配置文件 放在一个固定的地方比如:/data/docker/docker-compose.yml

1
2
3
4
5
6
7
version: "3.7"
networks:
netName:
volumes:
volumeName:
services:
svrName:

这就是整个配置文件的1、2级配置结构,你必须遵循这个结构,否则会运行失败

这里特别提醒下,yml语法特性(其实是解释器识别能力较弱),决定了所有的缩进必须遵循同一个规则,比如svrName的缩进用了1个tab,name下面netName也必须用1个tab,而不能改成2个空格,否则会造成block闭合失败。

对于yml来说,所有的配置就是键值对。具体使用中对于不希望更改对象配置的,可以使用数组方式指向。对于需要更改的内容通过键值对

字节

配置中会使用到内存、磁盘、数据量等容量单位,默认为 b

时间

配置中会使用到时间单位,默认为 s

version & 配置版本

version用于指示配置文件所套用的版本号,参照标准是docker的版本

1
2
$ docker -v
Docker version 19.03.2, build 6a30dfc
Version Code Docker Engine release
3.7 18.06.0+
3.6 18.02.0+
3.5 17.12.0+
3.4 17.09.0+
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.4 17.12.0+
2.3 17.06.0+
2.2 1.13.0+
2.1 1.12.0+
2.0 1.10.0+
1.0 1.9.1.+

基本上现在docker-ce的版本在18以上。所以,放心的使用3.7吧,如果用老版本docker的话,请自行选择。

大部分教程都会从 services 开始说,但我觉得 networksvolumes 属于全局性的功能配置,会对 services 中的配置造成一定影响,所以先行说明。

除了 version 必须是第一个 networksvolumesservices 顺序没有严格要求。

networks & 网络配置

这个配置项对应了 docker network create [OPTIONS] 命令中的内容,可以用于创建私有网络。

networks 的配置,作用于整个docker全局,所以可以用于一键化项目部署。

在docker-compose起效时都会存在。手动 docker run --net 方式同样可以使用创建的网络
但同时,当docker-compose被终止时,创建的网络会被删除,引用网络的容器会造成异常

注意:networks必然会创建一个网络,所以名称不允许重复(包括已创建网络,指的是name字段)

1
2
3
4
5
6
7
8
networks:
netName:
name: net
driver: bridge
ipam:
driver: default
config:
- subnet: 100.0.0.0/16

以上是我常用的配置方式,如果转换成docker命令的话就是:docker network create --driver bridge --subnet=100.0.0.0/16 net

这里特别需要注意 netName 这个是关联名称,在 services 配置中需要用到,但也只是在yml配置中才有效

docker环境中有效的是 name 字段的内容

建议把这两个用同一个名称便于管理,但(bridge、host、null、none)这几个名字属于保留字,不允许使用

networks 配置下面还有很多的配置,但针对小范围使用来说,基本没用。

volumes & 挂载配置

这个配置对应了 docker volume create [OPTIONS] 命令中的内容,可以用于创建全局性的挂载目录或磁盘。

限制与 networks 配置一致

挂载的机制是通过类似ln的方式进行目录引用,在linux环境中类似mount效果,windows环境中类似共享连接配置

1
2
3
4
volumes:
volumeName:
external:
name: data

services & 服务配置

这个配置对应了 docker run [OPTIONS] 命令中的内容,用于部署具体容器(包括打包)

在看具体配置说明前,要先明确两点

1、services下的内容,可以简单的理解成容器,但本质上是一种服务配置,即它可以用于多个容器的管理/分配或参与一个服务的整个生命周期(构建、运行、部署、销毁)

2、services下的内容,不存在运行的先后顺序,他们是并行执行的,即不存在svrName1启动后再启动svrName2,svrName1和svrName2是同时被启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
services:
svrName:
container_name: redis
image: redis:alpine
command: redis-server --appendonly yes
restart: always
environment:
SHOW: 'true'
networks:
- net
volumes:
- /data/docker/redis:/data
ports:
- 6372:6372
depends_on:
- mongodb

这是一段标准的redis部署配置(depends_on除外)

所对应的docker命令为:docker run --net net --name redis -d -v /data/docker/redis:/data -p 6372:6372 redis:alpine redis-server --appendonly yes

在services章节,我这里少写了很多配置,比如:linksexposeinitlabels 诸如此类的,这些并不是无效,但在时间过程中作用有限,有兴趣的可以自行学习


services build、deploy & 服务配置 build、delploy

之前说过services不仅仅是个容器配置,而是参与了服务的整个生命周期,而这就依赖于 builddeploy 配置来实现。

这两个配置相对独立,分别对应了服务的构建(打包)、部署阶段

build & 构建打包

对应了 docker build [OPTIONS] 命令

build的所有配置在docker stack状态下是被忽略的!

1
2
3
4
5
6
7
8
services:
svrName:
build:
context: ./dir
dockerfile: Dockerfile
image: imgName:tag
args:
buildno: 1

deploy & 部署

deploy是个特殊的配置,它只在docker stack状态下工作,docker-compose时被忽略

这里不得不说一下docker stack是什么。简单的说,它是一个被docker吸收为内部功能的py脚本。

常用于集群部署(在之后会单独讲下docker集群,主要是对这块知识我还没有学透),是docker生产环境下的一个非常好用的模式,天生带负载均衡。

我们可以简单的认为docker run用于开发环境/单机环境,docker stack用于生产环境/集群环境(分布式环境)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
services:
svrName:
image: redis:alpine
deploy:
mode: global
replicas: 6
resources:
limits:
cpus: '0.5'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 0
max_attempts: 0
rollback_config:
parallelism: 0
delay: 0
failure_action: pause
max_failure_ratio: 0
order: stop-first
update_config:
parallelism: 2
delay: 10s

deploy 必须指定一个image,因为docker stack会忽略build配置,所以必须制定一个存在的image作为内容

update_configrollback_config 常联合适用,独立对应 docker service 命令

它们的生效场景在于服务已经存在,而需要更新服务镜像的时候,因单独一个配置文件进行操作。

命令操作

docker-compose的命令非常丰富,这里只讲基本的几个

启动与卸载

之前我们讲了大段的YML配置,其实本质上就是docker命令的配置简化,通过 -f 参数进行指向,来加载配置。

构建、启动、重启、停止

针对于已经执行过注册命令后,我们仍然会需要手动操作某些服务的情况。

重要:我们操作的所有内容是针对配置文件中的服务名(svrName),而非容器!!!

至于其他的指令,docker-compose也有支持,不过建议还是用docker本身的比较好

系统部署

开篇我们已经说过docker-compose只是一个命令行工具。因此要自动化使用,只有两种方式

通过这样的方式,就可以完美的运行docker-compose了。

当然,如果使用docker stack方式进行集群部署的话,进行适当的脚本改造也可以满足功能

常用配置

这里提供下常用的几种工具配置。

docker-compose配置路径为 /data/docker/docker-compose.yml

docker工作路径为 /data/docker