一、功能说明

容器在当今的云计算中极为重要,是构建微服务的重要组成部分。而一个微服务如果由多个容器,比如nginx+php+mysql,单个容器分开管理会非常麻烦 。目前华为云、阿里云等厂商都提供了很多Docker容器的管理工具。Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具。

一个使用docker-compose的架构示例

二、安装

Linux下的安装命令:

 sudo curl -L  -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose -v  

Mac环境在使用安装文件安装Docker时会自带Compose

三、常用命令
 # 列出所有容器
docker-compose ps
# 看服务日志
docker-compose logs
# 打印绑定的公共端口,下面是个示例
docker-compose port eureka 8761
# 构建服务
docker-compose build
# 启动指定服务已存在的容器
docker-compose start eureka
# 停止已运行的服务的容器
docker-compose stop eureka
# 删除指定服务的容器
docker-compose rm eureka
# 构建启动容器,更新容器
docker-compose up
# kill:通过发送 SIGKILL 信号来停止指定服务的容器
docker-compose kill eureka
# pull:下载服务镜像
# scale:设置指定服务运气容器的个数,以 service=num 形式指定
docker-compose scale user=3 movie=3
# run:在一个服务上执行一个命令
docker-compose run web bash  
四、使用步骤
  1. 使用 Dockerfile 定义应用程序的环境。
  2. 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  3. docker-compose up 启动。
五、测试步骤

1. 准备文件

 mkdir composetest
cd composetest
vim app.py  
 import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)


def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)


@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)  

这个示例 Python 去访问redis服务,端口6379。

在 composetest 目录中创建另一个名为 requirements.txt 的文件,内容如下:

 flask
redis  

2. 编辑vim Dockerfile文件

 FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]  

这个Dockerfile是构建Python容器使用。字段解释如下:

  • FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。
  • WORKDIR /code: 将工作目录设置为 /code。
  • ENV FLASK_APP app.py flask主文件设置
  • ENV FLASK_RUN_HOST 0.0.0.0 设置 flask 命令使用的 环境变量 。
  • RUN apk add –no-cache gcc musl-dev linux-headers: 安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
  • COPY requirements.txt requirements.txt
  • RUN pip install -r requirements.txt 复制 requirements.txt 并安装 Python 依赖项。
  • COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。
  • CMD [“flask”, “run”]: 容器提供默认的执行命令为:flask run。

3. 创建 docker- com pose.yml

在测试目录中创建一个名为 docker-compose.yml 的文件:

 # yaml 配置
version: '3'
 services :
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"  

该 Compose 文件定义了两个服务:web 和 redis。

  • version: 指定 docker-compose.yml 文件的写法格式
  • services: 多个容器的集合
  • web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
  • redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。
  • links: 服务之间可以使用服务名称相互访问,links 允许定义一个别名,从而使用该别名访问其它服务,如:
 version: '2'
services:
    web:
        build: .
        links:
            - "db:database"
    db:
        image: postgres  

Web 服务就可以使用 db 或 database 作为 hostname 访问 db 服务了。

4. 使用 Compose 命令构建和运行应用

在测试目录中,执行以下命令来启动应用程序:

 docker-compose up  

后台执行该服务可以加上 -d 参数:

 docker-compose up -d  

运行效果:

六、yml 配置指令参考

version

指定本 yml 依从的 compose 哪个版本制定的。

build

指定为构建镜像上下文路径:例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:

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

或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:

 version: "3.7"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1
      labels:
        - "com.example.description=Accounting webapp"
        - "com.example.department=Finance"
        - "com.example.label-with-empty-value"
      target: prod  
  • context:上下文路径。
  • dockerfile:指定构建镜像的 Dockerfile 文件名。
  • args:添加构建参数,这是只能在构建过程中访问的环境变量。
  • labels:设置构建镜像的标签
  • target:多层构建,可以指定构建哪一层。

cap_add,cap_drop

添加或删除容器拥有的宿主机的内核功能。

 cap_add:
  - ALL # 开启全部权限

cap_drop:
  - SYS_PTRACE # 关闭 ptrace权限  

cgroup_parent

为容器指定父 cgroup 组,意味着将继承该组的资源限制。

 cgroup_parent: m-executor-abcd  

command

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

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

container_name

指定自定义容器名称,而不是生成的默认名称。

depends_on

设置依赖关系。

deploy

指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。

endpoint_mode:

访问集群服务的方式。

devices

指定设备映射列表。

dns

自定义 DNS 服务器,可以是单个值或列表的多个值。

dns_search

自定义 DNS 搜索域。可以是单个值或列表。

entrypoint

覆盖容器默认的 entrypoint。

env_file

从文件添加环境变量。可以是单个值或列表的多个值。

environment

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

expose

暴露端口,但不映射到宿主机,只被连接的服务访问。

extra_hosts

添加主机名映射。类似 docker client –add-host。

healthcheck

用于检测 docker 服务是否健康运行。

image

指定容器运行的镜像。

logging

服务的日志记录配置。

network_mode

设置网络模式。

restart

重启策略

secrets

存储敏感数据

security_opt

修改容器默认的 schema 标签。

stop_grace_period

指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。

stop_signal

设置停止容器的替代信号。

sysctls

设置容器中的内核参数,可以使用数组或字典格式。

tmpfs

在容器内安装一个临时文件系统。可以是单个值或列表的多个值。

ulimits

覆盖容器默认的 ulimit。

volumes

将主机的数据卷或着文件挂载到容器里。