一、简介
在Harbor安装章节,大家应该注意到我们使用了docker-compose这个命令,其实在将harbor安装包解压后,运行install.sh,会生成一个docker-compose.yml的文件,其实我们就是根据这个文件来部署harbor的。通过这个文件,docker-compose这个命令能够很方便的对harbor所需要的容器进行启动、停止、重启甚至删除。可以看到,这个yml文件还是很有用的,当在宿主机启动较多的容器时候,如果都是手动操作会觉得比较麻烦而且容易出错,此时可以考虑使用docker 单机编排工具 docker-compose,能够很方便的对要启动的容器进行配置管理。下面我将逐个解析一下docker-compose.yml这个文件中的配置语法,在了解之后,我们自己也能改进自己的一些服务部署方式。

二、安装
1、通过pip安装

[root@k8s-m1 ~]# yum -y install epel-release
[root@k8s-m1 ~]# yum -y install python-pip
[root@k8s-m1 ~]# pip install docker-compose
[root@k8s-m1 ~]# docker-compose --version
#不同环境可能有点区别,正确安装即可

2、从github上下载所需版本安装包
github地址:参看说明:https://github.com/docker/compose/releases

[root@k8s-m1 ~]# wget https://github.com/docker/compose/releases/download/v2.18.1/docker-compose-linux-x86_64
[root@k8s-m1 ~]# mv docker-compose-linux-x86_64 /usr/bin/docker-compose
[root@k8s-m1 ~]# chmod +x  /usr/bin/docker-compose

3、直接通过yum安装
此方法安装的版本较旧,不推荐使用

#CentOS7安装,依赖EPEL源
[root@k8s-m1 ~]# yum -y install docker-compose
##docker-compose帮助信息
[root@k8s-m1 ~]# docker-compose --help

docker compse文件格式
官方文档:https://docs.docker.com/compose/compose-file/

docker compose文件是一个yaml格式的文件,所以注意行首的缩进很严格

默认docker-compose命令会调用当前目录下的docker-compose.yml的文件,因此一般执行docker-compose命令前先进入docker-compose.yml文件所在目录

docker compose文件的格式很不同版本,版本不同,语法和格式有所不同,参看以下列表
具体参考官方文档https://docs.docker.com/compose/compose-file/compose-versioning/

Compose file format

Docker Engine release

Compose file format Docker Engine release

Compose specification 19.03.0+

3.8 19.03.0+

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+

三、重要语法详解
version
version用来表示Compose配置文件语法版本,目前为止语法有3个版本,分别为1, 2.x 和 3.x。目前最新的为 3.x版本, 通过过上表可以看到其与docker 1.13.0 及其以上的版本兼容。docker2.x版本的语法仍然在使用中,其与3.x语法并无太大的差异,但能匹配使用的docker版本就比较低,推荐使用较高版本。

version: '2.3'
services:
  log:
    image: goharbor/harbor-log:v2.8.1
    container_name: harbor-log
    restart: always

service
service 相关的用于定义一个服务,如上面定义了一个服务名为log的服务,具体为:
image:log服务使用的docker镜像是goharbor/harbor-log:v2.8.1
container_name:log服务对应的容器名称设置为harbor-log
restart:log服务的重启策略是always

cap_add && cap_drop

cap_drop:
  - ALL
cap_add:
  - CHOWN
  - DAC_OVERRIDE
  - SETGID
  - SETUID

这两参数都是用于安全方面的设置,cap_drop ALL用于设置去掉容器操作linux内核的作用,
cap_add 用于为容器添加某些所需的作用,CHOWN修改文件属主的功能;SETGID(SETUID)设置用户组ID、用户ID的功能;DAC_OVERRIDE权限更大,包含用户、用户组、ACL操作权限。
这部分用于调整容器操作内核权限、能力的配置。在v3版本中有一点点变化,就是在docker swarm 模式中,Compose 会忽略这部分参数的值。

volumes
volumes用于定义数据卷,将主机的数据卷或着文件挂载到容器里。

volumes:
  - /var/log/harbor/:/var/log/docker/:z
  - type: bind
    source: ./common/config/log/logrotate.conf
    target: /etc/logrotate.d/logrotate.conf
  - type: bind
    source: ./common/config/log/rsyslog_docker.conf
    target: /etc/rsyslog.d/rsyslog_docker.conf

需要注意的是:z(小z)表示数据卷的内容可以在容器之间共享,如果是:Z(大Z)表示数据卷是该容器私有的。

ports
ports用于容器与宿主机之间的端口映射,冒号前面是宿主机端口,冒号后面是容器端口(暴露给宿主机上的其他进程或容器)。

ports:
  - 127.0.0.1:1514:10514

如果宿主机有多网卡多IP、可以指定映射的ip。映射到127.0.0.1可以避免暴露到外网,在宿主机范围内暴露端口。

networks
用于定义网络,配置容器连接的网络,sevices下的networks表明该服务所在的容器使用哪个网络。同一网络名下的容器能够互联

networks:
  - harbor:
......
networks:
  harbor:
    external: false

如上所示定义使用网络harbor,external: false是否使用外部网络, 表示使用harbor这个网络,如果harbor这个网络不存在则新建该网络。external: true则docker-compose up不会尝试新建网络,而是使用已经存在的网络(需要自己事先将网络创建好),网络不存在就报错。

depends_on
设置依赖关系。
按依赖性顺序启动服务。文示例的depends_on表示registry容器需要在log服务对应的容器启动之后才能启动,用于控制服务之间依赖关系及容器启动顺序。

depends_on:
  - log

logging
服务的日志记录配置。registry服务将自己的syslog日志发送到tcp://localhost:1514(也就是上面的log服务容器),并为日志打上标签registry。

logging:
  driver: "syslog"
  options:
    syslog-address: "tcp://localhost:1514"
    tag: "registry"

目前支持三种日志驱动类型,在linux操作系统/var/log下面的那些日志文件,基本都属于syslog。
driver: “json-file”
driver: “syslog”
driver: “none”

env_file
从文件添加环境变量。可以是单个值或列表的多个值。下文中的env_file表示在docker-compose.yml同级目录下的common/config/core/env有一个文件叫做env,里面包含该容器需要的一些环境变量。当所需的变量很多的时候可以选择此种方式,不然就可以选择下面的直接通过environment设置。

env_file:
  - ./common/config/core/env

大家可以看看每个目录的env文件,里面包含很多变量内容设置。

environment
添加环境变量。可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。如:

environment:
  POSTGRES_PASSWORD=root123

shm_size
shm_size创建容器时候指定最小共享内存,对于内存有要求的容器服务需要设置这个值。

logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://localhost:1514"
        tag: "postgresql"
    shm_size: '1gb'

build
指定为构建镜像上下文路径。但一般情况下,本地没有所需的镜像情况下我们都是直接从仓库中拉取镜像。
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:

version: "2.3"
services:
  webapp:
    build: ./dir

command
覆盖容器启动的默认命令。如

command: ["bundle", "exec", "thin", "-p", "3000"]

entrypoint
覆盖容器默认的 entrypoint。
entrypoint: [“/code/entrypoint.sh”]

healthcheck
用于检测 docker 服务是否健康运行,用法和前面章节分享的docker服务健康检查一样。

healthcheck:
  test: ["CMD","curl", "-fs", "http://localhost"] # 设置检测程序
  interval: 30s # 设置检测间隔
  timeout: 10s # 设置检测超时时间
  retries: 3 # 设置重试次数
  start_period: 40s # 启动后,多少秒开始启动检测程序

更多参数,如ulimits、sysctls、secret、dns、dns_search等等都是可以设置的,大家可以根据实际需要编写。

v3和v2版本的区别总结
由于 Swarm mode 中网络的特殊性,Compose v3版本配置文件中一些声明比如expose和links会被忽略。注意:不能再使用 link 定义的网络别名来进行容器互联,可以使用服务名连接。
Compose v3版本配置文件中volumes_from不再支持,只能使用命名数据卷来实现容器数据的持久化和共享。
Compose v3版本配置文件中引入了deploy指令,可对Swarm mode中服务部署的进行细粒度控制,包括
resources:定义cpu_shares,cpu_quota,cpuset,mem_limit,memswap_limit等容器资源限制指令。(v1/v2中相应指令在v3版本的配置文件中不再被支持)
restart_policy:定义服务的重启条件 (v1/v2中restart指令在v3版本的配置文件中不再被支持)

四、Docker-compose常用命令
docker-compose命令需要根据docker-compose.yml文件执行相关命令。执行命令前要么先直接进入到含有docker-compose.yml文件的目录,要么通过-f 选项指定,不然会报错。如下:

[root@k8s-m1 ~]# docker-compose  -f /root/registry/harbor/harbor/docker-compose.yml  ps

##更多命令可以通过docker-compose --help查看

命令

描述

build

构建或重新构建服务

create

创建服务

ps

列出容器

up

创建和启动容器

exec

在运行的容器里面执行命令

scale

指定一个服务容器启动数量

top

显示正在运行的容器进程

logs

查看服务容器的输出

down

删除容器、网络、数据卷和镜像

stop/start/restart

停止/启动/重启服务

rm

删除一个停止的容器

五、实例
简单以redis服务为例,使用docker-compose部署redis。注意不同版本的语法有不同之处,不匹配的话是不能正常启动的。
[root@k8s-m1 compose-test]# cat docker-compose.yml

# yaml 配置实例
version: '3'
services:
  redis:
    image: redis:7.0.11
    container_name: redis-test
    ports:
      - "127.0.0.1:6379:6379"
    volumes:
      - ./redis.conf:/usr/local/redis/conf/redis.conf
##该redis镜像是用的是前面章节通过dockerfile制作的镜像
[root@k8s-m1 compose-test]# redis-cli 
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379>