Docker Compose(容器编排)

"这不属于我,谁会愿意生活都被胁迫~"


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文件。

通过页面访问:

停止服务:

重启服务:

删除服务:

释放对应的容器,关闭创建的网络。

常见问题

  1. up、run 和 start 之间有什么区别?

通常 docker compose up用于启动或重新启动 docker-composed.yml。在默认的"附加"模式下,会看到来自所有容器的所有日志。在"分离"模式 ( -d) 中,启动容器后 Compose 退出,但容器继续在后台运行。

docker compose run 命令用于运行"一次性"或"临时"任务。需要运行的服务名称,并且只为这个要运行服务的容器启动。

docker compose start 仅对重新启动先前创建但已停止的容器有用。它从不创建新容器。

  1. 如何在同一主机上运行 Compose 文件的多个副本?

Compose 使用项目名称为项目的所有容器和其他资源创建唯一标识符。
要运行项目的多个副本,请使用-p 命令行选项 或 COMPOSE_PROJECT_NAME 环境变量设置自定义项目名称。

  1. 如何控制服务启动顺序?

通过依赖指定depend_on,并且配合healthcheck等检查健康之后,再将服务启动。


本篇到此结束,感谢你的阅读。

祝你好运,向阳而生~

相关推荐
芯的一天1 分钟前
windows下DockerDesktop命令行方式指定目录安装
windows·docker
是芽芽哩!1 小时前
【Kubernetes】常见面试题汇总(五十八)
云原生·容器·kubernetes
帅气的人1231 小时前
使用 docker-compose 启动 es 集群 + kibana
elasticsearch·docker
獨枭1 小时前
Ubuntu 通过 Docker 搭建 GitLab
ubuntu·docker·gitlab
zixingcai2 小时前
dockertop提示Failed to fetch extensions
docker
雪域迷影11 小时前
PostgreSQL Docker Error – 5432: 地址已被占用
数据库·docker·postgresql
福大大架构师每日一题12 小时前
22.1 k8s不同role级别的服务发现
容器·kubernetes·服务发现
莹雨潇潇12 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
tangdou36909865513 小时前
1分钟搞懂K8S中的NodeSelector
云原生·容器·kubernetes
tangdou36909865515 小时前
Docker系列-5种方案超详细讲解docker数据存储持久化(volume,bind mounts,NFS等)
docker·容器