[Docker] Docker Compose 基础教程(概念/基础操作)

发布时间 2023-10-24 17:53:35作者: 千千寰宇

1 Docker Compose 概述

1.1 Docker Compose 简述

Compose 是用于定义和运行多容器 Docker 应用程序的工具。
通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。
然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

如果你还不了解 YML 文件配置,可以先阅读 YAML 入门教程

Compose 使用的三个步骤:

  • Step1 使用 Dockerfile 定义应用程序的环境。
  • Step2 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • Step3 执行 docker-compose up 命令来启动并运行整个应用程序。

1.1.0 Docker Compose 的产生背景

  • 我们使用 Docker 时:
    • Step1 定义 Dockerfile 文件
    • Step2 使用 docker builddocker run 等命令操作容器。

然而:微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,那么效率之低维护量之大

为了提高效率,我们就需要一种像 Dockerfile 定义 Docker 容器一样,能够定义容器(多个)编排和部署工具。

于是,Docker Compose 出现了(其实应该说 Fig 出现了,Docker 收购了 Fig 并改名为 compose)。

1.1.1 Docker Compose 是什么?

  • Docker-compose 是一个定义和运行多个 Docker 应用的工具,你可以使用YMAL文件来配置你的服务,然后使用docker-compose 命令,创建和启动、编排所有你配置的的服务。
  • compose 可以在任何工作环境中使用,生产环境,开发环境,持续集成等等。

从logo上可以看出来, 它就是一个管理容器的工( zhang )具( yu ), 我们可以方便的使用它来管理我们的Docker容器, 可以极大程度的简化命令行的复杂操作

1.1.2 容器编排模板 docker-compose.yml

docker-compose.yml 的配置案例如下(配置参数参考下文):

  • Demo 1
# yaml 配置实例
version: '3'
services:
  web:
    build: .
    ports:
    - "5000:5000"
    volumes:
    - .:/code
    - logvolume01:/var/log
    links:
    - redis
  redis:
    image: redis
volumes:
  logvolume01: {}
  • Demo 2
version: '3.7'
services:
  haproxy:
    image: dockercloud/haproxy
  redis:
    image: rediS
    
 ...

即 project 包含 service ,service 包含 container

1.1.3 Docker Compose 版本沿革

1.1.4 Docker Compose (V2) 与 Docker-Compose (V1) 的区别

  • docker compose(带空格)是一个较新的项目,用于将 composedocker 项目的其余部分一起迁移到 Go

    • 这是docker/compose repov2分支。
    • 它首先被介绍给 Docker Desktop 用户,所以 Linux 上的 docker 用户看不到该命令。
  • 除了迁移到 Go 之外,它使用了 compose-spec,部分重写可能会导致行为差异。

  • 最初的 python 项目,称为docker-compose docker/compose repov1,现已于2023年7月被正式弃用,开发已全部转移到 v2

  • 要在 Linux 上将 v2 docker compose作为 CLI 插件安装,支持的发行版现在可以安装该docker-compose-plugin软件包。
  • 例如在 debian Linux 上,我运行apt-get install docker-compose-plugin
  • 建议:使用 docker compose(较新版本/V2),而不是 docker-compose(旧版本/V1)

https://docs.docker.com/compose/#compose-v2-and-the-new-docker-compose-command

1.2 容器编排与管理工具比对:Docker Compose vs. K8s

在开始比较Docker Compose和之前,我们首先要了解这两个工具的概述。

  • Docker Compose是Docker公司推出的开源工具,它允许用户在单个主机上定义和运行多个容器应用程序。
  • Kubernetes(K8s)是一个由Google维护的开源系统,它用于自动化部署、扩展和管理容器化应用程序。
    • 使用K8s,用户可以轻松地在集群中运行容器应用程序。

1.2.1 功能比对

尽管Docker Compose和K8s都用于部署和管理容器应用程序,但它们的功能有所不同。

  • Docker Compose主要用于在单个主机上管理和运行多个容器应用程序。

使用Docker Compose,用户可以轻松地定义多个容器和它们之间的依赖关系,并在单个主机上部署和运行它们。

  • 相比之下,K8s更灵活,它不仅可以在单个主机上运行容器应用程序,还可以在多个主机上运行这些应用程序。
  • 此外,K8s提供了许多高级功能,例如:服务发现自动扩缩容等,使用户可以更轻松地管理容器应用程序

1.3 Docker Compose 模板文件(详解)

  • Compose模板文件格式
  • Docker Compose 使用 YAML 文件来定义多服务的应用。
  • Docker Compose 默认 使用文件名 docker-compose.yml。当然,也可以使用 -f 参数指定具体文件

官方提供了一个 yaml Docker Compose 配置文件的标准例子
提示:可以用 .yml.yaml 作为文件扩展名

version: "3.7"
services:
​
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"
    networks:
      - frontend
    deploy:
      # 指定运行容器的数量
      replicas: 2
      update_config:
        # 一次性更新的容器数量
        parallelism: 2
        # 更新一组容器之间的等待时间
        delay: 10s
      restart_policy:
        condition: on-failure
​
  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        constraints: [node.role == manager]
​
  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - 5000:80
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        # 一次性更新的容器数量
        parallelism: 2
      restart_policy:
        condition: on-failure
​
  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - 5001:80
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        # 一次性更新的容器数量
        parallelism: 2
        # 更新一组容器之间的等待时间
        delay: 10s
      restart_policy:
        condition: on-failure
​
​
networks:
  frontend:
  backend:
​
volumes:
  db-data: 

1.3.1 项目级配置(project)

  • version:指定 docker-compose.yml 文件的写法格式

    • 如 3.7 / 3 / ...
  • volumes / 卷标设置与查看

使用卷标模式进行挂载
​
volumes:
  db-data:

挂载方式对比:

  • 绝对路径:直接挂载到本地,比较直观,但需要管理本地的路径

  • 卷标:简洁,但你不知道数据存在本地什么位置

  • networks / 网络定义

目的:实现网络隔离

networks:
  frontend:
  backend:
docker network create --subnet=172.158.0.0/16 frontend
  • services
    • 参见:服务级配置

1.3.2 服务级配置(services)

  • replicas: 指定运行容器的数量

  • update_config :

    • parallelism:一次性更新的容器数量
    • delay:更新一组容器之间的等待时间
  • mode : replicated 如果服务是 replicated(默认),需要指定运行的容器数量

  • restart_policy 重启策略

配置容器的重新启动,代替 restart

  • condition : 值可以为 none 、on-failure 以及 any(默认)
  • delay : 尝试重启的等待时间,默认为 0
  • max_attempts : 在放弃之前尝试重新启动容器次数(默认:从不放弃)。如果重新启动在配置中没有成功 window,则此尝试不计入配置max_attempts 值。例如,如果 max_attempts 值为 2,并且第一次尝试重新启动失败,则可能会尝试重新启动两次以上。
  • windows : 在决定重新启动是否成功之前的等时间,指定为持续时间(默认值:立即决定)

1.4 Docker Compose 架构与原理

1.4.1 Docker 总体架构

1.4.2 Docker Compose 运行架构

1.4.3 Docker Compose 核心概念

  • Docker Compose将所管理的容器分为三层,这三个概念均为Compose抽象的数据类型,其中 project 会包含service以及container:

    • 项目/工程(project)
    • 服务(service)
    • 容器(contaienr)
  • 项目(project):代表用户需要完成的一个项目。

    • 通过 Docker Compose 管理的一个项目被抽象称为一个 project
      • 何为项目?Compose的一个配置文件可以解析为一个项目。
      • 即:Compose通过分析指定配置文件,得出配置文件所需完成的所有容器管理与部署操作。
      • 例如:用户在当前目录下执行docker-compose up -d,配置文件为当前目录下的配置文件docker-compose.yml,命令请求类型为up,-d为命令参数,对于配置文件中的内容,compose会将其解析为一个project。
    • project 里包括多个 service
      • 一个project拥有特定的名称,并且包含多个或一个service,同时还带有一个Docker Client。
  • service,代表配置文件中的每一项服务,何为服务?

    • 即以容器为粒度,用户需要Compose所完成的任务。
      • 比如,前面的配置文件中包含了两个service,第一个为web,第二个为redis。
    • 每个 service 定义了容器运行的镜像(或构建镜像)、网络端口、文件挂载、参数、依赖等
      • 一个service包含的内容,无非是用户对服务的定义。定义一个服务,可以为服务容器指定镜像,设定构建的Dockerfile,可以为其指定link的其他容器,还可以为其指定端口的映射等。
    • 每个 service 可包括同一个镜像的多个容器实例。
  • 容器(container)

1.4.4 docker-compose下启动容器的过程

# docker-compose up -d 

Compose 的一次调用流程

    1. 首先,用户执行 docker-compose up 命令调用命令行中的启动方法
    1. 然后,如果当前宿主机已存在与该应用对应的容器,docker-compose 则进行行为逻辑判断。如果用户指定可以重新启动已有服务,docker-compose 就会执行 service 模块的容器重启方法,否则就直接启动已有容器。这两种操作的区别在于前者会停止旧的容器,创建并启动新的容器,并把旧容器移除掉。
    1. 最后,contaier 模块会调用 docker-py 客户端来执行向 docker daemon 发起创建容器的 POST 请求。

2 Docker Compose 安装卸载与运维使用

2.1 安装

2.1.1 Docker Compose V1

注:Docker Compose V1,需用户手动/主动安装 docker-compose

Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。 运行以下命令以下载 Docker Compose 的当前稳定版本:

## 源安装
#### 方式1:国外源安装 | 版本最全 【推荐】
$ curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 等效于 : 
# sudo curl -L "https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 等效于 :
# curl -SL "https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-$(uname -s | tr 'A-Z' 'a-z')-$(uname -m)" -o /usr/local/bin/docker-compose
# curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose 

#### 方式2:国内源安装 | 版本更新相对缓慢
# curl -SL "https://get.daocloud.io/docker/compose/releases/download/v2.17.2/docker-compose-$(uname -s | tr 'A-Z' 'a-z')-$(uname -m)" -o /usr/local/bin/docker-compose
# curl -SL https://get.daocloud.io/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

## 检查是否下载成功 
ls -la /usr/local/bin | grep "docker-compose"
vi /usr/local/bin/docker-compose
  • uname -s : Linux
  • uname -m : x86_64
    要安装其他版本的 Compose,请替换 v2.17.2。
    Docker Compose 存放在 GitHub,不太稳定。
    你可以也通过执行下面的命令,高速安装 Docker Compose。

curl -L https://get.daocloud.io/docker/compose/releases/download/v2.17.2/docker-compose-uname -s-uname -m > /usr/local/bin/docker-compose

将可执行权限应用于二进制文件:

$ sudo chmod +x /usr/local/bin/docker-compose

创建软链:

## 创建软链接
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

测试是否安装成功:

## 验证是否安装成功
$ docker-compose version
Docker Compose version v2.17.2

注意: 对于 alpine,需要以下依赖包: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make。

常见问题:

  • 如果安装完成后,查看版本频繁报错,如下
    • Cannot open self /usr/local/bin/docker-compose or archive /usr/local/bin/docker-compose.pkg
  • 可使用下面的解决方案:
    • 1、切换到 /usr/local/bin,删除之前的下载 /docker-compose
    • 2、切换到 /usr/local/bin 执行下面的命令
      • wget https://github.com/docker/compose/releases/download/1.25.0-rc4/docker-compose-Linux-x86_64
    • 3、下载完毕后重命名为docker-compose : mv docker-compose-Linux-x86_64 docker-compose
    • 4、赋权限
    • 5、查看版本成功

2.1.2 Docker Compose V2

docker version = 18.06.3-ce 为例

docker compose --version

  • 安装 docker compose v2 | 官网
    You can download Docker Compose binaries from the release page on this repository.
    Rename the relevant binary for your OS to docker-compose and copy it to $HOME/.docker/cli-plugins
    Or copy it into one of these folders to install it system-wide:
/usr/local/lib/docker/cli-plugins OR /usr/local/libexec/docker/cli-plugins
/usr/lib/docker/cli-plugins OR /usr/libexec/docker/cli-plugins

2.2 验证

2.2.1 Docker Compose V1

## 验证是否安装成功
$ docker-compose version
Docker Compose version v2.17.2

2.3 卸载

2.3.1 Docker Compose V1

# step1 停止 + 删除所有容器 + 移除自定义网络(down)
docker-compose down

# step2 二进制包方式安装的,删除二进制文件即可
rm /usr/local/bin/docker-compose

2.3 容器管理

2.3.1 构建镜像

2.3.1.1 构建镜像(build)

  • docker-compose build
    • 构建或者重新构建服务的镜像,但不会创建和启动容器
    • 当你改变本地代码之后,先执行 docker-compose build 构建新的镜像,然后执行 docker-compose up -d 取代运行中的容器
docker-compose build

docker-compose -f docker-compose.yml build

  • 构建指定的镜像
    • 如,仅web目标将需要构建映像
version: '3.2'

services:
  database:
    image: mariadb
    restart: always
    volumes:
      - ./.data/sql:/var/lib/mysql

  web:
    build:
      dockerfile: Dockerfile-alpine
      context: ./web
    ports:
      - 8099:80
    depends_on:
      - database

调用时docker-compose build,仅web目标将需要构建映像。该docker build命令如下所示:

docker build -t web_myproject -f Dockerfile-alpine ./web

2.3.1.2 构建镜像,并部署、启动容器(up)

  • docker-compose up

用于部署一个 Compose 应用。 默认情况下该命令会读取名为 docker-compose.yml 或 docker-compose.yaml 的文件。

当然用户也可以使用 -f 指定其他文件名。通常情况下,会使用 -d 参数令应用在后台启动。

docker-compose up

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

docker-compose -f docker-compose-non-dev.yml up -d

2.3.1.3 从【镜像仓库】中【拉取镜像】(pull)

  • docker-compose pull

docker compose pull 是一个Docker Compose命令,用于从镜像仓库中拉取所需的Docker镜像。

它的作用是根据docker-compose.yml文件中定义的服务和镜像名称,从配置的镜像仓库中下载最新版本的镜像。如果本地没有需要的镜像或者需要更新已有的镜像版本时,使用docker compose pull命令可以获取最新的镜像并存储到本地。

如果要使用docker compose pull命令,需要在命令行中切换到包含docker-compose.yml文件的目录,然后执行该命令即可。代码示例如下:

cd /path/to/docker-compose
docker compose pull

demo

docker compose -f docker-compose-non-dev.yml pull

2.3.2 启动容器

  • 启动所有的容器
docker-compose start
  • 启动指定的容器,如果不指定则停止所有的容器
docker-compose start {containerName}
  • 重启所有的容器 | docker-compose restart
    • 重启已停止的 Compose 应用。 如果用户在停止该应用后对其进行了变更,那么变更的内容不会反映在重启后的应用中
    • 这时需要重新部署应用使变更生效。
docker-compose restart
  • 重启指定的容器
docker-compose restart web

2.3.3 停止容器

停止 Compose 应用相关的所有容器,但不会删除它们。 被停止的应用可以很容易地通过 docker-compose restart 命令重新启动。

  • 停止所有容器
docker-compose stop

  • 停止指定容器,若不指定则停止所有的容器
docker-compose stop container_name

2.3.4 删除镜像

2.3.4.1 删除镜像

  • 删除镜像 | docker-compose rm

用于删除已停止的 Compose 应用;
它会删除容器和网络,但是不会删除卷和镜像。

docker-compose rm
  • 删除指定的已停止容器,若不指定则删除所有已停止容器
docker-compose rm {containerName/containerId}

2.3.4.2 停止、删除所有容器,移除自定义网络(down)

  • 停止并删除运行中的 Compose 应用。 它会删除容器和网络,但是不会删除卷和镜像
docker-compose down

demo

# 停止并移除容器 docker-compose 的所有资源 | 停止并移除docker-compose.yml中定义的所有容器、网络和数据卷
# cd /root/projects/superset
# docker-compose -f docker-compose-non-dev.yml down

2.3.5 查看运行的容器

docker-compose ls

  • docker-compose ps

用于列出 Compose 应用中的各个容器。 输出内容包括当前状态、容器运行的命令以及网络端口。

docker-compose ps

注:必须在 docker-compose.yml 下执行,否则报“no configuration file provided: not found”

对比一下docker ps

2.3.6 查看指定容器的日志

  • 查看具体容器的日志
    • -f 参数表示:实时日志输出
docker-compose logs -f {containerName/containerId}

2.3.7 查看指定容器端口所绑定的宿主机端口

即 查看某个容器端口所映射的公共端口

docker-compose port [options] {containerName} {containerPort}
	--protocol=proto 指定端口协议,tcp(默认值)或者 udp
	--index=index 如果同一服务存在多个容器,指定命令对象容器的序号(默认为 1)
# 下面结果表示:将web服务的5000端口映射到了宿主机的5001端口
[root@centos01 ~]# docker-compose port web 5000
0.0.0.0:5001

X 参考文献