docker容器编排利器Docker Compose(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 Tair(兼容Redis),内存型 2GB
简介: docker容器编排利器Docker Compose(一)

Compose 简介

我们可以通过 Dockerfile 文件让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况,例如之前我给大家讲过的《Docker搭建Redis Cluster集群》,或者开发一个 Web 应用,除了 Web 服务容器本身,还需要数据库服务容器、缓存容器,甚至还包括负载均衡容器等等。

Docker Compose 恰好满足了这样的需求,它是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YAML 文件来配置应用程序所需要的服务。然后使用一个命令,就可以通过 YAML 配置文件创建并启动所有服务。

Docker Compose 项目是 Docker 官方的开源项目,来源于之前的 Fig 项目,使用 Python 语言编写。负责实现对 Docker 容器集群的快速编排。项目地址为:https://github.com/docker/compose/releases

Docker Compose 使用的三个步骤为:

  • 使用 Dockerfile 文件定义应用程序的环境;
  • 使用 docker-compose.yml 文件定义构成应用程序的服务,这样它们可以在隔离环境中一起运行;
  • 最后,执行 docker-compose up 命令来创建并启动所有服务。

Compose 安装

下载

官方文档:https://docs.docker.com/compose/install/

您可以在 macOS,Windows 和 Linux 上运行 Compose。本文演示基于 Linux 环境的安装。我们可以使用 curl 命令从 Github 下载它的二进制文件来使用,运行以下命令下载 Docker Compose 的当前稳定版本。或者从网页下载后上传至服务器指定目录 /usr/local/bin 也行。

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

因为 Docker Compose 存放在 GitHub,可能不太稳定。你也可以通过执行下面的命令,高速安装Compose。该加速通道由 DaoCloud 提供:http://get.daocloud.io/#install-compose

curl -L https://get.daocloud.io/docker/compose/releases/download/v2.0.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

你可以通过修改URL中的版本,可以自定义您的需要的版本。

授权

安装完成以后,查看指定目录,发现该文件没有可执行权限,进行授权操作

# 将可执行权限应用于该二进制文件
sudo chmod +x /usr/local/bin/docker-compose

测试

docker-compose --version


[root@centos8 bin]# docker-compose --version
Docker Compose version v2.0.1

卸载

卸载 Compose 非常简单,直接删除二进制文件即可。

sudo rm /usr/local/bin/docker-compose

docker-compose.yml 文件详解

概念

官方文档:https://docs.docker.com/compose/compose-file/

Docker Compose 允许用户通过 docker-compose.yml 文件(YAML 格式)来定义一组相关联的容器为一个工程 (project) 。一个工程包含多个服务 (service) ,每个服务中定义了创建容器时所需的镜像、参数、依赖等。

工程名若无特殊指定,即为 docker-compose.yml 文件所在目录的名称。

Docker Compose 模板文件我们需要关注的顶级配置有 version 、 services 、 networks 、volumes 几个部分,除 version 外,其他几个顶级配置下还有很多下级配置,后面也会详细给大家介绍,先来看看这几个顶级配置都什么意思:

  • version :描述 Compose 文件的版本信息,当前最新版本为 3.8 ,对应的 Docker 版本为v2.0.1
  • services :定义服务,可以多个,每个服务中定义了创建容器时所需的镜像、参数、依赖等
  • networkds :定义网络,可以多个,根据 DNS server 让相同网络中的容器可以直接通过容器名称进行通信
  • volumes :数据卷,用于实现目录挂载

案例

在配置文件中,所有的容器通过 services 来定义,然后使用 docker-compose 脚本来启动,停止和重启容器,非常适合多个容器组合使用进行开发的场景。我们先从一个简单的 Compose 案例学起。

编写 docker-compose.yml 文件。

# 创建目录
mkdir -p /usr/local/docker-nginx
# 切换至指定目录
cd /usr/local/docker-nginx/
# 编写 docker-compose.yml 文件
vi docker-compose.yml

在文件中添加以下内容:

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
        nginx: # 服务名称
                image: nginx # 创建容器时所需的镜像
                container_name: mynginx # 容器名称,默认为"工程名称_服务条目名称_序号"
                ports: # 宿主机与容器的端口映射关系
                        - "8080:80" # 左边宿主机端口:右边容器端口
                networks: # 配置容器连接的网络,引用顶级 networks 下的条目
                        - nginx-net
# 定义网络,可以多个。如果不声明,默认会创建一个网络名称为"工程名称_default"的 bridge 网络
networks:
        nginx-net: # 一个具体网络的条目名称
                name: nginx-net # 网络名称,默认为"工程名称_网络条目名称"
                driver: bridge # 网络模式,默认为 bridge

使用 docker-compose up 创建并启动所有服务。这个简单的案例中就只有一个 Nginx 后续我们会来一些复杂的练习

# 前台启动
docker-compose up
# 后台启动
docker-compose up -d


[root@centos8 docker-nginx]# docker-compose up
[+] Running 1/0
 ⠿ Container mynginx  Created                                                                               0.0s
Attaching to mynginx
mynginx  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
mynginx  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
mynginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
mynginx  | 10-listen-on-ipv6-by-default.sh: info: IPv6 listen already enabled
mynginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
mynginx  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
mynginx  | /docker-entrypoint.sh: Configuration complete; ready for start up
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: using the "epoll" event method
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: nginx/1.21.3
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6) 
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: OS: Linux 4.18.0-305.3.1.el8.x86_64
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker processes
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker process 24
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker process 25
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker process 26
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker process 27
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker process 28
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker process 29
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker process 30
mynginx  | 2021/10/19 06:59:05 [notice] 1#1: start worker process 31

浏览器访问:http://192.168.135.10:8080/ 结果如下:

使用 docker-compose down 可以停止并删除容器、网络。

[root@centos8 docker-nginx]# docker-compose down
[+] Running 2/2
 ⠿ Container mynginx  Removed                                                                               0.0s
 ⠿ Network nginx-net  Removed 

version

描述 Compose 文件的版本信息,当前最新版本为 3.8 ,对应的 Docker 版本为 19.03.0+ 。关于

每个版本的详细信息请参考:https://docs.docker.com/compose/compose-file/compose-versioning/

以下为 Compose 文件的版本信息所对应的 Docker 版本。

image.png

services

刚才我们提到 docker-compose.yml 文件中包含很多下级配置项,下面带大家把一些常用的配置项详细了解一下,先从顶级配置 services 开始。

services 用来定义服务,可以多个,每个服务中定义了创建容器时所需的镜像、参数、依赖等,就像将命令行参数传递给 docker run 一样。同样,网络和数据卷的定义也是一样的。

比如,之前我们通过 docker run 命令构建一个 MySQL 应用容器的命令如下:

docker run -id --name mysql8 -p 3306:3306 -v
/mydata/docker_mysql/conf:/etc/mysql/conf.d -v
/mydata/docker_mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1234 mysql:8

使用 docker-compose.yml 以后则可以这样定义:

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  mysql: # 服务名称
  image: mysql:8 # 创建容器时所需的镜像
  container_name: mysql8 # 容器名称,默认为"工程名称_服务条目名称_序号"
  ports: # 宿主机与容器的端口映射关系
    - "3306:3306" # 左边宿主机端口:右边容器端口
  environment: # 创建容器时所需的环境变量
    MYSQL_ROOT_PASSWORD: 1234
  volumes:
    - "/mydata/docker_mysql/conf:/etc/mysql/conf.d"
    - "/mydata/docker_mysql/data:/var/lib/mysql"

然后通过 dokcer-compose 相关命令即可完成容器的创建,停止或删除等一系列操作。

image

指定创建容器时所需的镜像名称标签或者镜像 ID。如果镜像在本地不存在,会去远程拉取。

services:
  web:
    image: hello-world

build

除了可以基于指定的镜像构建容器,还可以基于 Dockerfile 文件构建,在使用 up 命令时会执行构建任务。

通过 build 配置项可以指定 Dockerfile 所在文件夹的路径。Compose 将会利用 Dockerfile自动构建镜像,然后使用镜像启动服务容器。

build 配置项可以使用绝对路径,也可以使用相对路径。

# 绝对路径,在该路径下基于名称为 Dockerfile 的文件构建镜像
/usr/local/docker-centos
# 相对路径,相对当前 docker-compose.yml 文件所在目录,基于名称为 Dockerfile 的文件构建镜
.

接下来我们来个稍微复杂点的练习,通过基础镜像 centos:7 ,在该镜像中安装 jdk 和 tomcat 以后将其制作为一个新的镜像 mycentos:7 。

创建目录并编写 Dockerfile 文件。

# 创建目录
mkdir -p /usr/local/docker-centos
# 切换至指定目录
cd /usr/local/docker-centos/
# 编写 Dockerfile 文件
vi Dockerfile

Dockerfile 文件内容如下:

# 指明构建的新镜像是来自于 centos:7 基础镜像
FROM centos:7
# 通过镜像标签声明了作者信息
LABEL maintainer="mrhelloworld.com"
# 设置工作目录
WORKDIR /usr/local
# 新镜像构建成功以后创建指定目录
RUN mkdir -p /usr/local/java && mkdir -p /usr/local/tomcat
# 拷贝文件到镜像中并解压
ADD jdk-11.0.6_linux-x64_bin.tar.gz /usr/local/java
ADD apache-tomcat-9.0.37.tar.gz /usr/local/tomcat
# 暴露容器运行时的 8080 监听端口给外部
EXPOSE 8080
# 设置容器内 JAVA_HOME 环境变量
ENV JAVA_HOME /usr/local/java/jdk-11.0.6/
ENV PATH $PATH:$JAVA_HOME/bin
# 启动容器时启动 tomcat 并查看 tomcat 日志信息
CMD ["/usr/local/tomcat/apache-tomcat-9.0.37/bin/catalina.sh", "run"]

将所需的资源包 jdk 和 tomcat 上传至 Dockerfile 同一目录。

创建目录并编写 docker-compose.yml 文件。

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  mycentos: # 服务名称
    build: . # 相对当前 docker-compose.yml 文件所在目录 的文件构建镜像
    container_name: mycentos7 # 容器名称,默认为"工程名称_服务条目名称_序号"
    ports: # 宿主机与容器的端口映射关系
    - "8080:8080" # 左边宿主机端口:右边容器端口

然后通过 dokcer-compose 相关命令即可完成容器的创建,停止或删除等一系列操作。

context

该选项可以是 Dockerfile 文件的绝对/相对路径,也可以是远程 Git 仓库的 URL,当提供的值是相对路径时,相对当前 docker-compose.yml 文件所在目录。

build:
  context: . # 相对当前 docker-compose.yml 文件所在目录,基于名称为 Dockerfile 的文件构建镜像
dockerfile

一般情况下,默认都基于文件名叫 Dockerfile 的文件构建镜像,当然也可以是自定义的文件名,使用 dockerfile 声明,不过这个选项只能声明文件名,文件所在路径还是要通过 centext 来声明。

build:
  context: . # 相对当前 docker-compose.yml 文件所在目录
  dockerfile: Dockerfile-alternate # 基于名称为 Dockerfile-alternate 的文件构建镜像

container_name

Compose 创建的容器默认生成的名称格式为: 工程名称_服务条目名称_序号 。如果要使用自定义名称,使用 container_name 声明。

services:
  mycentos:
  build: .
  container_name: mycentos7 # 容器名称,默认为"工程名称_服务条目名称_序号"

因为 Docker 容器名称必须是唯一的,所以如果指定了自定义名称,就不能将服务扩展至多个容

器。这样做可能会导致错误。

关于序号

序号是干什么用的呢,看下面这个列子你就懂了, docker-compose.yml 文件内容如下:

# 描述 Compose 文件的版本信息
version: "3.8"
  # 定义服务,可以多个
  services:
    helloworld: # 服务名称
    image: hello-world

然后通过 --scale 指定 helloworld 服务一次性启动 3 个。

docker-compose up -d --scale helloworld=3

通过下图可以看到有 3 个容器被创建,容器名称最后的序号是从 1 开始累加的,这就是序号的作用。所以如果指定了自定义名称,就不能将服务扩展至多个容器。

depends_on

使用 Compose 最大的好处就是敲最少的命令做更多的事情,但一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没有启动数据库容器的情况下启动了 Web 应用容器,应用容器会因为找不到数据库而退出。depends_on 就是用来解决容器依赖、启动先后问题的配置项。

version: "3.8"
services:
  web:
  build: .
  depends_on:
    - db
    - redis
  redis:
    image: redis
  db:
    image: mysql

上述 YAML 文件定义的容器会先启动 db 和 redis 两个服务,最后才启动 web 服务。

ports

容器对外暴露的端口,格式: 左边宿主机端口:右边容器端口 。

ports:
  - "80:80"
  - "8080:8080"

expose

容器暴露的端口不映射到宿主机,只允许能被连接的服务访问。

expose:
  - "80"
  - "8080"

restart

容器重启策略,简单的理解就是 Docker 重启以后容器要不要一起启动:

  • no :默认的重启策略,在任何情况下都不会重启容器;
  • on-failure :容器非正常退出时,比如退出状态为 非0 (异常退出),才会重启容器;
  • always :容器总是重新启动,即使容器被手动停止了,当 Docker 重启时容器也还是会一起启动;
  • unless-stopped :容器总是重新启动,除非容器被停止(手动或其他方式),那么 Docker 重启时容器则不会启动。
services:
  nginx:
  image: nginx
  container_name: mynginx
  ports:
    - "80:80"
  restart: always

environment

添加环境变量。可以使用数组也可以使用字典。布尔相关的值(true、false、yes、no)都需要用引号括起来,以确保 YML 解析器不会将它们转换为真或假。

environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:

或者以下格式:

environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET

docker容器编排利器Docker Compose(二):https://developer.aliyun.com/article/1416690

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
8天前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
4天前
|
关系型数据库 MySQL API
|
5天前
|
Java 应用服务中间件 Linux
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
本文主要讲解了Docker的安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库以及Docker容器虚拟化与传统虚拟机比较。
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
|
7天前
|
JavaScript 持续交付 Docker
解锁新技能:Docker容器化部署在微服务架构中的应用
【10月更文挑战第29天】在数字化转型中,微服务架构因灵活性和可扩展性成为企业首选。Docker容器化技术为微服务的部署和管理带来革命性变化。本文探讨Docker在微服务架构中的应用,包括隔离性、可移植性、扩展性、版本控制等方面,并提供代码示例。
35 1
|
8天前
|
Docker 容器
docker 修改容器内的系统时间
【10月更文挑战第27天】docker 修改容器内的系统时间
148 2
|
12天前
|
负载均衡 监控 开发者
深入浅出:掌握 Docker Compose 的高级用法
【10月更文挑战第22天】本文深入探讨了 Docker Compose 的高级用法,包括环境变量、服务扩展、网络配置和数据卷管理。通过实例详细介绍了如何利用这些功能提升开发效率和应用部署的灵活性。适合希望深入了解 Docker Compose 的开发者阅读。
|
14天前
|
Kubernetes 负载均衡 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【10月更文挑战第22天】随着云计算和容器技术的快速发展,微服务架构逐渐成为现代企业级应用的首选架构。微服务架构将一个大型应用程序拆分为多个小型、独立的服务,每个服务负责完成一个特定的功能。这种架构具有灵活性、可扩展性和易于维护的特点。在构建微服务架构时,Docker和Kubernetes是两个不可或缺的工具,它们可以完美搭档,为微服务架构提供高效的支持。本文将从三个方面探讨Docker和Kubernetes在构建高效微服务架构中的应用:一是Docker和Kubernetes的基本概念;二是它们在微服务架构中的作用;三是通过实例讲解如何使用Docker和Kubernetes构建微服务架构。
51 6
|
14天前
|
Kubernetes Cloud Native 开发者
云原生技术入门:Kubernetes和Docker的协作之旅
【10月更文挑战第22天】在数字化转型的浪潮中,云原生技术成为推动企业创新的重要力量。本文旨在通过浅显易懂的语言,引领读者步入云原生的世界,着重介绍Kubernetes和Docker如何携手打造弹性、可扩展的云环境。我们将从基础概念入手,逐步深入到它们在实际场景中的应用,以及如何简化部署和管理过程。文章不仅为初学者提供入门指南,还为有一定基础的开发者提供实践参考,共同探索云原生技术的无限可能。
23 3
|
5天前
|
Docker 容器
docker 容器重启
【10月更文挑战第30天】docker 容器重启
10 0
|
3月前
|
存储 Kubernetes Linux
在Linux中,如何使用Docker和Kubernetes管理容器?
在Linux中,如何使用Docker和Kubernetes管理容器?
下一篇
无影云桌面