"这不属于我,谁会愿意生活都被胁迫~"
Docker Compose(容器编排)
什么是容器编排?
docker-compose是Docker 官方的开源项目,使用 python 编写,实现上调用了Docker 服务的 API 进行容器管理及编排。其官方定义为定义和运行多个 Docker 容器的应用。
在docker-compose中存在两个重要的概念:
• 服务(service): 指的是一个应用的容器,一个服务内部可以包含若干容器。
• 项目(project): 由一组关联的应用容器组成的一个完整业务单元,在 dockercompose.yml文件中定义, 整个 docker-compose.yml 定义一个项目。
Compose的默认管理对象是项目,通过子命令对项目中的各个容器进行便捷地生命周期管理。
通过 compose 可以方便的管理多个服务。
为什么需要Docker Compose?
Docker本质是一个轻量化的进程。Docker 官方推荐每个 Docker 容器中只运行一个进程**。** 但一个应用如果涉及到Mysql、nginx等环境,那么我们需要分别为应用创建单独的数据库和nginx容器。按照这个步骤,我们大概需要敲击几次 "docker run"命令,让这些服务能够有序地启动。你启动几个容器尚能应付,但如果要部署许多容器呢?这么做肯定是繁琐的。
另外,这些 docker 容器都是分散独立的,也不方便镜像管理。可是,这些服务的应用是唯一的,我们干脆将这些过程 "打包",一次性解决。这便引出了dockercompose 来解决。
Docker Compose安装
安装 docker 的时候,我们默认已经安装了 docker-compose,安装的组件包名称为docker-compose-plugin,此处不再赘述。
Docker Compose功能
使用步骤:
🎨 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
🎨 最后,执行 docker compose up 命令来启动并运行整个应用程序
核心功能:
• 启动,停止和重建服务
• 查看正在运行的服务的状态
• 流式传输运行服务的日志输出
• 在服务上运行一次性命令
使用场景:
✨ 单主机部署:快速搭建一个单节点开发或者测试环境,方便使用。
**✨**不同环境隔离: 通过指定 project 来运行不同的环境,实现隔离的目的。
Docker Compose 文件
目前官方支持三个大的版本 Version 1、Version 2 及 Version 3,不过Version 1 已经被废弃掉了。当前最新的版本是3.8,这个我们可以参照官方文档。
文件基本结构及常见指令
本篇也是基于3.8版本Compose file语法进行讲解:
bash
# 定义版本, 表示当前使用的 docker-compose 语法的版本
version: "3.8"
# 服务,可以存在多个
services
# 服务名字,它也是内部 bridge 网络可以使用的 DNS name
servicename
# 镜像的名字
image
# 如果设置,则会覆盖默认镜像里的 CMD 命令
command
# 等价于 docker container run 里的 --env 选项设置环境变量
environment
# 等价于 docker container run 里的 -v 选项 绑定数据卷
volumes
# 可选,等价于 docker container run 里的 --network 选项指定网络
networks
# 可选,等价于 docker container run 里的 -p 选项指定端口映射
ports
# 可选,指定容器暴露的端口
expose
# 构建目录
build
# 服务依赖配置
depends_on
# 环境变量文件
env_file
常见字段格式语法
🎒 image:
指定容器运行镜像。
bash
# 使用镜像名\镜像名:Tag\镜像ID
image:redis
image:redis:5
image:@sha256:e4720093a3c1381245b53a5a51b417963b3c4472d3f47fc301930a4f3b17666a
🎒 command
覆盖容器启动的默认命令。
bash
command: ["bundle", "exec", "thin", "-p", "3000"]
command: bundle exec thin -p 3000
🎒 entrypoint
覆盖容器默认的 entrypoint。
bash
entrypoint: /code/entrypoint.sh
🎒 environment
添加环境变量,注意: 使用数组或字典、任何布尔值时,需要用引号引起来。以确保 YML 解析器不会将其转换为 True 或 False
bash
#map 语法
environment:
RACK_ENV: development
SHOW: "true"
USER_INPUT:
#数组语法
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT
🎒 networks
指定容器运行的网络。
配置容器网络:
bash
services:
redis:
image: redis:5.0
networks:
- front-tier
- back-tier
monitor:
image:webapp/monitor
networks:
- font-tier
- back-tier
networks:
front-tier:
back-tier:
配置网络驱动和子网信息:
bash
services:
frontend:
image: awesome/webapp
networks:
front-tier:
ipv4_address: 172.16.238.10
networks:
front-tier:
ipam:
driver:default
config:
- subnet:"172.16.0.0/16"
🎒 volumes
将主机的数据卷或者文件挂载到容器里。
bash
#短语法
services:
nginx:
image: nginx:1.24.0
volumes:
- /localhost/data/webApp/:/usr/share/nginx/html
- /localhost/data:/var/lib/postgresql/data
# 完整语法
services:
backend:
image: awesome/backend
volumes:
# docker管理卷
- type: volume
source: backend_data
target: /data/var/backend/
volume:
nocopy:true
# 绑定卷
- type:bind
source: /data/var/run/backend/
target: /tmp/var/lib/backend
volumes:
backend_data:
🎒 ports
指定端口映射。
bash
#完整语法
ports:
①
- target: 80 # 内部端口
host_ip:127.0.0.1
published: 80 # 暴露端口
protocol: tcp
mode:host
②
- target: 80
host_ip: 127.0.0.1
published: 8000-9000
protocol: tcp
mode: host
#短语法
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
🎒 expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
bash
expose:
- "3000"
- "8000"
🎒 build
指定为构建镜像上下文路径。
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
bash
version:"3.8"
services:
webApp:
build: ./dir
或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:
bash
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
OPTIONS:
context:上下文路径
dockerfile:指定构建镜像的 Dockerfile 文件名
args:添加构建参数,这是只能在构建过程中访问的环境变量
labels:设置构建镜像的标签
🎒 depends_on
设置依赖关系。
🎲 docker compose up: 以依赖性顺序启动服务。
🎲 docker compose up SERVICE: 自动包含 SERVICE 的依赖项。
🎲 docker compose stop: 按依赖关系顺序停止服务。
bash
version:"3.8"
services:
web:
build: .
depend_on:
- db
- redis
redis:
image: redis.6.0
db:
image:mysql:5.7
可以指定条件,healthy 需要配置 healthcheck 来完成。
bash
version: "3.8"
services:
web:
image:nginx:1.24.0
environment:
TEST: 1
depends_on:
mysql:
condition:service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "xxx@123"
volumes:
- /data/var/xxx/database/:/var/lib/mysql
healthcheck:
test: mysql --user=root --password='xxx@123' -e "Select 1";
interval:10s
timeout: 5s
retries: 10
# 注
interval:间隔
timeout: 超时
retries: 重试次数
🎒 env_file
从文件添加环境变量。可以是单个值或列表的多个值。
bash
version: "3.8"
service:
web:/app/docker.io
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
其他指令可以参照官方文档,里面为很多指令提供了详细的解释和使用手册。
Docker Compose使用
命令清单:
|------------------------|----------------------------------------------------------------|
| 命令 | 功能 |
| docker compose build | 构建服务 |
| docker compose config | 规范的格式来显示服务配置,如果yml文件语法出错,会告警 |
| docker compose cp | 在本地系统和服务容器直接拷贝文件 |
| docker compose create | 创建服务的容器 |
| docker compose down | 停止服务中的所有容器,并删除容器 |
| docker compose events | 从服务器获取实时事件 |
| docker compose exec | 在容器中执行命令 |
| docker compose images | 列出所有容器使用的镜像 |
| docker compose kill | 强制停止服务的容器 |
| docker compose logs | 显示日志 |
| docker compose ls | 显示所有项目 |
| docker compose pause | 暂停服务 |
| docker compose port | 列出所有的端口映射 |
| docker compose ps | 该命令可以列出项目中目前的所有容器 |
| docker compose pull | 拉取服务镜像 |
| docker compose push | 推送服务镜像 |
| docker compose restart | 重启或者重启某个服务 |
| docker compose rm | 删除服务停止的容器 |
| docker compose run | 在指定服务容器上执行相关的命令 |
| docker compose start | 启动当前停止的某个容器 |
| docker compose stop | 停止当前运行的某个容器 |
| docker compose top | 显示运行的进程 |
| docker compose unpause | 恢复服务 |
| docker compose up | up 命令会构建,(重新)创建,启动,链接一个服务相关的容器 --no-recreate 参数可以让容器不被停止或者重新创建 |
| docker compose version | 查看版本 |
🎴 up/down/run
• up命令的作用十分强大,它会尝试自动完成包括构建镜像、(重新)创建服务、启动服务并关联服务相关容器的一系列操作,可以直接通过该命令来启动一个项目。
bash
docker compose up [options] [SERVICE...]
options:
• -d 在后台运行服务容器, 推荐在生产环境下使用该选项
• --force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用
• --no-recreate 如果容器已经存在了,则不重新创建,不能与 --forcerecreate 同时使用
• down
停止所有容器,并删除容器和网络。
bash
docker compose down [options] [SERVICE...]
options:
• -v, --volumes 删除容器同时删除目录映射
• run
该命令可以在指定服务容器上执行相关的命令。
bash
docker compose run [options] SERVICE [COMMAND] [ARGS...]
options:
• -d 后台运行容器
• --name NAME 为容器指定一个名字
• --entrypoint CMD 覆盖默认的容器启动指令
• -e KEY=VAL 设置环境变量值,可多次使用选项来设置多个环境变量
• -u, --user="" 指定运行容器的用户名或者 uid
• --rm 运行命令后自动删除容器
• -p, --publish=[] 映射容器端口到本地主机
操作案例
Docker Compose 基本操作
创建 compose 目录,在里面新建yml文件:
打开.yml文件,使用Compose语法编写该文件内容:
输入 docker compose config 会做检查:
我们将这个错误更正后,就可以通过了:
在这个示例中,我们使用到了nginx服务,因为是绑定卷,我们需要给nginx提供新的首页:
完成这些之后,我们直接输入启动服务命令: docker compose up -d:
看到这个动画时,就是docker compose根据咱们些的.yml文件进行容器启动和配置。值得注意的是,你只能在创建.yml目录下执行这条命令,否则这条命令找不到你写的.yml文件。
通过页面访问:
停止服务:
重启服务:
删除服务:
释放对应的容器,关闭创建的网络。
常见问题
- up、run 和 start 之间有什么区别?
通常 docker compose up用于启动或重新启动 docker-composed.yml。在默认的"附加"模式下,会看到来自所有容器的所有日志。在"分离"模式 ( -d) 中,启动容器后 Compose 退出,但容器继续在后台运行。
docker compose run 命令用于运行"一次性"或"临时"任务。需要运行的服务名称,并且只为这个要运行服务的容器启动。
docker compose start 仅对重新启动先前创建但已停止的容器有用。它从不创建新容器。
- 如何在同一主机上运行 Compose 文件的多个副本?
Compose 使用项目名称为项目的所有容器和其他资源创建唯一标识符。
要运行项目的多个副本,请使用-p 命令行选项 或 COMPOSE_PROJECT_NAME 环境变量设置自定义项目名称。
- 如何控制服务启动顺序?
通过依赖指定depend_on,并且配合healthcheck等检查健康之后,再将服务启动。
本篇到此结束,感谢你的阅读。
祝你好运,向阳而生~