使用 Docker Compose 编排容器集群

Docker Compose可以让我们方便、快速地编排容器集群,有利于分布式架构的实现。

假设我们有一个应用以MySQL作为数据存储,如果没有编排工具的话,我们在构建此应用的Docker镜像时必须将MySQL一同打包进镜像中,这样不仅会使镜像体积臃肿,而且不利于分布式架构的实现(假如要做读写分离、主从复制之类的)。而有了Docker Compose,我们就可以创建两个镜像:单独的应用镜像和MySQL镜像。在运行时,分别创建两个容器,并且将两个容器链接(link)在一起,使它们之间可以按照配置相互通信。这样就将我们的单体应用拆分成了多个组件构成的应用(其实这就是微服务的思想),从而更有利于服务间的解耦以及分布式架构的实现。

下面举一个例子,完整实现可见vertx-blueprint-todo-backend | GitHub。现有一服务Vert.x Blueprint Todo Backend已打包成jar包,该服务以Redis作为数据存储。该服务以及Redis监听的地址和端口通过JSON配置文件来提供。我们可以设计两个镜像:服务镜像(通过Dockerfile构建)以及官方Redis镜像,运行时分别创建一个容器实例,然后通过Docker Compose将两个容器组合起来。首先来看一下我们的Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM java:8-jre
ENV VERTICLE_FILE build/libs/vertx-blueprint-todo-backend-fat.jar
ENV VERTICLE_HOME /usr/verticles
EXPOSE 8082
COPY $VERTICLE_FILE $VERTICLE_HOME/
COPY config/config_docker.json $VERTICLE_HOME/
WORKDIR $VERTICLE_HOME
ENTRYPOINT ["sh", "-c"]
CMD ["java -jar vertx-blueprint-todo-backend-fat.jar -conf config_docker.json"]

服务容器运行时对外暴露8082端口。再看一下服务配置文件:

1
2
3
4
5
6
7
{
"service.type": "redis",
"http.port": 8082,
"http.address": "0.0.0.0",
"redis.host": "redis",
"redis.port": 6379
}

注意我们将Redis的host设为redis,这个redis是对应的访问路径,后面会提到。下面来看Docker Compose的配置文件docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: "2"
services:
redis:
container_name: vertx-todo-backend_redis
image: redis:latest
expose:
- "6379"
vertx-todo-backend:
depends_on:
- redis
container_name: vertx-todo-backend_service
build: .
links:
- redis
ports:
- "8082:8082"

其中version: "2"代表对应镜像版本,最新的需要Docker 1.10.0支持。在services中,我们定义了两个serviceredisvertx-todo-backend

先来看redis中的配置。container_name代表容器名称,image代表对应的镜像,expose代表在集群内暴露的端口号(不对外暴露)。其它容器通过服务名redis访问此镜像。

再来看vertx-todo-backend。我们的服务需要依赖Redis,因此容器的启动顺序应该是redis -> vertx-todo-backend,因此我们配置了depends_on选项,此选项下的所有容器都将会在本容器启动之前启动(注意只是启动,并不是其它容器初始化完成后本容器才启动。如果需要等待其它容器初始化完毕,则需要另写脚本)。build对应着Dockerfile文件的路径,links代表链接的镜像,ports代表对外暴露的端口。

配置好以后,我们在目录下执行docker-compose up --build,一会就可以看到容器集群运行起来了,非常方便。

Docker Compose

更多的有关Docker Compose的信息,参考官方文档

文章目录