「docker」学习笔记 | 容器编排之Docker Compose
why docker-compose?
为什么需要用到编排工具?
当我们的业务越来越复杂时,需要多个容器相互配合,甚至需要多个主机组成容器集群才能满足我们的业务需求,这个时候就需要用到容器的编排工具了。Docker三种常用的编排工具:Docker Compose、Docker Swarm和Kubernetes。了解这些编排工具,可以让你在不同的环境中选择最优的编排框架。
容器编排工具的优点
- 批量地创建、调度和管理容器,帮助我们解决容器的部署问题。
Docker Compose 的前世今生
Docker Compose 项目是Docker官方的开源项目,负责实现对 Docker 容器集群的快速编排。
Docker Compose 的前身是 Orchard 公司开发的 Fig,2014 年 Docker 收购了 Orchard 公司,然后将 Fig 重命名为 Docker Compose。现阶段 Docker Compose 是 Docker 官方的单机多容器管理系统,它本质是一个 Python 脚本,它通过解析用户编写的 yaml 文件,调用 Docker API 实现动态的创建和管理多个容器。
Linux系统下安装Docker Compose
macOS 系统下通常以Docker桌面版本的形式安装 docker,桌面版安装之后就默认已安装了docker compose。下面介绍其他 Linux 系统下的安装流程:
-
使用 curl 命令(一种发送 http 请求的命令行工具)下载 Docker Compose 的安装包:
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
-
修改 Docker Compose 执行权限:
sudo chmod +x /usr/local/bin/docker-compose
-
检查 Docker Compose 是否安装成功:
docker-compose --version # docker-compose version 1.27.3, build 4092ae5d
Docker Compose 模板文件的介绍
在使用 Docker Compose 之前,我们首先需要先编写 Docker Compose 模板文件,因为 Docker Compose 运行的时候是根据 Docker Compose 模板文件中的定义来运行的。
在使用 Docker Compose 启动容器时, Docker Compose 会默认使用docker-compose.yml
文件, docker-compose.yml 文件的格式为 yaml(类似于 json,一种标记语言)。
Docker Compose 文件主要分为三部分: services(服务)、networks(网络) 和 volumes(数据卷)。
- services(服务):服务定义了容器启动的各项配置,就像我们执行
docker run
命令时传递的容器启动的参数一样,指定了容器应该如何启动,例如容器的启动参数,容器的镜像和环境变量等。 - networks(网络):网络定义了容器的网络配置,就像我们执行
docker network create
命令创建网络配置一样。 - volumes(数据卷):数据卷定义了容器的卷配置,就像我们执行
docker volume create
命令创建数据卷一样。
/各个参数之间的层级关系图-By Billie/
1. version
Docker Compose 模板文件一共有三个版本: v1、v2 和 v3。目前最新的版本为 v3,也是功能最全面的一个版本。
2. services
services下,首先需要定义服务名称,例如nginx服务,便可以命名为nginx,格式如下
version: "3"
services:
nginx:
...
-
images
- 指定容器镜像的地址 -
volumes
- 不仅可以挂载主机数据卷到容器中,也可以直接挂载主机的目录到容器中,使用方式类似于使用docker run
启动容器时添加-v参数 -
networks
- 这是服务要使用的网络名称,对应顶级的networks中的配置 -
build
- 用于构建docker镜像,类似于docker build
命令,build可以指定Dockerfile文件路径,然后根据Dockerfile命令来构建文件 -
cap_add
\cap_drop
- 指定容器可以使用到哪些内核能力(capabilities) -
command
- 用于覆盖容器默认的启动命令,和Dockerfile中的CMD用法类似 -
container_name
- 用于指定容器启动时容器的名称 -
depends_on
- 用于指定服务间的依赖关系,这样可以先启动被依赖的服务,例如,我们的服务依赖数据库服务 db,可以指定 depends_on 为 db -
devices
- 挂载主机的设备到容器中 -
dns
- 自定义容器中的dns配置 -
dns_search
- 配置dns的搜索域 -
entrypoint
- 覆盖容器的entrypoint命令 -
env_file
- 指定容器的 环境变量文件,启动时会把文件中的环境变量值注入容器中 -
environment
- 指定容器启动时的环境变量 -
pid
- 共享主机的进程命名空间,像在主机上的直接启动进程一样,可以看到主机的进程信息 -
ports
- 暴露端口信息,使用格式为HOST:CONTAINER,前面填写要映射到主机上的端口,后面填写对应的容器内的端口
3. volumes
如果你想在多个容器间共享数据卷,则需要在外部声明数据卷,然后在容器里声明使用数据卷。例如我想在两个服务间共享日志目录,则使用以下配置:
version: "3"
services:
my-service1:
image: service:v1
volumes:
- type: volume
source: logdata
target: /var/log/mylog
my-service2:
image: service:v2
volumes:
- type: volume
source: logdata
target: /var/log/mylog
volumes:
logdata:
4. netwoks
Docker Compose 文件顶级声明的 networks 允许你创建自定义的网络,类似于docker network create
命令。
例如你想声明一个自定义 bridge 网络配置,并且在服务中使用它,使用格式如下:
version: "3"
services:
web:
networks:
mybridge:
ipv4_address: 172.16.1.11
networks:
mybridge:
driver: bridge
ipam:
driver: default
config:
subnet: 172.16.1.0/24
编写 Docker Compose 模板文件
1. command指令
方式1: /bin/bash -c 字符串方式
command: /bin/bash -c "uwsgi --ini ./web_flask/uwsgi.ini && python3 run.py"
在这个示例中,sh -c
允许您在一个命令中执行多个命令。&&
符号表示仅在第一个命令成功执行后才执行第二个命令。
多条命令之间使用&&
符号连接,并且此方式为串行运行,后一条命令需等前一条命令结束之后才会执行。
方式2: /bin/bash -c 配置文件方式
-
串行
command: - sh - -c - cmd1 cmd2 cmd3
如上配置会按顺序执行cmd1,之后再执行cmd2,之后cmd3。对于可以串行的命令,这样即可。
-
并行
有时候想配置几个常驻脚本在docker,希望这几个 脚本一起跑起来(并行运行)
command: - sh - -c - cmd1 & cmd2 & cmd3
上面cmd 都是要求常驻的,没有顺序要求,那么在命令中,前面的几个都加上
&
,最后一个命令不加,也就是前面几个扔后台运行,最后一个直接运行,使得docker 和最后一个cmd 一样“生命周期”,这样就做到几个cmd 并行运行了。如果每条命令结尾都加上
&
,其实是不正确的,docker 运行起来,就马上结束了。猜测是像程序开发的开多线程一样,“主线程开了线程,不等线程,自己就退出了,由于主线程退出,进程也跟着退出了,导致一个线程都没有跑起来”。
2. restart指令
代码示例:
version: '3'
services:
redis-server:
image: 'redis'
node-app:
restart: unless-stopped
build: .
ports:
- "4001:8081"
- 不 -
restart: 'no'
,这意味着如果容器停止或崩溃,永远不要尝试重新启动容器。记得给单引号'no'
因为在 yaml 文件中,如果我们给no
不带引号,它会被视为 false。 - 总是 -
restart: always
,如果我们的容器因任何原因停止,请始终尝试重新启动停止的容器。 - 故障 -
restart: on-failure
,仅当容器因错误代码停止时才重新启动。 - 除非停止 -
restart: unless-stopped
,除非开发人员强行停止该过程,否则始终重新启动。
docker-compose 操作命令
使用docker-compose -h
命令用于查看 docker-compose 的用法,docker-compose 的基本使用格式如下:
docker-compose [-f <arg>...] [options] [--] [COMMAND] [ARGS...]
其中 options 是 docker-compose 的参数,支持的参数和功能说明如下:
-f, –file FILE | 指定 docker-compose 文件,默认为 docker-compose.yml |
-p, –project-name NAME | 指定项目名称,默认使用当前目录名称作为项目名称 |
–verbose | 输出调试信息 |
–log-level LEVEL | 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
-v, –version | 输出当前版本并退出 |
-H, –host HOST | 指定要连接的 Docker 地址 |
–tls | 启用 TLS 认证 |
–tlscacert CA_PATH | TLS CA 证书路径 |
–tlscert CLIENT_CERT_PATH | TLS 公钥证书问价 |
–tlskey TLS_KEY_PATH | TLS 私钥证书文件 |
–tlsverify | 使用 TLS 校验对端 |
–skip-hostname-check | 不校验主机名 |
–project-directory PATH | 指定工作目录,默认是 Compose 文件所在路径。 |
COMMAND 为 docker-compose 支持的命令。支持的命令如下:
build | 构建服务 |
config | 校验和查看 Compose 文件 |
create | 创建服务 |
down | 停止服务,并且删除相关资源 |
events | 实时监控容器的时间信息 |
exec | 在一个运行的容器中运行指定命令 |
help | 获取帮助 |
images | 列出镜像 |
kill | 杀死容器 |
logs | 查看容器输出 |
pause | 暂停容器 |
port | 打印容器端口所映射出的公共端口 |
ps | 列出项目中的容器列表 |
pull | 拉取服务中的所有镜像 |
push | 推送服务中的所有镜像 |
restart | 重启服务 |
rm | 删除项目中已经停止的容器 |
run | 在指定服务上运行一个命令 |
scale | 设置服务运行的容器个数 |
start | 启动服务 |
stop | 停止服务 |
top | 限制服务中正在运行中的进程信息 |
unpause | 恢复暂停的容器 |
up | 创建并且启动服务 |
version | 打印版本信息并退出 |
编程
1. 在结束时执行指定任务
为了确保在容器停止时生成的静态文件是最新的,您可以使用trap
命令在脚本中捕获SIGTERM
信号。当Docker容器收到SIGTERM
信号时,它将优雅地关闭并执行清理任务。
请按照以下步骤操作:
- 在您的项目目录中创建一个名为
start.sh
的脚本,并添加以下内容:
bashCopy code
#!/bin/sh
# 定义一个函数来处理SIGTERM信号
shutdown_handler() {
echo "SIGTERM received, generating static files and stopping the server..."
hugo -D
pkill hugo
}
# 设置一个信号捕获器来监听SIGTERM信号
trap shutdown_handler SIGTERM
# 运行Hugo服务器
hugo server --bind 0.0.0.0 -w
# 等待所有子进程完成
wait
- 为
start.sh
脚本添加可执行权限。在项目目录中执行以下命令:
bashCopy code
chmod +x start.sh
- 修改您的
docker-compose.yaml
文件,以引用新创建的start.sh
脚本。假设您的服务名称是your_service
,则docker-compose.yaml
文件应如下所示:
yamlCopy code
version: '3.8'
services:
your_service:
build: .
ports:
- "本地端口:容器端口"
command: ./start.sh
现在,当您通过docker-compose down
或类似命令停止容器时,shutdown_handler
函数将捕获SIGTERM
信号,生成静态文件,然后停止Hugo服务器。
结语
Docker Compose 是一个用来定义复杂应用的单机编排工具,通常用于服务依赖关系复杂的开发和测试环境,如果你还在为配置复杂的开发环境而烦恼,Docker Compose 可以轻松帮你搞定复杂的开发环境。你只需要把复杂的开发环境使用 Docker Compose 模板文件描述出来,之后无论你在哪里可以轻松的一键启动开发和测试环境,极大地提高了我们的开发效率,同时也避免了污染我们开发机器的配置。
推荐阅读
项目实践案例请参考: