Docker Compose 实践

继续向 Kubernetes 进发,上一篇 Docker Swarm 集群模式实操 了解完 Swarm 后,有必要对 Docker Compose 了解一番。Docker Swarm 是把 Docker 宿主机组成集群,部署服务时只要告知 Manager 节点,它就会自动找到相应节点去运行相应的容器。Compose 完全是另一个概念,它把相关联的多个容器组织成一个整体来部署,如由负载容器,多个 Web 容器和一个 Redis 缓存容器构成一个整体。

由其名 Compose 正式有了容器编排这么一个概念,后来将要学的 Kubernetes 是更高级别的组织,运行,管理容器的工具。Compose  由于把容器组织起来了,所以能够一条命令启动多个相关联的容器,而无需单独启动一个一个的容器。

关于 Docker Compose  的安装,在 Mac OS X 下的  Docker Desktop 自带了 docker-compose; 由于 Docker Compose 是用 Python 编写的,我们可以用  pip install docker-compose 的安装,安装后使用它的命令就是 docker-compose

下方的 Docker Container, Swarm, Compose 三者之间的关系图很形像

Compose 由多个容器组成,它可以以一个整体部署到单个 Docker 宿主机或 Swarm 宿主机集群当中。

下面亲自来体验一下 Docker Compose 的功能,设计了一个服务含有如下容器

  1. 前端负载均衡服务器,由 HAProxy 来扮演,请求转发到以下两个  Web 容器
  2. 两个 Web 容器,用 Python Flask 来演示
  3. 一个 Redis 缓存容器,Web 将会访问该容器中的缓存数据

定义 Docker Compose 涉及到的文件有  Dockerfile 和 docker-compose.yml,需要为每一个自定义的 Docker 容器创建一个 Dockerfile,某些容器能直接使用 Docker 镜像仓库的就不用单独的 Dockerfile。也就是说一个 Compose 中可有一个或多个 Dockerfile,  如果是一个 Dockerfile  的情况时,目录结构可以是

myapp/
    - Dockerfile
    - docker-compose.yml

如果需要用到多个 Dockerfile 的情况时,Dockerfile 必须要放在不同的目录中,这时目录结构需要调整为如下(并加上后面将要用到的几个辅助文件)

myapp/
    - proxy/
        - Dockerfile
        - haproxy.cfg
    - web/
        - Dockerfile
        - app.py
        - requirements.txt
    - docker-compose.yml

接下来看每一个文件的内容

myapp/proxy/Dockerfile

myapp/proxy/haproxy.cfg

这是一个最简单的 haproxy.cfg 配置文件,只是把请求轮转的转发到 web_a 和 web_b, 将会在后面的 docker-compose.yml 文件中看到 web_a 和 web_b。

myapp/web/Dockerfile

myapp/web/requirements.txt

myapp/web/app.py

用简单的 Flask 来演示一个 Web 应用,访问计数保存在 Redis 中,并显示当前处理请处的机器名。

myapp/docker-compose.yml

自已构建两个 Docker  镜像,Redis 的镜像直接用  redis:alpine 的,在这里定义了端口及映射,所以在 Dockerfile 中不用 EXPOSE 来定义端口号。我们将启动两个 Web 服务,分别为 web_a, web_b, 在前方的 haproxy.cfg 转发请求就是到这两个容器中去的。

现在我们可以来到命令行下的 myapp 目录处,执行命令

$ docker-compose up -d

此时,如果本地没有相应的镜像文件将会构建 myapp_proxy, myapp_web_a, myapp_web_b 镜像,然后启动它们。如果本地已有那些镜像则直接启动那些容器。启动完成后,用 docker ps 查看

启动了四个容器,一个 haproxy, 两个 web, 一个  redis,正是我们所需要的。再来验证一下服务,是否能共同完成请求:

负载均衡,Web 服务,Redis 正在协同无误的工作

如果此时用 docker kill 56 杀掉任何一个容器,该容器不会自动恢复起来,但再次运行 docker-compose run -d 后,只是刚刚被杀的容器又起来了,其他的容器没变化。

请用 docker-compose -h 查看更丰富的命令参数,不少与 docker 命令参数是一样的,只是针对 docker-compose而已,例如下面常用的

  1. docker-compose images: 显示当前 compose 所用到的 docker 镜像
  2. docker-compose logs: 显示当前 compose  的运行日志
  3. docker-compose down: 停掉 compose 涉及到的所有容器
  4. docker-compose kill: 杀掉  compose 涉及的所有容器,而无须用 docker kill 逐个杀
  5. docker-compose restart: 重启整个  compose  服务(所有容器)

还有更简单的支持 HAProxy + 多个动态的 Web 容器的方式

修改前面的 docker-compose.yml 文件内容如下:

proxy 选用了 dockercloud/haproxy 镜像,自己构建用的 myapp/proxy 目录及其中的 Dockerfilehaproxy.cfg 文件也不用了。

现在用同样的命令启动 docker-compose up -d

只有一个 web 容器,现在还能动态扩容,用 docker-compose up --scale web=d -d

来测试一下他们是否能正常工作

三次请求分别被三个不同的 Web 容器处理。

注:

  1. docker-compose scale web=2 命令不推荐使用,而应用 docker-compose up --scale web=2 -d
  2. docker-compose.yml 中的 deploy 配置只能工作于 Swarm 模式,而 deploy 下的 replicas 是工作于 docker stack deploy 命令的,在 docker-compose updocker-compose run 中被忽略

关于在 Swarm  集群之上运行 Compose

看起来有点麻烦,见官方的 Use Compose with Swarm. 需要用到 docker stack 来部署 Compose。自己就不作实际操作了,也不知道产品中这种结合情景多不多,关键了解一下部署后容器是如何在 Swarm  节点中分配的,是把  Compose 当作一个整体呢?还是以 Compose 中的容器为粒度来部署。

Deploy Docker Compose (v3) to Swarm (mode) Cluster 中的一张图片来看

Swarm 还是能把 Compose 中定义的容器拆分出来,单独的部署到 Swarm 集群中的节点上,而不是把 Compose 当作一个整体来看待,表现的不错。

链接:

  1. How to use Docker Compose to run complex multi container apps on your Raspberry Pi
  2. Docker Compose 多容器部署 (五)
  3. Docker-Compose简介安装使用

本文链接 https://yanbin.blog/docker-compose-in-action/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments