当前位置: 首页 > news >正文

循序渐进Docker Compose

文章目录

  • 1.概述
    • 1.1 Docker Compose 定义
    • 1.2 Docker Compose背景
    • 1.3 Docker Compose核心概念
  • 2.安装
    • 2.1 Official Repos
    • 2.2 Manual Installation
    • 2.3 v1.x 兼容性
  • 3. YAML 配置说明
    • 3.1 Services
    • 3.2 Volumes & Networks
  • 4. 解析 Service
    • 4.1 Pulling一个Image
    • 4.2 Building一个Image
    • 4.3 Configuring the Networking
    • 4.4 设置卷
    • 4.5 声明依赖关系
  • 5. 管理环境变量
  • 6. Scaling & Replicas
  • 7. 生命周期管理
    • 7.1. Startup
    • 7.2. Shutdown
  • 8. Docker compose示例
    • 8.1 Single service
    • 8.2 Multiple Service
    • 8.3 启动多个compose project

1.概述

1.1 Docker Compose 定义

Docker Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器

1.2 Docker Compose背景

我们使用 Docker 的时候,定义 Dockerfile 文件,然后使用 docker build、docker run 等命令操作容器。然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,那么效率之低,维护量之大可想而知。
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。.Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器,Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。
注意,为变量输入数据时,必须遵循标准 YAML 规则。 对于包含特殊字符的密码,需要正确转义它们($ 是转义字符)或正确引用变量。 如果不知道如何执行此操作或不愿意研究,最好的做法是仅使用字母数字字符。

1.3 Docker Compose核心概念

Docker Compose将所管理的容器分为三层,分别是:

  • 项目(project)
  • 服务(service)
  • 容器(containner)
    我们将通过后续的章节理解这三层的意思或用途

2.安装

2.1 Official Repos

从版本 2 开始,Docker 开始将 docker compose 发布为基于 Go 的 Docker 插件(而不是基于 Python 的独立二进制文件)。并且为多个架构发布了这个插件,而 v1.x 版本的二进制文件仅适用于 x86_64 架构。
按照此处描述从官方仓库安装 Docker,确保在此过程中安装 docker-compose-plugin 软件包。

2.2 Manual Installation

通过以下命令手动安装 docker compose:

mkdir -p "$HOME/.docker/cli-plugins" 
curl -sL "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o "$HOME/.docker/cli-plugins/docker-compose" 
chmod +x $HOME/.docker/cli-plugins/docker-compose

在系统范围内安装,可以使用 /usr/local/lib/docker/cli-plugins 而不是 $HOME/.docker/cli-plugins
如果已经安装了 docker(或至少安装了 docker-cli),最好是从官仓 安装compose,运行 docker compose version 将显示 compose 版本。

./docker-compose version
Docker Compose version v2.27.0

2.3 v1.x 兼容性

由于 v2 作为插件运行而不是独立的二进制文件,它通过 docker compose args 而不是 docker-compose args调用。
Docker 在推出 v2 作为插件运行后,为了帮助用户更顺利地从 v1 迁移到 v2,提供了一个新的适用于 x86_64 和 aarch64 平台的docker-compose 二进制文件以兼容原有的命令调用方式。例如:

  • 以插件方式运行comose:
docker compose version
Docker Compose version v2.27.0
  • 兼容命令方式:
/home/docker/.docker/cli-plugins/docker-compose version
Docker Compose version v2.27.0

3. YAML 配置说明

简而言之,Docker Compose 通过应用在单个 docker-compose.yml 配置文件中声明的许多规则来工作。
几乎每个规则都替换了特定的 Docker 命令,因此最终只需要运行:

docker-compose up

使用 Docker Compose 可以应用大量的配置,而这些配置是由 Compose 在后台处理的, 这省去用 Bash 或其他东西编写脚本的麻烦。

在此文件中,我们需要指定至少一项服务以及可选的卷和网络:

version: "3.7"
services:...
volumes:...
networks:...

3.1 Services

首先,服务指的是容器的配置.
例如,以一个由前端、后端和数据库组成的 Docker 化 Web 应用程序为例。 可能会将这些组件拆分为三个映像,并在配置中将它们定义为三个不同的服务:

services:frontend:image: my-vue-app...backend:image: my-springboot-app...db:image: postgres...

3.2 Volumes & Networks

卷是主机和容器之间甚至容器之间共享的磁盘空间的物理区域。 换句话说,卷是主机中的共享目录,对某些或所有容器可见。
同样,网络定义了容器之间以及容器与主机之间的通信规则。 Common network zones(公共网络区域)将使容器的服务可以相互发现,而private zones(私有区域)将它们隔离在虚拟沙箱中。

4. 解析 Service

现在让我们开始检查服务的主要设置。

4.1 Pulling一个Image

有时,Service所需的镜像已经(由我们或其他人)发布在 Docker Hub 或另一个 Docker Registry中。
可以通过来使用 image 属性引用它,在属性中指定镜像名称和标签

services: my-service:image: ubuntu:latest...

4.2 Building一个Image

或者使用dockerfile建置,需要通过读取 Dockerfile构建镜像。
这里使用 build 关键字,将 Dockerfile 的路径作为值传递:

services: my-custom-app:build: /path/to/dockerfile/...

使用 URL 代替路径:

services: my-custom-app:build: https://github.com/my-company/my-project.git

还可以与 build 属性一起指定image名称,该属性将在创建后命名image,后续可供其他服务使用:

services: my-custom-app:build: https://github.com/my-company/my-project.gitimage: my-project-image...

4.3 Configuring the Networking

Docker 容器之间,通过 Docker Compose 隐式创建或通过配置创建的网络进行通信。一个服务可以通过容器名称和端口(例如 network-example-service:80)直接引用同一网络上的另一个服务进行通信,前提是已经通过expose关键字公开端口:

services:network-example-service:image: karthequian/helloworld:latestexpose:- "80"

但是,要从主机访问容器,端口必须通过ports关键字进行映射,映射的format如下:
host_port:container_port

services:network-example-service:image: karthequian/helloworld:latestports:- "80:80"...my-custom-app:image: myapp:latestports:- "8080:3000"...my-custom-app-replica:image: myapp:latestports:- "8081:3000"...

端口 80 现在将在主机上可见,而其他两个容器的 3000 端口将分别在主机的 8080 和 8081 端口上可用

进一步定义额外的虚拟网络来隔离容器:

services:network-example-service:image: karthequian/helloworld:latestnetworks: - my-shared-network...another-service-in-the-same-network:image: alpine:latestnetworks: - my-shared-network...another-service-in-its-own-network:image: alpine:latestnetworks: - my-private-network...
networks:my-shared-network: {}my-private-network: {}

“another-service-in-the-same-network“将能够ping并访问“network-example-service”的端口80,而“another-service-in-its-own-network”则不行。

4.4 设置卷

卷分为三种类型:

  • anonymous(匿名卷)
  • named(命名卷)
  • host(主机卷)
    Docker 管理着匿名卷和命名卷,并自动将它们挂载到主机上自行生成的目录中。虽然在旧版本的 Docker(1.9 之前)中,匿名卷很有用,但现在推荐使用命名卷。主机卷还允许我们指定主机上的一个现有文件夹。。
    我们可以在service级别配置主机卷,并在配置的外层级别配置命名卷,以便后者对其他容器可见,而不仅仅是它们所属的容器可见:
services:volumes-example-service:image: alpine:latestvolumes: - my-named-global-volume:/my-volumes/named-global-volume                     --引用命名卷- /tmp:/my-volumes/host-volume                                               --主机卷- /home:/my-volumes/readonly-host-volume:ro                                  --主机卷...another-volumes-example-service:image: alpine:latest                        volumes:- my-named-global-volume:/another-path/the-same-named-global-volume           --引用命名卷...
volumes:my-named-global-volume:  --定义命名卷

这里,两个容器都将对 my-named-global-volume 共享文件夹具有读/写访问权限,无论它们将其映射到哪个路径。 相反,这两个主机卷将仅可用于volumes-example-service。

主机文件系统的 /tmp 文件夹映射到容器的 /my-volumes/host-volume 文件夹。 文件系统的这一部分是可写的,这意味着容器可以读取也可以写入(和删除)主机中的文件。
通过在规则中附加 :ro 以只读模式挂载卷,就像 /home 文件夹(因为有时候不希望 Docker 容器错误地删除用戶的home目录)。

4.5 声明依赖关系

通常,如果需要在服务之间创建依赖链,以便某些服务在其他服务之前加载(并在之后卸载)。 则通过depends_on关键字来实现这个结果:

services:kafka:image: wurstmeister/kafka:2.11-0.11.0.3depends_on:- zookeeper...zookeeper:image: wurstmeister/zookeeper

不过要注意,Compose 不会等待 Zookeeper 服务加载完成才启动 kafka 服务; 它只是简单的等待它start。 如果我们需要在启动另一个服务之前完全加载一个服务,需要在 Compose 中更深入地控制启动和关闭顺序。

5. 管理环境变量

在 Compose 中使用环境变量非常简单。我们可以定义静态环境变量,也可以使用 ${} 标记来定义动态变量。

services:database: image: "postgres:${POSTGRES_VERSION}"environment:DB: mydbUSER: "${USER}"

有不同的方法可以向 Compose 提供这些值:
例如,一种方法是将它们设置在同一目录中的 .env 文件中,其结构类似于 .properties 文件,key=value:

POSTGRES_VERSION=alpine
USER=foo

否则,在调用命令之前在操作系统中设置变量:

export POSTGRES_VERSION=alpine
export USER=foo
docker-compose up

也可以在 shell 中使用简单的一行代码:

POSTGRES_VERSION=alpine USER=foo docker-compose up

可以混合使用这些方法,但请记住,Compose 使用以下优先级顺序,用较高优先级覆盖不太重要的内容:

  • 1.Compose file
  • 2.Shell environment variables
  • 3.Environment file
  • 4.Dockerfile
  • 5.Variable not defined

6. Scaling & Replicas

在较旧的 Compose 版本中,可以通过 docker-compose scale 命令来扩展容器实例。较新的版本废弃了这个命令,并用 --scale 选项取而代之。
利用 Docker Swarm(一个 Docker 引擎的集群),并通过 deploy 部分的 replicas 属性声明性地自动扩展容器。

services:worker:image: dockersamples/examplevotingapp_workernetworks:- frontend- backenddeploy:mode: replicatedreplicas: 6resources:limits:cpus: '0.50'memory: 50Mreservations:cpus: '0.25'memory: 20M

在 deploy 部分,还可以指定许多其他选项,例如资源阈值。然而,Compose 仅在部署到 Swarm 时才考虑整个 deploy 部分,否则会忽略它。

7. 生命周期管理

Docker Compose 的语法:

docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]

有许多可用的选项和命令,但至少需要知道正确active和deactive整个系统的选项和命令。

7.1. Startup

可以使用 up 命令来创建和启动配置中定义的容器、网络和卷。

docker-compose up

在第一次之后,可以简单地使用 start 命令来启动服务

docker-compose start

如果文件的名称与默认文件名 (docker-compose.yml) 不同,可以利用 -f 和 ––file 标志来指定备用文件名:

docker-compose -f custom-compose-file.yml start

使用 -d 选项启动时,Compose 还可以作为守护进程在后台运行:

docker-compose up -d

7.2. Shutdown

为了安全地停止活动服务,可以使用 stop,它将保留容器、卷和网络,以及对它们所做的每项修改:

docker-compose stop

要重置项目的状态,可以运行 down 命令。运行 down 命令会删除由 docker-compose.yml 文件定义的所有服务、网络和容器,但会保留外部卷(如果有的话)

docker-compose down

8. Docker compose示例

8.1 Single service

以下是使用 docker compose 部署 single service的基本示例:

services:heimdall:image: linuxserver/heimdallcontainer_name: heimdallvolumes:- /home/user/appdata/heimdall:/configenvironment:- PUID=1000- PGID=1000- TZ=Europe/Londonports:- 10080:80- 10443:443restart: unless-stopped

如果将上述代码片段保存在名为 compose.yml 的文件中,则只需从同一文件夹中运行 docker compose up -d 即可自动拉取 heimdall 映像,并创建并启动一个容器。 up 表示创建并启动服务,-d 表示在后台执行。
如果从不同的文件夹执行操作,或者 yaml 文件命名为其他名字,例如 heimdall.yml,那么需要在命令中使用 -f 选项:

docker compose -f /path/to/single_service.yml up -d。

docker compose ls将列出running状态的服务,如果要列出包含“非running状态”,需要搭配-a 选项

docker compose ls
NAME                STATUS              CONFIG FILES
docker              running(1)          /home/docker/single_service.yaml

8.2 Multiple Service

以下是使用 docker compose 部署 multiple service的基本示例:
可以通过一个单一的 compose yaml 文件来管理多个服务。将以下内容复制.yml 文件中,然后使用 docker-compose up/down 命令就可以同时对所有服务进行操作。

services:heimdall:image: linuxserver/heimdallcontainer_name: heimdallvolumes:- /home/user/appdata/heimdall:/configenvironment:- PUID=1000- PGID=1000- TZ=Europe/Londonports:- 80:80- 443:443restart: unless-stoppednginx:image: linuxserver/nginxcontainer_name: nginxenvironment:- PUID=1000- PGID=1000- TZ=Europe/Londonvolumes:- /home/user/appdata/nginx:/configports:- 81:80- 444:443restart: unless-stoppedmariadb:image: linuxserver/mariadbcontainer_name: mariadbenvironment:- PUID=1000- PGID=1000- MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD- TZ=Europe/Londonvolumes:- /home/user/appdata/mariadb:/configports:- 3306:3306restart: unless-stopped

启动yaml档:

docker compose -f /home/docker/multi_service.yaml up -d
[+] Running 3/3✔ Container nginx     Running                                                                                                                                                                                 0.0s✔ Container heimdall  Running                                                                                                                                                                                 0.0s✔ Container mariadb   Started 

查看compose项目运行状况

docker@anzfam:~$ docker compose ls -a
NAME                STATUS              CONFIG FILES
docker              running(3)          /home/docker/multi_service.yaml

查看compose包含的服务

docker@anzfam:~$ docker compose config --services
heimdall
mariadb
nginx

查看compose所拥有的容器

docker container ls -a
CONTAINER ID   IMAGE                  COMMAND   CREATED          STATUS              PORTS                                                                                NAMES
dcbf3af2c44e   linuxserver/heimdall   "/init"   19 minutes ago   Up 19 minutes       0.0.0.0:10080->80/tcp, :::10080->80/tcp, 0.0.0.0:10443->443/tcp, :::10443->443/tcp   heimdall
a3939bcca133   linuxserver/nginx      "/init"   19 minutes ago   Up 19 minutes       0.0.0.0:10081->80/tcp, :::10081->80/tcp, 0.0.0.0:10444->443/tcp, :::10444->443/tcp   nginx
59b322021f3a   linuxserver/mariadb    "/init"   19 minutes ago   Up About a minute   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp                                            mariadb

从上述输出结果来看,已经定义了 3 个服务:heimdall、nginx 和 mariadb,并与之对应有三个container运行,当执行 docker compose up -d 时,它将首先下载所有三个容器的映像(如果它们不存在)(如果存在,则不会更新),然后它将创建所有三个容器并启动它们。 docker compose down 将关闭所有三个服务并销毁容器(持久数据将保留)。

8.3 启动多个compose project

前面讲到docker compose将整个结构分为project、service以及container三层,如果想要在同一台主机上启动多个yaml档项目,需要指定-p选项来指定project name,否则docker将默认project name为docker,如此当分别启动上述两个示例时,可能会产生冲突

启动single_service.yaml,并命名为single-service-example

 docker compose -f ./single_service.yaml -p single-service-example up -d
[+] Running 2/2✔ Network single-service-example_default  Created                                                                                                                                                                                      0.1s✔ Container heimdall01                    Started 

启动multi_service.yaml,并命名为multi-service-example

docker compose -f ./multi_service.yaml -p multi-service-example up -d
[+] Running 4/4✔ Network multi-service-example_default  Created                                                                                                                                                                                       0.1s✔ Container nginx                        Started                                                                                                                                                                                       1.9s✔ Container mariadb                      Started                                                                                                                                                                                       1.5s✔ Container heimdall02                   Started 

查看结果显示这里已经有两个不同yaml档建立的project

docker@anzfam:~$ docker compose ls -a
NAME                     STATUS              CONFIG FILES
multi-service-example    running(3)          /home/docker/multi_service.yaml
single-service-example   running(1)          /home/docker/single_service.yaml

相关文章:

  • SEC批准以太坊ETF了吗?
  • react 使用 Reducer 和 Context 进行纵向扩展
  • 安全攻防三
  • 29【PS 作图】宫灯 夜景转换
  • SCP收容物191~200
  • [Android]将私钥(.pk8)和公钥证书(.pem/.crt)合并成一个PKCS#12格式的密钥库文件
  • 周末总结(2024/05/25)
  • spring cloud config server源码学习(一)
  • 用天工AI写文章,节约了8个人的成本
  • 前端Vue小兔鲜儿电商项目实战Day01
  • 7个靠谱的副业赚钱方法,宝妈,上班族,学生党可以做的兼职副业
  • Debug-011-ES6中的链判断运算符(?.)
  • 前端自动将 HTTP 请求升级为 HTTPS 请求
  • Vue3实战笔记(37)—粒子特效登录页面
  • React@16.x(11)ref
  • .pyc 想到的一些问题
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • go append函数以及写入
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • Logstash 参考指南(目录)
  • node和express搭建代理服务器(源码)
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • 翻译:Hystrix - How To Use
  • 工作手记之html2canvas使用概述
  • 计算机在识别图像时“看到”了什么?
  • 记录:CentOS7.2配置LNMP环境记录
  • 为视图添加丝滑的水波纹
  • MyCAT水平分库
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #php的pecl工具#
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (C++20) consteval立即函数
  • (补)B+树一些思想
  • (第27天)Oracle 数据泵转换分区表
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (含笔试题)深度解析数据在内存中的存储
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (三)docker:Dockerfile构建容器运行jar包
  • (转)Google的Objective-C编码规范
  • (转)平衡树
  • (转)项目管理杂谈-我所期望的新人
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .NET Framework与.NET Framework SDK有什么不同?
  • .Net Redis的秒杀Dome和异步执行
  • .NET 中让 Task 支持带超时的异步等待
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .Net各种迷惑命名解释
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • [ C++ ] STL---stack与queue