docker-compose up命令 docker-compose stop_配置文件


通过


清香白莲:容器技术(一):docker基础zhuanlan.zhihu.com

docker-compose up命令 docker-compose stop_docker-compose up命令_02


我们可知使用 Docker布署应用的步骤是,先定义 Dockerfile 文件,然后使用 docker build构建镜像,再用docker run 命令启动容器。

然而再生产环境,尤其是微服务架构中,业务模块一般包含若干个服务,每个服务一般都会部署多个实例。整个系统的布署或启停将涉及多个子服务的布署或启停,而且这些子服务之间还存在强依赖关系,手动操作不仅劳动强度大还容易出错。

docker-compose就是解决这种容器编排问题的一个高效轻量化工具,它通过一个配置文件来描述整个应用涉及的所有容器与容器之间的依赖关系,然后可以用一条指令来启动或停止整个应用。

本文将介绍其原理与使用方式。

docker-compose原理

docker-compose是一个python项目,它是通过调用docker-py库与docker engine交互实现构建docker镜像,启动停止docker容器等操作实现容器编排的。而Docker-py库则是通过调用docker remote API与Docker Daemon交互(可通过DOCKER_HOST配置本地或远程Docker Daemon的地址)来操作docker镜像与容器的。

为了方便docker-compose将所管理的对象抽象为三层: 工程(project)、服务(service)与容器(contaienr)。docker-compose命令运行的目录下的所有文件(docker-compose.yml, extends文件或环境变量文件等)组成一个工程,默认的名称即为目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。每一个服务当中又包含了一个或多个容器实例,但docker-compose并没有负载均衡功能,还需要借助其他工具来实现服务发现与负载均衡。

创建docker-compose工程的核心在于定义配置文件,配置文件的默认名称docker-compose.yml,也可以用其他名称,但需要修改环境变量COMPOSE_FILE或者启动时通过-f参数指定配置文件。配置文件定义了多个有依赖关系的服务及每个服务运行的容器,示例与其定义方式可见下一小节。docker-compose启动一个工程主要经历如下步骤:

  1. 工程初始化 – 解析配置文件(包括docker-compose.yml,外部配置文件extends files,环境变量配置文件env_file),并将每个服务的配置转换成python字典,初始化docker-py客户端用于与docker engine通信。
  2. 根据docker-compose的命令参数将命令分发给相应的处理函数,其中启动命令为up;
  3. 调用project类的up函数,得到当前工程中的所有服务,并根据服务的依赖关系进行拓扑排序并去掉重复出现的服务;
  4. 通过工程名以及服务名从docker engine获取当前工程中处于运行中容器,从而确定当前工程中各个服务的状态,再根据当前状态为每个服务制定接下来的动作。docker-compose使用labels标记启动的容器,使用docker inspect可以看到通过docker-compose启动的容器都被被添加了标记。
  • 若容器不存在,则服务动作设置为创建(create);
  • 若容器存在但设置不允许重建,则服务动作设置为启动(start);
  • 若容器配置发生变化(config-hash)或者设置强制重建标志,则服务动作设置为重建(recreate);
  • 若容器状态为停止,则服务动作设置为启动(start);
  • 若容器状态为运行但其依赖容器需要重建,则服务状态设置为重建(recreate);
  • 若容器状态为运行其无配置改变则不作操作;
  • 根据每个服务不同的动作执行不同的操作

5. 根据拓扑排序的次序,一次执行每个服务的动作。如果服务动作为创建:

  • 检查镜像是否存在,若镜像不存在,则检查配置文件中关于镜像的定义。如果在配置文件中设置为build则调用docker-py build函数与docker engine通信完成docker build的功能。如果在配置文件中设置为image则通过docker-py pull函数与docker engine通信完成docker pull的功能。
  • 获取当前服务中容器的配置信息,如端口,存储卷,主机名,使用镜像环境变量等配置的信息。若在配置中指定本服务必须与某个服务在同一台主机(previous_container,用于集群)则在环境变量中设置affinity:container=。通过docker-py与docker engine通信创建并启动容器。

如果服务动作为重建:

  • 停止当前的容器;
  • 将现有的容器重命名,这样数据卷在原容器被删除前就可以拷贝到新创建的容器中了;
  • 创建并启动新容器,previsous_container设置为原容器确保其运行在同一台主机(存储卷挂载);
  • 删除旧容器。

如果服务动作为启动则启动停止的容器。

这就是docker-compose up的命令执行过程,docker-compose.yml文件中定义的所有服务或容器会被全部启动。

docker-compose配置

下列为一个docker-compose配置文件的示例,其定义的工程包含了两个service,一个是数据库服务test_db一个是web服务test_web。其中web服务包含了两个副本,并且要再数据库服务启动之后才能启动。


version: '3'                               # 配置版本号
services: 
  database:                                # 服务名称             
    image: mysql:5.7                       # 使用的镜像
    container_name: test-db                # 容器名称
    ports:                                 # 端口映射配置
      - "3307:3306"
    restart: always                        # 重启方式
    networks:                              # 服务连接到的指定网络
      - deploy-net
    environment:                           # 配置环境变量
      MYSQL_DATABASE: "test_db"
      MYSQL_ROOT_PASSWORD: "@QWEqwe123"
      MYSQL_ROOT_HOST: "%"
#    command: mysql -hlocalhost -uroot -p@QWEqwe123
    volumes:                               # 配置容器内文件或目录挂载到宿主机
      - "/home/db/test/test_db:/var/lib/mysql"
      - "/home/dbtest/test_db/conf/my.cnf:/etc/my.cnf"
      - "/home/db/test/test_db/init:/docker-entrypoint-initdb.d/"
  web:
    depends_on:                          # 配置当前服务依赖的服务
      - database
    build: ./                            # 配置构建image的Dockerfile文件位置
    image: test-web
#    container_name: test-web            # 容器名必须唯一,所以如果服务包两个以上容器,则不能指定容器名
    restart: always
    volumes:
      - /home/logs/test/web/test_web/service:/home/logs/test/web/test_web/service
    ports:
      - "8888:8888"
    deploy:                              # 布署配置
      replicas: 2                        # 创建两个副本
    networks:
      - test-net
networks:                                # 网络配置
  test-net:
    driver: bridge                       # 指定网络驱动器为bridge


大多数配置项都具有自解释性,下面介绍两个比较重要的布署配置

deploy
指定与部署和运行服务相关的配置


version: '3'
services:
  redis:
    image: redis:alpine
    deploy:
      mode: replicated     #global:每个集节点只有一个容器;replicated:指定容器数量(默认)
      replicas: 6
      update_config:
        delay: 10s
        order: stop-first
      parallelism: 2
      delay: 10s
      restart_policy:     #容器重启配置,用于替代restart
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      resources:           #资源限制
        limits:
          cpus: '0.50'
          memory: 50M
          reservations:
          cpus: '0.25'
          memory: 20M


这里有几个子选项

endpoint_mode 指定连接到群组外部客户端服务发现方法,主要又两个选项:

  • vip :Docker 为该服务分配了一个虚拟 IP(VIP),作为客户端的 “前端“ 部位用于访问网络上的服务。
  • dnsrr : DNS轮询(DNSRR)服务发现不使用单个虚拟 IP。Docker为服务设置 DNS 条目,使得服务名称的 DNS 查询返回一个 IP 地址列表,并且客户端直接连接到其中的一个。如果想使用自己的负载平衡器,或者混合 Windows 和 Linux 应用程序,则 DNS 轮询调度(round-robin)功能就非常实用。

update_config配置更新服务方式,用于无缝更新应用(rolling update),主要包括一下啊子配置:

  • delay:更新一组容器之间的等待时间。
  • failure_action:如果更新失败,可以执行的的是 continue、rollback 或 pause (默认)。
  • monitor:每次任务更新后监视失败的时间(ns|us|ms|s|m|h)(默认为0)。
  • max_failure_ratio:在更新期间能接受的失败率。
  • order:更新次序设置,top-first(旧的任务在开始新任务之前停止)、start-first(新的任务首先启动,并且正在运行的任务短暂重叠)(默认 stop-first)。

restart

容器重启方式,主要又三个选项:

  • no :即在任何情况下都不会重新启动容器;
  • always :容器总是重新启动;
  • on-failure:当出现 on-failure 报错容器退出时,容器重新启动。

docker-compose常见命令

docker-compose命令的格式为:


docker-compose [options] [COMMAND] [ARGS...]


  • options: 选项,如-f file_name来指定配置文件,默认为为当前目录下的 docker-compose.yml文件。-p选项指定项目名称,默认为当前目录名称。--project-directory PATH指定工作目录(默认当前目录)。
  • COMMAND: 子命令,表示要进行的操作,最常见的为构建容器命令up,杀死容器命令kill,打印容器日志命令logs,散出容器命令rm等。
  • ARGS: 命令的运行参数,如-d表示后台运行。

其中COMMAND主要分为以下几类:

  • 管理服务:up/start/scale/stop/restart/rm/kill;
  • 管理镜像:build/pull;
  • 查看服务运行状态:ps/port;
  • 打印服务运行日志:logs;
  • 在一个服务中执行命令:run。

使用示例

  • 启动服务。在docker-compose.yml目录下,运行该命令会按照其定义的编排方式运行所有容器,如果镜像没有构建会自动构建,也可以指定配置文件。
docker-compose up
docker-compose up -d 
# 根据指定文件启动
docker-compose -f compose.yml  up -d


  • 列出所有容器
docker-compose ps
# 列出compose.yml定义的所有容器
docker-compose -f compose.yml ps


  • 开始,停止以及停止后删除服务
docker-compose -f compose.yml stop
docker-compose -f compose.yml stop
docker-compose -f compose.yml start
docker-compose -f compose.yml down


  • 进入容器
docker-compose -f compose.yml exec mysql bash


  • 打印绑定的公共端口.如输出 my-service 服务 7001 端口所绑定的公共端口
docker-compose port myservice 7001


  • 构建或者重新构建服务的image
docker-compose build
docker-compose -f compose.yml build


结论

docker-compose是一个为了解决工程中包含大量子服务时布署困难的问题的python项目,它是通过调用docker-py库与docker engine交互实现容器编排的。使用docker-compose布署应用主要分为三步:

  • Dockerfile 定义应用的运行环境;
  • docker-compose.yml 定义组成应用的各服务;
  • docker-compose up 启动整个应用。

其中核心在于定义docker-compose.yml 配置文件。