Docker Compose 轻量级容器编排

使用 Docker Compose 编排 Spring Cloud 分布式应用。

说到容器编排,目前很火的 Kubernetes 就是一个自动化容器编排工具,但 Kubernetes 是一个重量级选手,部署比较复杂,对于简单的分布式应用,可以使用 Docker Compose 做轻量级的容器编排,实现容器间的服务注册发现和弹性伸缩。

Spring Cloud 分布式应用

这里用 Spring Cloud 开发一个简单的分布式应用,该应用包含几个简单的微服务:Eureka 做服务注册发现,Feign 服务调用,Zuul 微服务网关,Ribbon 负载均衡,Hystrix 服务降级 / 隔离。

把微服务放在 Docker 容器内,用 compose 进行容器自动化构建和部署,实现基本的注册中心、服务调用、路由和监控。

Docker compose 容器编排

Docker compose 是一个容器管理工具,可以很方便地构建和管理多容器应用。

构建运行容器

在 docker-compose.yml 中配置容器编排规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
version: "3"
services:
eureka:
build: eureka-server
image: eureka
ports:
- 8000:80
provider:
build: service-provider
image: service-provider

consumer:
build: feign-consumer
image: feign-consumer

gateway:
build: zuul-gateway
image: zuul-gateway
ports:
- 80:80
hystrix:
build: hystrix-turbine
image: hystrix-turbine

为了加快构建速度,需要先编译出 jar 文件,再统一构建和运行:

1
2
3
4
5
6
7
8
# 编译SpringBoot
mvn clean package

# 构建Docker镜像
docker-compose build

# 运行所有容器
docker-compose up

Docker 容器内是一个封闭环境,容器内服务间可通过 Docker compose 中的服务名直接互联。

注册中心

Eureka 注册中心服务映射到容器外 8000 端口,打开注册中心可以看到服务都已启动:

API 网关

Zuul 网关映射到容器外 80 端口,通过 Zuul 可以访问到容器内的服务。

1
2
3
4
5
# 停止所有微服务
docker-compose stop

# 删除所有容器
docker-compose rm

服务扩容

微服务架构中,我们经常需要对服务进行扩容缩容,docker-compose scale 可以指定服务启动多少个实例,方便实现系统的弹性伸缩。

比如要启动 3 个 provider 和两个 gateway 实例,执行一条命令:

1
docker-compose scale provider=3 gateway=2

执行完成后打开注册中心,可以看到已经启动了 3 个 provider 和两个 gateway 实例:

清理中间镜像

构建镜像后,如果之前有同名镜像,会出现一些标签为空的镜像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
yunterry/service-provider latest 088d56298e08 About a minute ago 144MB
yunterry/feign-consumer latest 5e04a653948a About a minute ago 147MB
yunterry/zuul-gateway latest 160c477c3909 About a minute ago 148MB
yunterry/hystrix-turbine latest e61c005e7740 About a minute ago 148MB
yunterry/eureka latest a58a9dfdfe24 About a minute ago 148MB
<none> <none> 70c9ad8823b9 2 days ago 148MB
<none> <none> d331346e70a7 2 days ago 149MB
<none> <none> a3dafb3c5d70 2 days ago 148MB
<none> <none> e5c3078fe57c 2 days ago 145MB
<none> <none> fc30ccb5ff6d 2 days ago 150MB
consul latest d686c08d0dc8 11 days ago 51.8MB
node alpine a47a5669ac57 3 weeks ago 65.3MB
redis latest 1fb7b6c8c0d0 3 weeks ago 107MB
muli/gluon-tutorials-zh latest 1e80c558f4a8 5 weeks ago 2.15GB
java jre-alpine fdc893b19a14 8 months ago 108MB

可以通过过滤器查看标签为空的镜像:

1
2
3
4
5
6
7
$ docker images -f "dangling=true"
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 70c9ad8823b9 2 days ago 148MB
<none> <none> d331346e70a7 2 days ago 149MB
<none> <none> a3dafb3c5d70 2 days ago 148MB
<none> <none> e5c3078fe57c 2 days ago 145MB
<none> <none> fc30ccb5ff6d 2 days ago 150MB

所以清理这些中间镜像就很简单了,取出这些标签为空的镜像 ID,就可以批量删除:

1
docker rmi $(docker images -f "dangling=true" -q)

再用 docker images 查看就很整洁了。

项目源码

https://github.com/yunTerry/Spring-Cloud-Docker