> 文档中心 > Docker三剑客之Compose

Docker三剑客之Compose


一、 概述

compose 是用来定义和运行一个或多个容器(通常都是多个)运行和应用的工具。使用 compose 可以简化容器镜像的构建以及容器的运行。

compose 使用 YAML 文件来定义多容器之间的关系。一个 docker-compose up 就可以把完整的应用跑起来。 本质上,compose 把 YAML 文件解析成 docker 命令的参数,然后调用相应的 docker命令行接口,从而将应用以容器化的方式管理起来。它通过解析容器间的依赖关系顺序地启动容器。而容器间的依赖关系由 YAML 文件中的 links标记指定。

二、安装

1)二进制包安装(推荐)

$ curl -L https://github.com/docker/compose/releases/download/1.23.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose$ chmod +x /usr/local/bin/docker-compose$ docker-compose version

在这里插入图片描述
2)pip 安装(安装的是最新稳定版本)

# 环境centos8,先安装python3$ yum -y install python38$ pip3 install docker-compose# 做软链接$ ln -s /usr/bin/docker-compose /usr/local/bin/

三、Compose命令简介

1)常看帮助

docker-compose [COMMAND] --help 或者docker-compose help [COMMAND]

$ docker-compose --help$ docker-compose -h

使用格式

docker-compose [-f …] [–profile …] [options] [–] [COMMAND] [ARGS…]

Options参数选项

-f,--file file指定模板文件,默认是docker-compose.yml模板文件,可以多次指定--profile  启动具有配置文件的服务-p,--project-name name指定项目名称,默认使用所在目录名称作为项目名称--x-networking 使用Docker的后端可插拔网络特性--x-networking-driver driver指定网络的后端驱动,默认使用bridge--verbose 输入更多的调试信息-v,--version 输出版本信息

COMMAND参数详解

buildBuild or rebuild services (构建项目中的服务容器)bundle      Generate a Docker bundle from the Compose file (从Compose文件生成分布式应用程序包)config      Validate and view the Compose file (验证并查看Compose文件)create      Create services (为服务创建容器)down Stop and remove containers, networks, images, and volumes (停止容器并删除由其创建的容器,网络,卷和图像up)events      Receive real time events from containers (为项目中的每个容器流式传输容器事件)exec Execute a command in a running container (这相当于docker exec。使用此子命令,您可以在服务中运行任意命令。默认情况下,命令分配TTY,因此您可以使用命令docker-compose exec web sh来获取交互式提示。)help Get help on a command (获得一个命令的帮助)images      List images ()kill Kill containers (通过发送SIGKILL信号来强制停止服务容器)logs View output from containers (查看服务容器的输出)pausePause services (暂停一个容器)port Print the public port for a port binding (打印某个容器端口所映射的公共端口)ps   List containers (列出项目中目前所有的容器)pull Pull service images (拉取服务依赖镜像)push Push service images (推送服务镜像)restart     Restart services (重启项目中的服务)rm   Remove stopped containers (删除所有停止状态的服务容器)run  Run a one-off command (在指定服务上执行一个命令)scaleSet number of containers for a service (设置指定服务执行的容器个数)startStart services (启动已存在的服务容器)stop Stop services (停止已存在的服务容器)top  Display the running processes (显示容器正在运行的进程)unpause     Unpause services (恢复处于暂停状态的容器)up   Create and start containers (自动完成包括构建镜像、创建服务、启动服务并关联服务相关容器的一系列操作)version     Show the Docker-Compose version information (输出版本)

2)环境变量

COMPOSE_PROJECT_NAME    设置通过 Compose 启动的每一个容器前添加的项目名称,默认是当前工作目录的名字。 COMPOSE_FILE     设置要使用的 docker-compose.yml 的路径。默认路径是当前工作目录。 DOCKER_HOST      设置 Docker daemon 的地址。默认使用 unix:///var/run/docker.sock,与 Docker 客户端采用的默认值一致。 DOCKER_TLS_VERIFY如果设置不为空,则与 Docker daemon 交互通过 TLS 进行。 DOCKER_CERT_PATH 配置 TLS 通信所需要的验证(ca.pem、cert.pem 和 key.pem)文件的路径,默认是 ~/.docker

四、Docker-Compose YAML语法使用说明

  • version

docker-compose文件使用哪个version的file格式

目前有三个版本的 Compose 文件格式1,2.x,3.x。version版本统一用3,其实3是兼容2的,version版本1 就不要考虑了已经废弃了,一定要往前看。

version: '3'
  • build

这个是创建docker镜像时的选项,通过本地的dockerfile来创建,而不是通过image id来pull。

build:  context: ./nginx  # 指定构建镜像的路径  dockerfile: Dockerfile # 选项是备选的dockerfile  args: # 参数设置    - buildno=1    - user=someuser
  • image

生成镜像的ID,指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉去这个镜像。

image: ubuntuimage: orchardup/postgresql
  • links

链接到其它服务中的容器,使一个容器可以主动的去和另外一个容器通讯。使用服务名称(同时作为别名)或服务名称:服务别名 (SERVICE:ALIAS) 格式都可以。

links: - db - db:database - redis

使用的别名将会自动在服务容器中的 /etc/hosts 里创建,相应的环境变量也将被创建。例如

172.17.2.186 db
172.17.2.186 database
172.17.2.187 redis

  • external_links

链接到 docker-compose.yml 外部的容器,甚至 并非 Compose 管理的容器。参数格式跟 links 类似。

external_links: - redis_1 - project_db_1:mysql - project_db_1:postgresql
  • expose

这个是给link用的,将一些端口暴露给link到这个container上的containers。暴露端口,但不映射到宿主机,只被连接的服务访问

expose:    - "3000"    - "8000"
  • ports

暴露端口信息,这个是将端口和本机端口映射的选项,写法如下,其实跟docker -p一样。使用宿主:容器 (HOST:CONTAINER)格式或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

ports:    - "3000"    - "3000-3005"    - "80:80"    - "9090-9091:8080-8081"    - "49100:22"    - "127.0.0.1:8001:8001"    - "127.0.0.1:5000-5010:5000-5010"

注:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 你可能会得到错误得结果,因为 YAML 将会解析 xx:yy 这种数字格式为 60 进制。所以建议采用字符串格式。

  • environment

设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取它在 Compose 主机上的值,可以用来防止泄露不必要的数据。

environment:  RACK_ENV: development  SESSION_SECRET:environment:  - RACK_ENV=development  - SESSION_SECRET
  • env_file

从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过 docker-compose -f FILE 指定了模板文件,则 env_file 中路径会基于模板文件路径。
如果有变量名称与 environment 指令冲突,则以后者为准。

env_file: .envenv_file:  - ./common.env  - ./apps/web.env  - /opt/secrets.env
  • volumes

将本机的文件夹挂载到container中。

volumes:    # Just specify a path and let the Engine create a volume - /var/lib/mysql    # Specify an absolute path mapping - /opt/data:/var/lib/mysql    # User-relative path - ~/configs:/etc/configs/:ro    # Named volume - datavolume:/var/lib/mysql

卷挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)

volumes: - /var/lib/mysql - cache/:/tmp/cache - ~/configs:/etc/configs/:ro
  • volumes_from
    从另一个服务或容器挂载它的所有卷。
volumes_from: - service_name - container_name
  • extends

基于已有的服务进行扩展。例如我们已经有了一个webapp服务,模板文件为 common.yml。

# common.ymlwebapp:  build: ./webapp  environment:    - DEBUG=false    - SEND_EMAILS=false

编写一个新的 development.yml 文件,使用 common.yml 中的 webapp 服务进行扩展。

# development.ymlweb:  extends:    file: common.yml    service: webapp  ports:    - "8000:8000"  links:    - db  environment:    - DEBUG=truedb:  image: postgres

后者会自动继承 common.yml 中的 webapp 服务及相关环节变量。

  • net

设置网络模式。使用和 docker client 的 –net 参数一样的值。

net: "bridge"net: "none"net: "container:[name or id]"
  • pid

跟主机系统共享进程命名空间。打开该选项的容器可以相互通过进程 ID 来访问和操作。

pid: "host"
  • dns

配置 DNS 服务器。可以是一个值,也可以是一个列表。

dns: 8.8.8.8dns:  - 8.8.8.8  - 9.9.9.9
  • cap_add, cap_drop

添加或放弃容器的 Linux 能力(Capabiliity)。

cap_add:  - ALLcap_drop:  - NET_ADMIN  - SYS_ADMIN
  • dns_search

配置 DNS 搜索域。可以是一个值,也可以是一个列表。

dns_search: example.comdns_search:  - domain1.example.com  - domain2.example.com
  • command

覆盖容器启动后默认执行的命令。

command: bundle exec thin -p 3000
  • restart

定义容器重启策略(在使用 swarm 部署时将忽略该选项, 在 swarm 使用 restart_policy 代替 restart)。重启策略如下:

  • no,默认策略,在容器退出时不重启容器
  • on-failure,在容器非正常退出时(退出状态非0),才会重启容器
  • on-failure:3,在容器非正常退出时重启容器,最多重启3次
  • always,在容器退出时总是重启容器
  • unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
tomcat:    restart: always
  • 其它选项

working_dir, entrypoint, user, hostname, domainname, mem_limit, privileged, restart, stdin_open, tty, cpu_sharesv 这些都是和 docker run 支持的选项类似。

cpu_shares: 73working_dir: /codeentrypoint: /code/entrypoint.shuser: postgresqlhostname: foodomainname: foo.commem_limit: 1000000000privileged: truerestart: alwaysstdin_open: truetty: true

五、实战讲解

1)Docker-compose搭建Redis-jenkins

$ mkdir -p /opt/docker-composer-test/jenkins_home$ cd /opt/docker-composer-test/jenkins_home

用docker-compose安装,当然你也可以用docker run的方式,创建一个docker-jenkins-compose.yml文件。

version: "3"services:  jenkins:    image: jenkins/jenkins:lts    ports:      - 8080:8080      - 50000:50000    restart: "always"    container_name: jenkins    environment:      JAVA_OPTS: -Duser.timezone=Asia/Shanghai    volumes:      - /opt/docker-composer-test/jenkins_home:/var/jenkins_home      - /var/run/docker.sock:/var/run/docker.sock      - /usr/bin/docker:/usr/bin/docker    privileged: true    user: root

启动Jenkins容器

$ docker-compose -f docker-jenkins-compose.yml up -d

2)Docker-compose搭建Redis Sentinel(哨兵模式)

Redis Sentinel是针对原始Master/Slave模型而衍生的高可用模型。我们为便于灵活部署,先易后难,先搭建Redis Master/Slave模型,再搭建Redis Sentinel模型。

目录结构如下,先创建如下目录文件。

[root@Centos8-nat-bridge-168-182-153 redis_sentinel]# tree ..├── redis│?? └── docker-compose.yml└── sentinel    ├── docker-compose.yml    ├── sentinel1.conf    ├── sentinel2.conf    ├── sentinel3.conf    └── sentinel.conf

第一步:搭建Redis Master/Slave模型

下面的Compose文件设置了redis的 一主两从(Master-Slave)

1、创建redis/docker-compose.yml文件。

version: '3'services:  master:    image: redis    container_name: redis-master    command: redis-server --requirepass redis_pwd  --masterauth redis_pwd    ports:      - 6379:6379  slave1:    image: redis    container_name: redis-slave-1    ports:      - 6380:6379    command:  redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd  slave2:    image: redis    container_name: redis-slave-2    ports:      - 6381:6379    command: redis-server --slaveof redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd

注意,如果设置了Redis客户端访问密码requirepass, 那么也要设置相同的副本集同步密码masterauth。
另外我们后面使用哨兵模式能够完成故障转移,现有的Master可能会变成Slave,故在当前Master容器中也要携带masterauth参数

2、执行 以下命令 产生3个Redis容器,分别映射到宿主机6379、6380、6381端口, 默认连接在redis-default网桥

$ docker-compose -f redis/docker-compose.yml up -d

3、使用docker ps查看redis三个容器

$ docker ps -a

Docker三剑客之Compose

4、查看redis容器使用的网桥信息

$ docker inspect -f {{.HostConfig.NetworkMode}} 262b42fb0c9f

Docker三剑客之Compose
5、验证
Master/Slave副本集,进入Master容器,确认两个Slave容器已经连接。
在这里插入图片描述
redis/docker-compose.yml里面的redis密码我改成了:123456

第二步:docker-compose 部署Redis Sentinel

我们即将搭建的Sentinel容器需要能访问到以上3个容器,故需要在形成Sentinel容器时使用外置的redis-default网桥(Redis Master/Slave docker-compose 已经创建).

1、创建sentinel/docker-compose.yml,内容如下:

version: '3'services:  sentinel1:    image: redis    container_name: redis-sentinel-1    ports:      - 26379:26379    command: redis-sentinel /usr/local/etc/redis/sentinel.conf    volumes:      - ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf  sentinel2:    image: redis    container_name: redis-sentinel-2    ports:    - 26380:26379    command: redis-sentinel /usr/local/etc/redis/sentinel.conf    volumes:      - ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf  sentinel3:    image: redis    container_name: redis-sentinel-3    ports:      - 26381:26379    command: redis-sentinel /usr/local/etc/redis/sentinel.conf    volumes:      - ./sentinel3.conf:/usr/local/etc/redis/sentinel.confnetworks:  default:    external:      name: redis_default

2、创建哨兵文件sentinel/sentinel.conf,内容如下:

port 26379dir /tmpsentinel monitor mymaster 172.19.0.3 6379 2sentinel auth-pass mymaster 123456sentinel down-after-milliseconds mymaster 30000sentinel parallel-syncs mymaster 1sentinel failover-timeout mymaster 180000sentinel deny-scripts-reconfig yes

注意,以上 172.19.0.3是之前Redis Master/slave启动之后Master节点的IP,通过docker inspect [container]获取, 这里我们要配合设置Master/Slave访问密码:123456。

查看redis-master IP地址

$ docker inspect --format='{{.NetworkSettings.Networks.redis_default.IPAddress}}' redis-master#或者$ docker inspect redis-master

在这里插入图片描述

3、将哨兵文件复制三份

$ cp sentinel/sentinel.conf sentinel/sentinel1.conf$ cp sentinel/sentinel.conf sentinel/sentinel2.conf$ cp sentinel/sentinel.conf sentinel/sentinel3.conf

4、执行以下命令生成3个Sentinel容器。

$  docker-compose -f sentinel/docker-compose.yml up -d

5、此时docker ps显示如下:

$ docker ps

Docker三剑客之Compose
6、验证
进入其中一个redis-sentinel容器,确认Master、2个Slave、另外2个Sentinel.

$ docker exec -it redis-sentinel-1 /bin/bash$ redis-cli -p 26379$ sentinel master mymaster
  • flags: master表明master正常运作,异常情况会显示s-down,o-down
  • num-slaves:侦测到2个Slave副本集
  • num-other-sentinels:除此之外,还有2个哨兵
    在这里插入图片描述
    7、Redis Sentinel高可用验证

停止 redis-master容器,等待10s,进入任意sentinel容器,使用sentinel master mymaster命令观察主节点发生变化,观察外挂的Sentinel*.conf主节点IP发生变化,然后重新启动master节点,检查集群状态.

$ docker stop redis-master$ docker exec -it redis-sentinel-1 /bin/bash$ redis-cli -p 26379$ sentinel master mymaster

发现master节点以及s_down状态了。
在这里插入图片描述

六、Docker Compose 常用命令

命令 说明
docker-compose build 构建项目中的镜像,–force-rm:删除构建过程中的临时容器;–no-cache:不使用缓存构建;–pull:获取最新版本的镜像
docker-compose up -d 构建镜像、创建服务和启动项目,-d表示后台运行
docker-compose run ubuntu ls -d 指定服务上运行一个命令,-d表示后台运行
docker-compose logs 查看服务容器输出日志
docker-compose ps 列出项目中所有的容器
docker-compose pause [service_name] 暂停一个服务容器
docker-compose unpause [service_name] 恢复已暂停的一个服务容器
docker-compose restart 重启项目中的所有服务容器(也可以指定具体的服务)
docker-compose stop 停止运行项目中的所有服务容器(也可以指定具体的服务)
docker-compose start 启动已经停止项目中的所有服务容器(也可以指定具体的服务)
docker-compose rm 删除项目中的所有服务容器(也可以指定具体的服务),-f:强制删除(包含运行的)
docker-compose kill 强制停止项目中的所有服务容器(也可以指定具体的服务)