Skip to content

使用 Docker Compose 管理容器 ​

通过之前的介绍,我们已经基本掌握了构建、运行容器的方法,但这还远远不够,由于 Docker 采用轻量级容器的设计,每个容器一般只运行一个软件,而目前绝大多数应用系统都绝不是一个软件所能组成的。虽然我们之前提到了容器间互相连接、交换数据的各种方法,通过这些方法足以搭建起完整的用于应用系统运行的容器群,但是这显然还不够,这个容器群的搭建需要执行太多命令,更重要的是需要考虑太多应用和容器间的依赖关系处理,是一波令人头大的操作。在这一节中,我们就来介绍如何解决这些问题。

解决容器管理问题 ​

拿任何一个相对完整的应用系统来说,都不可能是由一个程序独立支撑的,而对于使用 Docker 来部署的分布式计算服务更是这样。随着时代的发展和技术演进,我们越来越推崇将大型服务拆分成较小的微服务,分别部署到独立的机器或容器中。也就是说,我们的应用系统往往由数十个甚至上百个应用程序或微服务组成。即使是一个小的微服务模块,通常都需要多个应用协作完成工作。

我们编写一个小型的微服务模块,虽然我们编写代码主要针对的是其中的应用部分,但如果我们要完整的进行开发、测试,与应用相关的周边软件必然是必不可少的。

虽然 Docker Engine 帮助我们完成了对应用运行环境的封装,我们可以不需要记录复杂的应用环境搭建过程,通过简单的配置便可以将应用运行起来了,但这只是针对单个容器或单个应用程序来说的。如果延伸到由多个应用组成的应用系统,那情况就稍显复杂了。

就拿最简单的例子来说吧,如果我们要为我们的应用容器准备一个 MySQL 容器和一个 Redis 容器,那么在每次启动时,我们先要将 MySQL 容器和 Redis 容器启动起来,再将应用容器运行起来。这其中还不要忘了在创建应用容器时将容器网络连接到 MySQL 容器和 Redis 容器上,以便应用连接上它们并进行数据交换。

这还不够,如果我们还对容器进行了各种配置,我们最好还得将容器创建和配置的命令保存下来,以便下次可以直接使用。

如果我们要想让这套体系像 docker run 和 docker rm 那样自如的进行无痕切换,那就更加麻烦了,我们可能需要编写一些脚本才能不至于被绕到命令的毛线球里。

说了这么多,其实核心还是缺少一个对容器组合进行管理的东西。

Docker Compose ​

针对这种情况,我们就不得不引出在我们开发中最常使用的多容器定义和运行软件,也就是 Docker Compose 了。

如果说 Dockerfile 是将容器内运行环境的搭建固化下来,那么 Docker Compose 我们就可以理解为将多个容器运行的方式和配置固化下来。

在 Docker Compose 里,我们通过一个配置文件,将所有与应用系统相关的软件及它们对应的容器进行配置,之后使用 Docker Compose 提供的命令进行启动,就能让 Docker Compose 将刚才我们所提到的那些复杂问题解决掉。

安装 Docker Compose ​

虽然 Docker Compose 目前也是由 Docker 官方主要维护,但其却不属于 Docker Engine 的一部分,而是一个独立的软件。所以如果我们要在 Linux 中使用它,还必须要单独下载使用。

Docker Compose 是一个由 Python 编写的软件,在拥有 Python 运行环境的机器上,我们可以直接运行它,不需要其它的操作。

我们可以通过下面的命令下载 Docker Compose 到应用执行目录,并附上运行权限,这样 Docker Compose 就可以在机器中使用了。

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$
$ sudo docker-compose version
docker-compose version 1.21.2, build a133471
docker-py version: 3.3.0
CPython version: 3.6.5
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

我们也能够通过 Python 的包管理工具 pip 来安装 Docker Compose。

$ sudo pip install docker-compose

在 Windows 和 macOS 中的 Docker Compose ​

在我们更常用于开发的 Windows 和 macOS 中,使用 Docker Compose 会来得更加方便。不论你是使用 Docker for Win 还是 Docker for Mac,亦或是 Docker Toolbox 来搭建 Docker 运行环境,你都可以直接使用 docker-compose 这个命令。这三款软件都已经将 Docker Compose 内置在其中,供我们使用。

Docker Compose 的基本使用逻辑 ​

如果将使用 Docker Compose 的步骤简化来说,可以分成三步。

  1. 如果需要的话,编写容器所需镜像的 Dockerfile;( 也可以使用现有的镜像 )
  2. 编写用于配置容器的 docker-compose.yml;
  3. 使用 docker-compose 命令启动应用。

准备镜像这一过程我们之前已经掌握了,这里我们就简单来看看后面两个步骤。

编写 Docker Compose 配置 ​

配置文件是 Docker Compose 的核心部分,我们正是通过它去定义组成应用服务容器群的各项配置,而编写配置文件,则是使用 Docker Compose 过程中最核心的一个步骤。

Docker Compose 的配置文件是一个基于 YAML 格式的文件。关于 YAML 的语法大家可以在网上找到,这里不再细说,总的来说,YAML 是一种清晰、简单的标记语言,你甚至都可以在看过几个例子后摸索出它的语法。

与 Dockerfile 采用 Dockerfile 这个名字作为镜像构建定义的默认文件名一样,Docker Compose 的配置文件也有一个缺省的文件名,也就是 docker-compose.yml,如非必要,我建议大家直接使用这个文件名来做 Docker Compose 项目的定义。

这里我们来看一个简单的 Docker Compose 配置文件内容。

version: '3'

services:

  webapp:
    build: ./image/webapp
    ports:
      - "5000:5000"
    volumes:
      - ./code:/code
      - logvolume:/var/log
    links:
      - mysql
      - redis

  redis:
    image: redis:3.2
  
  mysql:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=my-secret-pw

volumes:
  logvolume: {}

Docker Compose 配置文件里可以包含许多内容,从每个容器的各个细节控制,到网络、数据卷等的定义。

这里我们看几个主要的细节。首先是 version 这个配置,这代表我们定义的 docker-compose.yml 文件内容所采用的版本,目前 Docker Compose 的配置文件已经迭代至了第三版,其所支持的功能也越来越丰富,所以我们建议使用最新的版本来定义。

接下来我们来看 services 这块,这是整个 docker-compose.yml 的核心部分,其定义了容器的各项细节。

在 Docker Compose 里不直接体现容器这个概念,这是把 service 作为配置的最小单元。虽然我们看上去每个 service 里的配置内容就像是在配置容器,但其实 service 代表的是一个应用集群的配置。每个 service 定义的内容,可以通过特定的配置进行水平扩充,将同样的容器复制数份形成一个容器集群。而 Docker Compose 能够对这个集群做到黑盒效果,让其他的应用和容器无法感知它们的具体结构。

对于 docker-compose.yml 配置的具体细节,我们在下一节中还会专门讲解。

启动和停止 ​

对于开发来说,最常使用的 Docker Compose 命令就是 docker-compose up 和 docker-compose down 了。

docker-compose up 命令类似于 Docker Engine 中的 docker run,它会根据 docker-compose.yml 中配置的内容,创建所有的容器、网络、数据卷等等内容,并将它们启动。与 docker run 一样,默认情况下 docker-compose up 会在“前台”运行,我们可以用 -d 选项使其“后台”运行。事实上,我们大多数情况都会加上 -d 选项。

$ sudo docker-compose up -d

需要注意的是,docker-compose 命令默认会识别当前控制台所在目录内的 docker-compose.yml 文件,而会以这个目录的名字作为组装的应用项目的名称。如果我们需要改变它们,可以通过选项 -f 来修改识别的 Docker Compose 配置文件,通过 -p 选项来定义项目名。

$ sudo docker-compose -f ./compose/docker-compose.yml -p myapp up -d

与 docker-compose up 相反,docker-compose down 命令用于停止所有的容器,并将它们删除,同时消除网络等配置内容,也就是几乎将这个 Docker Compose 项目的所有影响从 Docker 中清除。

$ sudo docker-compose down

如果条件允许,我更建议大家像容器使用一样对待 Docker Compose 项目,做到随用随启,随停随删。也就是使用的时候通过 docker-compose up 进行,而短时间内不再需要时,通过 docker-compose down 清理它。

借助 Docker 容器的秒级启动和停止特性,我们在使用 docker-compose up 和 docker-compose down 时可以非常快的完成操作。这就意味着,我们可以在不到半分钟的时间内停止一套环境,切换到另外一套环境,这对于经常进行多个项目开发的朋友来说,绝对是福音。

通过 Docker 让我们能够在开发过程中搭建一套不受干扰的独立环境,让开发过程能够基于稳定的环境下进行。而 Docker Compose 则让我们更近一步,同时让我们处理好多套开发环境,并进行快速切换。

容器命令 ​

除了启动和停止命令外,Docker Compose 还为我们提供了很多直接操作服务的命令。之前我们说了,服务可以看成是一组相同容器的集合,所以操作服务就有点像操作容器一样。

这些命令看上去都和 Docker Engine 中对单个容器进行操作的命令类似,我们来看几个常见的。

在 Docker Engine 中,如果我们想要查看容器中主进程的输出内容,可以使用 docker logs 命令。而由于在 Docker Compose 下运行的服务,其命名都是由 Docker Compose 自动完成的,如果我们直接使用 docker logs 就需要先找到容器的名字,这显然有些麻烦了。我们可以直接使用 docker-compose logs 命令来完成这项工作。

$ sudo docker-compose logs nginx

在 docker-compose logs 衔接的是 Docker Compose 中所定义的服务的名称。

同理,在 Docker Compose 还有几个类似的命令可以单独控制某个或某些服务。

通过 docker-compose create,docker-compose start 和 docker-compose stop 我们可以实现与 docker create,docker start 和 docker stop 相似的效果,只不过操作的对象由 Docker Engine 中的容器变为了 Docker Compose 中的服务。

$ sudo docker-compose create webapp
$ sudo docker-compose start webapp
$ sudo docker-compose stop webapp

留言互动 ​

在本节中,我们展示了 Docker Compose 这个用于管理容器的工具。这里给大家留一道思考题:

在我们的开发中,我们应该如何的合理利用 Docker Compose 进行容器管理呢?

欢迎大家通过留言的方式说出你的看法。我会选出有代表性的优质留言,推荐给大家。

同时,如果你对 Docker Compose 和容器管理还有什么疑惑,或者有自己的想法要与大家分享,可以加入到这本小册的官方微信群中,参与对相关问题的讨论。

文章来源于自己总结和网络转载,内容如有任何问题,请大佬斧正!联系我