本文主要是介绍循序渐进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
这篇关于循序渐进Docker Compose的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!