百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

Docker集群管理之Docker Compose(docker—compose)

wptr33 2025-04-07 20:04 23 浏览

前言:在上一篇《Docker集群管理之Docker Machine》中,我们通过源码分析了解了Docker Machine的工作原理,使用者可以通过Docker Machine的一条命令在任意支持的平台创建一个Docker主机,并能集中管理这些主机。Docker主机创建好之后,接下来就该考虑Docker容器部署的问题了。本篇中我们将通过分析Docker Compose的源码,了解Docker Compose的工作原理。

与容器技术同样受到关注的微服务架构也在潜移默化的改变着应用的部署方式,其提倡将应用分割成一系列细小的服务,每个服务专注于单一业务功能,服务之间采用轻量级通信机制相互沟通。同时数据库解决方案也在发生在变化,多种持久化混合方案(Polyglot Persistence)提倡将数据存放在最适合的数据库解决方案中,而传统的数据库解决方案将数据存在在同一个数据库服务中。服务数量的增加也就意味着容器数量的增多,逐渐增加的容器数量为容器部署,运行及管理带来了挑战。Docker Compose的出现解决多个容器部署的问题并提高了多个容器解决方案的可移植性。

Docker Compose的前身是Fig,它是一个定义及运行多个Docker容器的工具。使用Docker Compose你只需要在一个配置文件中定义多个Docker容器,然后使用一条命令将多个容器启动,Docker Compose会通过解析容器件的依赖关系(link, 网络容器 –net-from或数据容器 –volume-from)按先后顺序启动所定义的容器。

安装Docker Compose

可以通过下载二进制可执行文件的方式安装Docker Compose

Docker Compose的工作原理

Docker Compose将所管理的容器分为三层,工程(project),服务(service)以及容器(contaienr)。Docker Compose运行的目录下的所有文件(docker-compose.yml, extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker Compose并没有解决负载均衡的问题,因此需要借助其他工具实现服务发现及负载均衡。

Docker Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。以下是一个简单的配置文件:

其定义了两个服务web和redis。web服务的镜像需要在当前目录实时构建,其容器运行时需要在宿主机开放端口5000并映射到容器端口5000,并且挂载存储卷/code以及关联服务redis。redis服务通过镜像redis启动。

Docker Compose是由python语言实现的,它通过调用docker-py库(可参考
https://github.com/docker/docker-py)与docker engine通信实现构建docker镜像,启动停止docker容器等。Docker-py库调用docker remote API(可参考
https://docs.docker.com/reference/api/docker_remote_api/)与Docker Daemon通信,可通过DOCKER_HOST配置本地或远程Docker Daemon的地址。

下面我们通过分析docker-compose最复杂的命令up的源码来了解一下docker compose的工作原理。

通过命令docker-compose up -d启动以上docker-compose.yml定义的服务。

我们可以看到redis服务先于web服务创建,这是因为docker-compose解析到服务间的依赖关系,web服务依赖于redis服务,所以进行了排序。我们来看一下docker compose up的工作流程。

1. 工程初始化 – 解析配置文件(包括docker-compose.yml,外部配置文件extends files,环境变量配置文件env_file),并将每个服务的配置转换成python字典,初始化docker-py客户端用于与本地或远端的docker engine通信。

2. 根据docker-compose的命令参数将命令分发给相应的处理函数,此处为up

3. 调用project类的up函数,得到当前工程中的所有服务,并根据服务的依赖性(links,external links – 本工程或docker-compose之外的容器,多用于多项目共用容器,网络容器net-from以及数据容器volume-from)进行排序并去掉重复出现服务(此情况可因某服务被其他多个服务依赖所造成)

4. Docker Compose使用labels标记启动的容器

使用docker inspect可以看到一个通过docker compose启动的容器被添加了一些compose使用的标记

5. Docker Compose通过compose工程名以及服务名从docker engine获取当前所有含有此标记的容器以检查当前工程所包含的服务状态,根据当前状态为每个服务制定接下来的动作。

a. 若容器不存在,则服务动作设置为创建(create)
b. 若容器存在但设置不允许重建,则服务动作设置为启动(start)
c. 若容器配置发生变化(config-hash)或者设置强制重建标志,则服务动作设置为重建(recreate)
d. 若容器状态为停止,则服务动作设置为启动(start)
e. 若容器状态为运行但其依赖容器需要重建,则服务状态设置为重建(recreate)
f. 若容器状态为运行其无配置改变则不作操作

6. 根据每个服务不同的动作执行不同的操作

服务动作为创建

a. 检查镜像是否存在(调用docker-py client inspect函数从本地或远程的docker engine获取镜像信息)。若镜像不存在,则检查配置文件中关于镜像的定义。如果在配置文件中设置为build则调用docker-py build函数与docker engine通信完成docker build的功能。如果在配置文件中设置为image则通过docker-py pull函数与docker engine通信完成docker pull的功能。
b. 获取当前服务中容器的配置信息,如端口,存储卷,主机名,使用镜像环境变量等配置的信息。若在配置中指定本服务必须与某个服务在同一台主机(previous_container,用于集群)则在环境变量中设置affinity:container=。通过docker-py与docker engine通信创建并启动容器。

服务动作为重建

a. 停止当前的容器
b. 将现有的容器重命名,这样数据卷在原容器被删除前就可以拷贝到新创建的容器中了
c. 创建并启动新容器,previsous_container设置为原容器确保其运行在同一台主机(存储卷挂载)
d. 删除旧容器

服务动作为启动则启动停止的容器

7. 若docker-compose up没有指明-d即前台运行,则将所有各个容器的输出汇聚打印

8. 注册信号SIGINT处理函数,若收到信号SIGINT则并行杀掉所有容器

到此为止docker-compose up的命令执行完毕,docker-compose.yml文件中定义的服务 全部启动。

Docker Compose的命令主要分为以下几类

管理服务:up/start/scale/stop/restart/rm/kill
管理镜像:build/pull
查看服务运行状态:ps/port
打印运行中的服务log:logs
在一个服务中执行一个一次性命令:run

以上这些命令都是通过label标记来过滤当前工程里的容器,然后调用docker-py库调用Docker remote API与docker engine通信控制容器。

Docker Compose是一个部署多个容器的简单但是非常必要的工具,它使你使用一条简单的命令部署多个容器。Docker Compose在实际工作中非常有价值,其大大简化了多容器的部署过程,避免了在不同环境运行多个重复步骤所带来的错误可能,使多容器移植变得简单可控。从其Roadmap可以看出,Docker Compose的目标是做一个生产环境可用的工具,包括服务回滚,多环境支持(dev/test/staging/prod),支持在线服务部署升级,防止服务中断并且监控服务使其始终运行在正确的状态。Roadmap中的另一个目标是更好的与Docker Swarm集成,目前版本存在的主要问题是无法保证处于多个主机的容器间正常通信因为目前不支持跨主机间容器通信,我们相信新的Docker网络实现将会解决这一问题。另一个问题是在Docker Compose中定义构建的镜像只存在在一台Docker Swarm主机上,无法做到多主机共享,因此目前需要手动构建镜像并上传到一个镜像仓库使多个Docker Swarm主机可以访问并下载镜像。相信随着Docker Compose的完善,其必将取代docker run成为开发者启动docker容器的首选。

作者简介:杜航,Websense云基础架构组开发经理,专注于Openstack和Docker。灵雀云资深用户。

预告:9月1日晚上8点整,杜航将通过在线培训的方式详细探讨《Docker集群管理三剑客》,报名地址请

相关推荐

MySQL进阶五之自动读写分离mysql-proxy

自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...

Postgres vs MySQL_vs2022连接mysql数据库

...

3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?

引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...

一文由浅入深带你完全掌握MySQL的锁机制原理与应用

本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...

验证Mysql中联合索引的最左匹配原则

后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...

MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)

目录1.索引基础...

你会看 MySQL 的执行计划(EXPLAIN)吗?

SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...

MySQL 从入门到精通(四)之索引结构

索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...

mysql总结——面试中最常问到的知识点

mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...

mysql总结——面试中最常问到的知识点(2)

首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...

MySQL基础全知全解!超详细无废话!轻松上手~

本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...

深入剖析 MySQL 中的锁机制原理_mysql 锁详解

在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...

Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析

引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...

MySQL基础篇:DQL数据查询操作_mysql 查

一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...

MySql:索引的基本使用_mysql索引的使用和原理

一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...