通常,一个完整的应用都是由多个容器组合而成,我们可以手动的去单独启动和管理每个容器,但是这样会很不方便。Docker Compose是这样的一个应用,它可以方便的帮助我们构建、运行和扩展一套由多个容器组成的应用。
1. 安装Docker Compose
参考Docker的github下载程序:
curl -L https://github.com/docker/compose/releases/download/1.23.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
参考Install command completion添加docker-compose命令自动补全功能:
# 先安装CentOS自己的bash-completion
[root@node2 ~]# yum -y install bash-completion
# 添加Docker Compose的command completion
[root@node2 ~]# curl -L https://raw.githubusercontent.com/docker/compose/1.23.0/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13238 100 13238 0 0 9156 0 0:00:01 0:00:01 --:--:-- 9161
[root@node2 ~]# source /etc/bash_completion.d/docker-compose
2. 使用docker-compose
Docker Compose通过读取docker-compose.yml配置文件,来启动相关的服务。一个docker-compose.yml配置示例如下:
version: "3.5"
services:
web:
image: fundamentalsofdocker/ch08-web:1.0
ports:
- 3000:3000
db:
image: fundamentalsofdocker/ch08-db:1.0
volumes:
- pets-data:/var/lib/postgresql/data
volumes:
pets-data:
上面的配置解释如下:
- version:不同的docker compose有不同的格式,这里我们使用3.5版本格式。
- services:服务,通常由多个容器组合而成。
- web:容器的名称。同时还指定该容器使用哪个镜像(该镜像需要存在于仓库中,这里是docker hub),开放的端口。
- db:数据库容器的名称。同时也指定了相应的镜像,以及挂载的数据卷与容器对应目录的关系。
- volumes:创建的数据卷。
Tips:容器之间可以通过上面定义的容器名,来进行数据通信交互。
进入到该docker-compose.yml所在的目录,这里是compose-test
目录,通过docker-compose up
命令启动服务:
[root@node2 compose-test]# docker-compose up
Creating network "compose-test_default" with the default driver
Creating volume "compose-test_pets-data" with default driver
Pulling web (fundamentalsofdocker/ch08-web:1.0)...
1.0: Pulling from fundamentalsofdocker/ch08-web
605ce1bd3f31: Pull complete
188ade417c9f: Pull complete
ad8771290e5e: Pull complete
Pulling db (fundamentalsofdocker/ch08-db:1.0)...
Pulling db (fundamentalsofdocker/ch08-db:1.0)...
1.0: Pulling from fundamentalsofdocker/ch08-db
ff3a5c916c92: Pull complete
ac3385cd756f: Pull complete
Creating compose-test_web_1_1c7e1b7ce98c ... done
Creating compose-test_db_1_14e7442081f6 ... done
Attaching to compose-test_web_1_ec5cf32a5b62, compose-test_db_1_785716b0e082
...
db_1_785716b0e082 | 2018-10-31 01:56:00.122 UTC [20] LOG: database system was shut down at 2018-10-31 01:55:42 UTC
db_1_785716b0e082 | 2018-10-31 01:56:00.144 UTC [1] LOG: database system is ready to accept connections
web_1_ec5cf32a5b62 | Listening at 0.0.0.0:3000
web_1_ec5cf32a5b62 | Connecting to DB
web_1_ec5cf32a5b62 | Connected!
...以上输出内容省略了部分
简单说明一下:上面的过程分两步,一是拉取镜像。二是启动服务,并打印日志。
启动完成后,通过浏览器访问http://主机IP:3000/pet
,可以查看服务。
按Ctrl+C可结束服务并退出。再次运行时,速度会快很多,因为不用再拉取镜像,相关的数据卷也已经创建完毕。
将服务放在后台运行:
[root@node2 compose-test]# docker-compose up -d
Starting compose-test_web_1_ec5cf32a5b62 ... done
Starting compose-test_db_1_785716b0e082 ... done
查看docker compose进程:
[root@node2 compose-test]# docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------------
compose-test_db_1_785716b0e082 docker-entrypoint.sh postgres Up 5432/tcp
compose-test_web_1_ec5cf32a5b62 /bin/sh -c node src/server.js Up 0.0.0.0:3000->3000/tcp
关闭服务:
[root@node2 compose-test]# docker-compose down
Stopping compose-test_db_1_785716b0e082 ... done
Stopping compose-test_web_1_ec5cf32a5b62 ... done
Removing compose-test_db_1_785716b0e082 ... done
Removing compose-test_web_1_ec5cf32a5b62 ... done
Removing network compose-test_default
Tips:你会发现停止web服务总是比较慢,那是因为db服务能够正确的响应系统发出的SIGTERM信号,正常停止服务。而web不会,所以docker在10秒超时后,强制停用了它。
3. 可伸缩的docker compose服务
当我们上面的服务中,一个web服务形成瓶颈的时候,我们可以快速地的扩充几个web服务出来。命令如下:
[root@node2 compose-test]# docker-compose up --scale web=3
Creating network "compose-test_default" with the default driver
Creating volume "compose-test_pets-data" with default driver
WARNING: The "web" service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash.
Creating compose-test_db_1_4a3325f40a66 ... done
Creating compose-test_web_1_34a682b911cd ... done
Creating compose-test_web_2_d1270f3e5ab6 ... error
Creating compose-test_web_3_4eee803fe1dc ... error
ERROR: for compose-test_web_2_d1270f3e5ab6 Cannot start service web: driver failed programming external connectivity on endpoint compose-test_web_2_b339ca2150cf (f9b0c19850ea1218bfa73e96df65e8c048b2936504c2f07baa85a66bbaa304e0): Bind for 0.0.0.0:3000 failed: port is already allocated
ERROR: for compose-test_web_3_4eee803fe1dc Cannot start service web: driver failed programming external connectivity on endpoint compose-test_web_3_af3222197ecd (101305704ef4a4da659f0aaa53931a8ef7aa103e7a9fc4b3806c98f7a76a2911): Bind for 0.0.0.0:3000 failed: port is already allocated
ERROR: for web Cannot start service web: driver failed programming external connectivity on endpoint compose-test_web_2_b339ca2150cf (f9b0c19850ea1218bfa73e96df65e8c048b2936504c2f07baa85a66bbaa304e0): Bind for 0.0.0.0:3000 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
我们发现当创建第二和第三个web服务的时候,发生了错误,主要是因为端口冲突问题。我们在docker-compose.yml
中指定端口映射的部分进行修改,让主机随机启动三个端口进行映射即可:
version: "3.5"
services:
web:
image: fundamentalsofdocker/ch08-web:1.0
ports:
- 3000
db:
image: fundamentalsofdocker/ch08-db:1.0
volumes:
- pets-data:/var/lib/postgresql/data
volumes:
pets-data:
再次启动:
# 先关闭刚才启动的(虽然没有完全启动成功)
[root@node2 compose-test]# docker-compose down
[root@node2 compose-test]# docker-compose up -d --scale web=3
Creating network "compose-test_default" with the default driver
Creating compose-test_db_1_6a526a0954dc ... done
Creating compose-test_web_1_5f57a97855bf ... done
Creating compose-test_web_2_37757fe7fff7 ... done
Creating compose-test_web_3_5db14966adca ... done
查看:
[root@node2 compose-test]# docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------------
compose-test_db_1_a2388d8552ee docker-entrypoint.sh postgres Up 5432/tcp
compose-test_web_1_5445bb723cbe /bin/sh -c node src/server.js Up 0.0.0.0:32772->3000/tcp
compose-test_web_2_9253be834670 /bin/sh -c node src/server.js Up 0.0.0.0:32773->3000/tcp
compose-test_web_3_c4178b44052d /bin/sh -c node src/server.js Up 0.0.0.0:32774->3000/tcp