Docker深入浅出系列 | Docker Compose多容器实战

时间:2023-12-26 11:00:13

Docker已经上市很多年,不是什么新鲜事物了,很多企业或者开发同学以前也不多不少有所接触,但是有实操经验的人不多,本系列教程主要偏重实战,尽量讲干货,会根据本人理解去做阐述,具体官方概念可以查阅官方教程,因为本系列教程对前一章节有一定依赖,建议先学习前面章节内容。

本系列教程导航:

Docker深入浅出系列 | 容器初体验

Docker深入浅出系列 | Image实战演练

Docker深入浅出系列 | 单节点多容器网络通信

Docker深入浅出系列 | 容器数据持久化

Docker深入浅出系列 | 单机Nginx+Springboot实战

教程目的:

  • 了解docker-compose是什么&为什么要用
  • 了解docker-compose如何安装
  • 了解如何创建docker-compose 文件
  • 了解如何利用docker-compose 文件去创建服务
  • 了解docker compose的基本命令
  • 了解如何通过docker compose进行弹性扩容
  • 掌握docker-compose在nginx+springboot实战应用

前期准备

1.下载mysql

docker pull mysql

2.下载nginx

docker pull nginx

3.克隆credit-facility-service作为后面部署演示使用,使用docker分支

git clone https://github.com/EvanLeung08/credit-facility-service.git

4.虚拟机、centos和docker环境安装请查看第一章,本章默认已经安装好centos和docker

Docker深入浅出系列 | 容器初体验


Docker Compose是什么

Docker Compose是一个用于定义和运行多容器应用程序的工具。 通过compose,我们可以使用yaml文件来配置应用程序的服务,然后使用一个命令来创建和启动所有已配置的服务。 在微服务环境中进行本地开发测试时,我们经常使用此工具。 它也是轻量级的,只需要简单的配置。 您可以预先配置所需的环境和服务,然后专注于当前开发的服务,而不必管理开发时如何运行每个服务的方式。

Docker深入浅出系列 | Docker Compose多容器实战


为什么要用Docker Compose

首先,我们回顾前一章,我们要部署一个微服务项目,需要手动配置一堆命令,十分繁琐,假如有几十上百个容器,并且容器之间还存在依赖,光是忙着搭建容器都耗掉一天了,还谈什么Devops,那有没有什么方便快捷的组建,可以让我们通过一个配置就搞定容器编排和运行呢?

Docker compose就是为了简化多容器配置和管理工作而生的,可以简化大量重复的手动工作,具有以下主要特点:

  • 提供工具用于定义和运行多个docker容器应用
  • 使用yaml文件来配置应用服务(docker-compse.yml)
  • 可以通过一个简单的命令docker-compse up可以按照依赖关系启动所有服务
  • 可以通过一个简单的命令docker-compose down停止所有服务
  • 当一个服务需要的时候,可以很简单地通过--scale进行扩容

Docker Compose的考虑理由:

  • 可移植性

    Docker Compose仅需一个命令即可提供完整的开发环境:docker-compose up,然后使用docker-compose down轻松将其拆解。 这使我们的开发人员可以将开发环境保持在一个中立位置,并帮助我们轻松地部署应用程序。
  • 测试

    Compose的另一个重要功能是通过将其置于自己的环境中,以快速可重复的方式支持运行单元和E2E测试。 这意味着,您可以运行与生产环境非常相似的环境,而不是在本地/主机系统上测试应用程序。
  • 单个主机上的多个隔离环境

    Compose使用项目名称将环境彼此隔离,这带来了以下好处:
    • 您可以在一台计算机上运行同一环境的多个副本
    • 它可以防止不同的项目和服务相互干扰

Docker Compose使用场景

Docker深入浅出系列 | Docker Compose多容器实战

  • 单主机部署

    传统上,Compose专注于开发和测试,但现在可用于在单个主机系统上进行部署和管理容器的整个部署过程。

  • 开发环境

    Compose提供了在孤立的环境中运行应用程序的能力,该环境可以在安装了Docker的任何计算机上运行。 这使测试你的应用程序变得非常容易,并提供了一种尽可能接近生产环境的工作方式。

    Compose文件管理应用程序的所有依赖项(数据库,队列,缓存等),并且可以使用单个命令创建每个容器。

  • 自动化测试环境

    持续集成和整个开发过程的重要组成部分是自动化测试套件,该套件要求可以在其中执行测试的环境。 Compose提供了一种方便的方法来创建和销毁与您的生产环境接近的隔离测试环境。


Docker Compose安装

可以参考官网:Docker Compose安装

1.下载当前稳定版本,选择对应系统版本,我这里用的是Centos

通过官方下载

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

通过国内源下载

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

2.赋予可执行权限

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

Compose Yaml文件结构

通过Compose,我们开发人员可以通过应用在docker-compose.yml文件中声明的许多规则轻松地一次处理多个Docker容器。

它由多个层级组成,这些层级使用制表符或空格分隔,而不是大多数编程语言中已知的括号。 几乎每个Compose-File应该具有以下四个主要方面:

  • Compose文件的Version
  • 我们将要构建的Services
  • 所有要使用的Volumes
  • 用来连接不同服务的network

docker-compose.yml 示例:

version: '3.3'

services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}

以上文件包含整个Wordpress应用程序,包括MySQL数据库。 这些服务中的每一个都被视为一个单独的容器,可以在需要时进行添加或删除

我是怎么知道这些命令怎么使用?

详细的配置参数,可以查阅: 官方配置参数


Compose 基本操作命令

查看docker-compose的基本操作命令,可以通过docker-compose --help进行查看,很多命令其实是跟docker相似

[root@localhost credit-facility]# docker-compose --help
Define and run multi-container applications with Docker. Usage:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help Options:
-f, --file FILE Specify an alternate compose file
(default: docker-compose.yml)
-p, --project-name NAME Specify an alternate project name
(default: directory name)
--verbose Show more output
--log-level LEVEL Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
--no-ansi Do not print ANSI control characters
-v, --version Print version and exit
-H, --host HOST Daemon socket to connect to --tls Use TLS; implied by --tlsverify
--tlscacert CA_PATH Trust certs signed only by this CA
--tlscert CLIENT_CERT_PATH Path to TLS certificate file
--tlskey TLS_KEY_PATH Path to TLS key file
--tlsverify Use TLS and verify the remote
--skip-hostname-check Don't check the daemon's hostname against the
name specified in the client certificate
--project-directory PATH Specify an alternate working directory
(default: the path of the Compose file)
--compatibility If set, Compose will attempt to convert keys
in v3 files to their non-Swarm equivalent
--env-file PATH Specify an alternate environment file Commands:
build Build or rebuild services
bundle Generate a Docker bundle from the Compose file
config Validate and view the Compose file
create Create services
down Stop and remove containers, networks, images, and volumes
events Receive real time events from containers
exec Execute a command in a running container
help Get help on a command
images List images
kill Kill containers
logs View output from containers
pause Pause services
port Print the public port for a port binding
ps List containers
pull Pull service images
push Push service images
restart Restart services
rm Remove stopped containers
run Run a one-off command
scale Set number of containers for a service
start Start services
stop Stop services
top Display the running processes
unpause Unpause services
up Create and start containers
version Show the Docker-Compose version information

Docker Compose实战

Docker深入浅出系列 | Docker Compose多容器实战

相信大家都已经看过上一章,如果大家还没有看过,请先回到上一章节教程

在上一章,我们通过手动方式,一步步搭建了Nginx、Mysql以及额度服务,相信大家都体会到整个流程非常繁琐,有一部出错了,都要重新敲一遍指令,在本章我们沿用上一章的环境配置,但是整个过程会通过docker compose来帮我们自动部署而不是手动部署。

实战目标

  • 创建docker网络,设置静态子网ip168.18.0.0/24
  • 搭建额度服务集群
    • [额度服务]credit-facility01 - 168.18.0.10
    • [额度服务]credit-facility02 - 168.18.0.11
    • [额度服务]credit-facility03 - 168.18.0.12
  • 搭建Mysql数据库
    • [Mysql服务]credit-facility-db - 168.18.0.4
  • 搭建Nginx服务,并配置负载均衡规则
    • [Nginx服务]credit-facility-nginx - 168.18.0.5
  • 创建Volume credit-facility-volume,用于持久化Mysql容器数据
  • 利用docker内置DNS服务器的特点,docker网络内容器之间通过容器名称进行通信
  • 通过浏览器访问swagger进行业务操作

实战步骤

清理旧配置

1.如果上一章已经创建好了容器,先清理上一章已经创建的容器,避免冲突

docker container stop credit-facility01
docker container stop credit-facility02
docker container stop credit-facility03
docker container stop credit-facility-db
docker container stop credit-facility-nginx
docker container rm credit-facility01
docker container rm credit-facility02
docker container rm credit-facility03
docker container rm credit-facility-db
docker container rm credit-facility-nginx

2.清理上一章创建好的网络credit-facility-net

docker network rm credit-facility-net

3.核对下当前Centos系统上credit-facility目录下的文件是否跟我一致,如果不一样,请先查看上一章

[root@localhost credit-facility]# ls
Dockerfile nginx start-1.0.0-SNAPSHOT.jar

我们上一章创建好的文件应该是以上三个

搭建环境

1.上传credit-facility-service项目里的docker-compose.yml文件到Centos系统credit-facility目录下,如果还没克隆额度服务到本地,请查看前期准备

docker-compose.yml文件存放在credit-facility-service项目dockerfile目录下

[root@localhost credit-facility]# ls
Dockerfile docker-compose.yml nginx start-1.0.0-SNAPSHOT.jar

这时候会多了一个docker-compose.yml文件

PS: 如果在前面章节没有创建额度服务镜像,这里需要先创建credit-facility-image镜像:

[root@localhost credit-facility]# docker build -t credit-facility-image .

2.通过docker config校验compose文件,如果文件格式有问题,通过该命令可以帮你校验并输出错误信息

[root@localhost credit-facility]# docker-compose config
networks:
credit-facility-net:
driver: bridge
ipam:
config:
- subnet: 168.18.0.0/24
services:
credit-facility-service1:
build:
context: /usr/local/credit-facility
container_name: credit-facility01
image: credit-facility-image
networks:
credit-facility-net:
ipv4_address: 168.18.0.10
ports:
- 8081:8080/tcp
restart: always
credit-facility-service2:
build:
context: /usr/local/credit-facility
container_name: credit-facility02
image: credit-facility-image
networks:
credit-facility-net:
ipv4_address: 168.18.0.11
ports:
- 8082:8080/tcp
restart: always
credit-facility-service3:
build:
context: /usr/local/credit-facility
container_name: credit-facility03
image: credit-facility-image
networks:
credit-facility-net:
ipv4_address: 168.18.0.12
ports:
- 8083:8080/tcp
restart: always
mysql:
build:
context: /usr/local/credit-facility
container_name: credit-facility-db
environment:
MYSQL_DATABASE: db_credit_facility
MYSQL_ROOT_PASSWORD: evan123
image: mysql
networks:
credit-facility-net:
ipv4_address: 168.18.0.4
ports:
- 3301:3306/tcp
restart: always
volumes:
- credit-facility-volume:/var/lib/mysql:rw
nginx:
build:
context: /usr/local/credit-facility
container_name: credit-facility-nginx
image: nginx
networks:
credit-facility-net:
ipv4_address: 168.18.0.5
ports:
- 80:80/tcp
restart: always
volumes:
- /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/nginx.conf:rw
version: '3.0'
volumes:
credit-facility-volume: {}

这里可以看到,我们的配置文件检验通过,接下来我们分段拆解来说明下每一段脚本的意思

配置网络

networks:
credit-facility-net:
driver: bridge
ipam:
config:
- subnet: 168.18.0.0/24

跟前面一样,这里创建了一个自定义网络credit-facility-net,指定了docker的网络模式是bridge,划分了一个子网ip段168.18.0.0/24,跟前一章手动配置对应的命令如下:

[root@localhost ~]# docker network create --subnet=168.18.0.0/24 credit-facility-net

配置Mysql容器

  mysql:
restart: always
container_name: credit-facility-db
image: mysql
ports:
- "3301:3306"
volumes:
- "credit-facility-volume:/var/lib/mysql:rw"
environment:
- MYSQL_DATABASE=db_credit_facility
- MYSQL_ROOT_PASSWORD=evan123
networks:
credit-facility-net:
ipv4_address: 168.18.0.4
  • restart - 指定了容器每次部署都会重新重启
  • container_name - 指定了容器名称为credit-facility-db
  • image - 指定了我们用来运行容器的镜像是mysql,如果指定的image不存在,它会自动从远程仓库下载
  • ports - 指定了我们映射端口,这里把容器3306端口映射到宿主机器3301端口
  • volumes - 指定了容器里的存储路径以volume挂载方式映射到宿主机器上credit-facility-volume,并且分配读写权限
  • environment - 这里环境变量的作用是向容器传递参数,指定了数据库实例为db_credit_facility,数据库root用户密码为evan123
  • networks - 指定了网络选用自定义网络credit-facility-net,分配静态IP 168.18.0.4

上面的compose文件配置对应前一章的手动配置命令如下:

[root@localhost ~]# docker run -d --name credit-facility-db -v credit-facility-volume:/var/lib/mysql -p 3301:3306 -e MYSQL_ROOT_PASSWORD=evan123 --net=credit-facility-net --ip 168.18.0.4 mysql

配置额度服务集群

  credit-facility-service1:
restart: always
container_name: credit-facility01
depends_on:
- mysql
image: credit-facility-image
build: .
ports:
- "8081:8080"
networks:
credit-facility-net:
ipv4_address: 168.18.0.10 credit-facility-service2:
restart: always
container_name: credit-facility02
depends_on:
- mysql
image: credit-facility-image
build: .
ports:
- "8082:8080"
networks:
credit-facility-net:
ipv4_address: 168.18.0.11 credit-facility-service3:
restart: always
container_name: credit-facility03
depends_on:
- mysql
image: credit-facility-image
build: .
ports:
- "8083:8080"
networks:
credit-facility-net:
ipv4_address: 168.18.0.12

核心配置:

  • container_name - 这里主要是配置3个额度服务实例,分别为credit-facility01credit-facility02credit-facility03
  • build - 这里指定了docker-compose从当前目录寻找dockerfile文件进行镜像创建和启动容器
  • depends_on - 它指定当前容器依赖mysql容器,这样子docker-compose启动时会按照依赖关系来启动
  • networks - 指定了自定义网络credit-facility-net,并对三个实例分别分配了静态ip168.18.0.10168.18.0.11168.18.0.12

大部分命令跟前面一样,所以这里不作重复讲解。这里对应前一章的手动配置命令如下:

[root@localhost credit-facility]# docker build -t credit-facility-image .
[root@localhost credit-facility]# docker run -d --name credit-facility01 -p 8081:8080 --net=credit-facility-net --ip 168.18.0.10 credit-facility-image
[root@localhost credit-facility]# docker run -d --name credit-facility02 -p 8082:8080 --net=credit-facility-net --ip 168.18.0.11 credit-facility-image
[root@localhost credit-facility]# docker run -d --name credit-facility03 -p 8083:8080 --net=credit-facility-net --ip 168.18.0.12 credit-facility-image

这里沿用上一章在credit-facility目录下创建的dockerfile:

FROM openjdk:8-jre-alpine
MAINTAINER evan
LABEL name="credit-facility" version="1.0" author="evan"
COPY start-1.0.0-SNAPSHOT.jar credit-facility-service.jar
CMD ["java","-jar","credit-facility-service.jar"]

配置Nginx服务

 nginx:
restart: always
container_name: credit-facility-nginx
depends_on:
- mysql
- credit-facility-service1
- credit-facility-service2
- credit-facility-service3
image: nginx
ports:
- "80:80"
volumes:
- /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/nginx.conf
networks:
credit-facility-net:
ipv4_address: 168.18.0.5

核心配置:

  • container_name - 把nginx容器命名为credit-facility-nginx
  • depends_on - 定义了容器启动依赖关系
  • ports - 把容器80端口映射到宿主机80端口
  • volumes - 把容器目录下的/etc/nginx/nginx.conf 文件映射到宿主机/usr/local/credit-facility/nginx/nginx.conf,这里的nginx配置沿用上一章的配置不变,宿主机的配置会自动覆盖容器的nginx.conf文件
  • networks - 指定网络为credit-facility-net,并分配静态ip为168.18.0.5

大部分命令跟前面一样,所以这里不作重复讲解。这里对应前一章的手动配置命令如下:

[root@localhost nginx]# docker run -d --name credit-facility-nginx -p 80:80 -v /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/ningx.conf --network=credit-facility-net --ip 168.18.0.5 nginx

这里沿用上一章的Nginx配置/usr/local/credit-facility/nginx/nginx.conf:

user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65; server {
listen 80;
location / {
proxy_pass http://balance;
}
} upstream balance{
server credit-facility01:8080;
server credit-facility02:8080 ;
server credit-facility03:8080;
}
include /etc/nginx/conf.d/*.conf;
}

这里是通过容器名称访问,因此不需要管每个容器的ip是多少

4.通过docker-compose up启动所有服务

[root@localhost credit-facility]# docker-compose up
Creating network "credit-facility_credit-facility-net" with driver "bridge"
Creating credit-facility02 ... done
Creating credit-facility-db ... done
Creating credit-facility03 ... done
Creating credit-facility-nginx ... done
Creating credit-facility01 ... done
...

通过docker-compose命令,会按照我们在docker-compose.yml配置的信息去创建和启动服务,并且把日志打印到控制台输出,这里因为日志太多,只截取了部分日志,只要日志没有报错信息,所有服务到这里已经搭建完成

验证环境

1.验证Nginx服务是否已经成功,这里需要通过宿主机ip+映射端口访问

先查看下当前centos机器的ip

[root@localhost credit-facility]# ip add
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:ba:0a:28 brd ff:ff:ff:ff:ff:ff
inet 192.168.101.23/24 brd 192.168.101.255 scope global noprefixroute dynamic eth1
valid_lft 68553sec preferred_lft 68553sec
inet6 fe80::a00:27ff:feba:a28/64 scope link
valid_lft forever preferred_lft forever

从上面可以看到,宿主机外网ip是192.168.101.23

在本机浏览器输入192.168.101.23进行验证

Docker深入浅出系列 | Docker Compose多容器实战Nginx服务已经启动成功

2.验证额度服务是否成功访问

通过Nginx 80端口验证

Docker深入浅出系列 | Docker Compose多容器实战

分别通过每个实例自身映射端口访问

Docker深入浅出系列 | Docker Compose多容器实战

Docker深入浅出系列 | Docker Compose多容器实战

Docker深入浅出系列 | Docker Compose多容器实战

3.验证额度服务接口是否可以处理成功

在验证额度服务前,需要先把表创建好,把credit-facility-service下的db script在DB里执行

Docker深入浅出系列 | Docker Compose多容器实战

进入到Mysql容器,把表创建sql放进去执行

[root@localhost credit-facility]# docker exec -it credit-facility-db bash
root@d0d2fb8006c9:/# mysql -uroot -pevan123
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| db_credit_facility |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec) mysql> use db_credit_facility;
Database changed
mysql> CREATE TABLE `t_product_limit`
...

输入下面请求数据测试接口

{
"registrationLimitCO": {
"applicationId": "1111",
"userId": 1111,
"quotaLimit": 10000,
"productCode": "tb",
"expirationTime": "2030-01-01",
"accountType": 1
} }

Docker深入浅出系列 | Docker Compose多容器实战

Docker深入浅出系列 | Docker Compose多容器实战

从上面输出结果可以看到,接口已经处理成功

4.进去数据库查看是否已经保存数据成功

mysql> select * from t_product_limit;
+--------------------+---------------------+---------------------+---------+---------+--------------------+--------------------+-------------+---------+--------------+-------------+---------------+-----------------+--------------+------------+--------------+------------+---------------+-------------+---------------+---------------------+---------------+---------------+-----------+-----------+
| id | create_time | edit_time | deleted | version | serial_number | account_id | customer_id | user_id | product_code | quota_limit | quota_balance | quota_occupancy | quota_frozen | quota_base | quota_change | quota_mode | frozen_status | frozen_time | expire_status | expiration_time | active_status | inactive_time | parent_id | abandoned |
+--------------------+---------------------+---------------------+---------+---------+--------------------+--------------------+-------------+---------+--------------+-------------+---------------+-----------------+--------------+------------+--------------+------------+---------------+-------------+---------------+---------------------+---------------+---------------+-----------+-----------+
| 684437432334159872 | 2020-03-03 08:30:00 | 2020-03-03 08:30:00 | 0 | 0 | 684437432338354177 | 684437432338354176 | 111111 | 1111 | tb | 10000 | 0 | 0 | 0 | 0 | 0 | NULL | 1 | NULL | NULL | 2030-01-01 00:00:00 | NULL | NULL | NULL | 0 |
+--------------------+---------------------+---------------------+---------+---------+--------------------+--------------------+-------------+---------+--------------+-------------+---------------+-----------------+--------------+------------+--------------+------------+---------------+-------------+---------------+---------------------+---------------+---------------+-----------+-----------+
1 row in set (0.00 sec)

Compose弹性扩容初体验

在互联网公司比较场景,经常会遇到服务器资源不足,特别是遇到节假日公司要搞活动,需要临时扩容增大服务的计算能力,假如我们公司已经用上docker,docker-compose就可以帮我们很简单做到服务器扩容,当然,docker-compose很少直接在生产上独立使用,更多是在开发测试环境,后面讲解k8s的时候会介绍生产上如何做到弹性扩容。

Docker深入浅出系列 | Docker Compose多容器实战

接下来,我们只需要通过简单的命令就可以实现弹性扩容

1.对于前面我们创建的docker-compose.yml做一点改动,加入一个新的服务定义,如下

  web:
restart: always
image: credit-facility-image
build: .
expose:
- "8080"
depends_on:
- mysql
- credit-facility-service1
- credit-facility-service2
- credit-facility-service3
networks:
- credit-facility-net

这里指定了容器端口是8080,但是没有配置宿主机端口映射,网络也加入到credit-facility-net

Nginx也需要调整下,把静态ip去掉,并且加上依赖,避免ip冲突,docker会自动分配一个静态ip

    nginx:
restart: always
container_name: credit-facility-nginx
depends_on:
- mysql
- credit-facility-service1
- credit-facility-service2
- credit-facility-service3
- web
image: nginx
ports:
- "80:80"
links:
- web
volumes:
- /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/nginx.conf
networks:
- credit-facility-net

在这里我复制了一份credit-facility-service配置,为了方便演示,我去掉了网络配置和端口映射,因为如果想使用弹性扩容,端口和ip不能固定,否则会启动失败,改造后完整的配置如下:

version: '3'
services: mysql:
restart: always
container_name: credit-facility-db
image: mysql
ports:
- "3301:3306"
volumes:
- "credit-facility-volume:/var/lib/mysql:rw"
environment:
- MYSQL_DATABASE=db_credit_facility
- MYSQL_ROOT_PASSWORD=evan123
networks:
credit-facility-net:
ipv4_address: 168.18.0.4 credit-facility-service1:
restart: always
container_name: credit-facility01
depends_on:
- mysql
image: credit-facility-image
build: .
ports:
- "8081:8080"
networks:
credit-facility-net:
ipv4_address: 168.18.0.10 credit-facility-service2:
restart: always
container_name: credit-facility02
depends_on:
- mysql
image: credit-facility-image
build: .
ports:
- "8082:8080"
networks:
credit-facility-net:
ipv4_address: 168.18.0.11 credit-facility-service3:
restart: always
container_name: credit-facility03
depends_on:
- mysql
image: credit-facility-image
build: .
ports:
- "8083:8080"
networks:
credit-facility-net:
ipv4_address: 168.18.0.12 web:
restart: always
image: credit-facility-image
build: .
expose:
- "8080"
depends_on:
- mysql
- credit-facility-service1
- credit-facility-service2
- credit-facility-service3
networks:
- credit-facility-net nginx:
restart: always
container_name: credit-facility-nginx
depends_on:
- mysql
- credit-facility-service1
- credit-facility-service2
- credit-facility-service3
- web
image: nginx
ports:
- "80:80"
links:
- web
volumes:
- /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/nginx.conf
networks:
- credit-facility-net networks:
credit-facility-net:
driver: bridge
ipam:
config:
- subnet: 168.18.0.0/24
volumes:
credit-facility-volume: {}

2.执行以下命令,对web服务进行弹性扩容,创建三个容器实例

[root@localhost credit-facility]# docker-compose up --scale web=3 -d
Creating network "credit-facility_credit-facility-net" with driver "bridge"
Creating network "credit-facility_default" with the default driver
Creating credit-facility_web_1 ... done
Creating credit-facility_web_2 ... done
Creating credit-facility_web_3 ... done
Creating credit-facility01 ... done
Creating credit-facility02 ... done
Creating credit-facility03 ... done
Creating credit-facility-nginx ... done
Creating credit-facility-db ... done

从上图可以看到,web服务对应的容器实例已经创建成功,它的命名方式是基于dockerfile里面的Label名称+_web_<实例序号>

3.通过docker-compose ps查看下当前已启动的容器

[root@localhost credit-facility]# docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------
credit-facility-db docker-entrypoint.sh mysqld Up 0.0.0.0:3301->3306/tcp, 33060/tcp
credit-facility-nginx nginx -g daemon off; Up 0.0.0.0:80->80/tcp
credit-facility01 java -jar credit-facility- ... Up 0.0.0.0:8081->8080/tcp
credit-facility02 java -jar credit-facility- ... Up 0.0.0.0:8082->8080/tcp
credit-facility03 java -jar credit-facility- ... Up 0.0.0.0:8083->8080/tcp
credit-facility_web_1 java -jar credit-facility- ... Up 8080/tcp
credit-facility_web_2 java -jar credit-facility- ... Up 8080/tcp
credit-facility_web_3 java -jar credit-facility- ... Up 8080/tcp

这里可以看到,我们配置的所有容器都启动成功,并且新增了三个web容器实例

4.通过docker-compose logs web可以查看web服务每个实例的日志

5.修改下nginx.conf的配置,改为新的web容器名称,注释掉我们原来的credit-facility容器

user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65; server {
listen 80;
location / {
proxy_pass http://balance;
}
} upstream balance{
# server credit-facility01:8080;
# server credit-facility02:8080 ;
# server credit-facility03:8080;
server credit-facility_web_1:8080;
server credit-facility_web_2:8080;
server credit-facility_web_3:8080;
}
include /etc/nginx/conf.d/*.conf;
}

6.重启nginx服务

[root@localhost nginx]# docker restart credit-facility-nginx
credit-facility-nginx

7.通过Postman测试WEB服务

请求Url输入你宿主机ip,请求方式是POST,在请求body输入以下请求数据:

{
"registrationLimitCO": {
"applicationId": "1111",
"userId": 1111,
"quotaLimit": 10000,
"productCode": "tb",
"expirationTime": "2030-01-01",
"accountType": 1
} }

Docker深入浅出系列 | Docker Compose多容器实战

从上面相应结果可以看到,服务处理成功


附录

引用

Docker Compose官方文档:官方文档

Demo项目地址:Demo下载

Q&A

1.docker-compose up启动报错

[root@localhost credit-facility]# docker-compose up
ERROR: Named volume "credit-facility-volume:/var/lib/mysql:rw" is used in service "mysql" but no declaration was found in the volumes section.

解决方案:

这是因为缺少Volume声明,在docker-compose.yml按如下配置(上文的配置文件已经配置好)

- "credit-facility-volume:/var/lib/mysql:rw"
volumes:
credit-facility-volume: {}

2.credit-facility-service在服务器上启动报错

先确定你是否已经切换到docker分支,并且本地构建可以成功,然后再打包部署


有兴趣的朋友,欢迎加我公众号一起交流,有问题可以留言,平时工作比较忙,我也抽时间尽量回复每位朋友的留言,谢谢!

Docker深入浅出系列 | Docker Compose多容器实战