控制Docker Compose的启动顺序的一个思路
- 起源
- 守护进程daemon
- 从守护进程的角度看Docker Compose
- Docker的解决方案
- 思路
- 代码
- 结果
起源
Docker Compose提供了一个depends_on参数。
https://docs.docker.com/compose/compose-file/#depends_on
depends_on参数用于描述服务之间的依赖关系,服务依赖将导致如下行为:
docker-compose up按照依赖关系的顺序启动服务。docker-compose up SERVICE自动包含SERVICE的依赖关系。
看起来功能强大,不过接下来又说了使用depends_on的注意事项:
depends_on在启动服务时并不会等待相关所依赖的服务完成。
也就是说,depends_on的主要功能是自动包含SERVICE的依赖关系,
而所谓的按照依赖关系的顺序启动服务在实践中几乎毫无意义,
因为很多被依赖的服务往往启动缓慢,例如数据库。
分析Docker的工作原理会发现,
管理依赖关系的挑战在于Docker本身并不管理服务的启动的过程,
一个Docker服务在启动entrypoint或者command进程的时候就开始了,
一直到这个进程退出后才能被Docker识别服务结束。
Docker服务的生命周期不同于使用服务角度的声明周期,
从使用服务的角度看,有这么几个关键点
- 服务的主进程启动
- 服务开始向外提供服务
- 服务向外提供服务
- 服务终止向外提供服务
- 服务的主进程结束
然后结合Docker服务的生命周期的关键点一起看
entrypoint或者command进程启动- 若干启动辅助进程启动到结束
- 服务的主进程启动
- 服务开始向外提供服务
- 服务向外提供服务
- 服务终止向外提供服务
- 服务的主进程结束
- 若干结束辅助进程启动到结束
entrypoint或者command进程结束
Docker可以识别entrypoint或者command进程的启动和结束,
但是里面的细节就很难识别了。
守护进程daemon
在启动服务的过程中还有一个容易混淆的地方————守护进程daemon, Linux中的服务往往以守护进程daemon的形式出现。
所有守护进程的启动脚本,都放在/etc/init.d目录下面。 init进程的主要任务,就是逐一运行这些脚本。
在Linux中一个守护进程的父进程是init进程,
因为守护进程真正的父进程在fork出子进程后就先于子进程exit退出了,
所以守护进程是一个由init继承的孤儿进程。
这种工作方式有两个基本的用途。
- 用于启动的父进程的运行权限较高,
fork子进程的同时可以设置子进程运行于不同的环境,例如不同的用户。 - 用于启动的父进程在
init中是串行的,而且可以依循一定的顺序,
在fork具体提供服务的子进程后,父进程退出,init运行下一个守护进程的启动的父进程,
下一个守护进程的启动的父进程就可以使用前面的守护进程的子进程提供的服务了。
这是和本文所讨论的相同的场景。
免责声明:本段并非专门的Linux技术分析,仅用于介绍相关知识。
从守护进程的角度看Docker Compose
既然Docker Compose中按照顺序启动服务的情况和守护进程类似,
那么能不能使用相同的机制呢?
从技术上没问题,如果所有的服务都采用和守护进程类似的机制,例如fork出子进程,
或者使用&运行后台进程。总之,只要保证主进程退出,
就可以被Docker Compose识别了。
这种方式看上去很美,不过就严格限制了服务的灵活性。
猜测,仅仅是猜测,Docker没有找到尽善尽美的解决方案,所以没有提供这个功能。
Docker的解决方案
Docker没有提供直接的解决方案,不过也并且给出了一篇参考文章:
https://docs.docker.com/compose/startup-order/
这篇文章很神奇,神奇之处不是提出了什么奇思妙想,
神奇之处在于点踩的人数远远多于点赞的人数,
今天(2018年4月3日)的数据是172踩53赞。竟然达到了3倍之多!
这种情况在官方文档中是非常罕见的。
不过我也要赞一下,不是赞这篇文章,
而是为Docker公司把这么一个数字暴露出来的勇气点赞。
文章内容就不讨论了,思路类似。
思路
既然官方给出的思路是服务之间检测,那么检测端口是一个方法,而且是非侵入式的。
不过当另一个服务并没有提供端口,例如仅仅是若干操作环节中的一个步骤,
就不能检查端口了,此时就需要借助其他的方式。
前置的服务设置一个标志,后续的服务检查这个标志。
从这个角度思考,借助文件系统检查时间戳可能是最简单的方法之一。
- 借助
volume在不同的服务之间共享卷 - 前置服务完成启动的时候
touch一个文件作为标记 - 后置服务不停的检查这个文件
具体涉及到两个技术细节。
- 由于服务会重用之前的卷,因此不能仅检查文件是否存在,
还需要比对文件的时间戳是否晚于当前服务的启动时间 - 当前服务的启动时间不能使用
uptime,这个是主机的启动时间,
而是比对 /proc/1/cmdline 这个文件的时间戳
代码
https://github.com/huzhenghui/Docker-Compose-Startup-Order
version: "3"
services:
service_1:
image: ubuntu
volumes:
- Docker-Compose-Startup-Order:/Startup-Order
command: |
bash -c '
echo Service 1 Start;
sleep 10;
echo Service 1 Up;
touch /Startup-Order/service_1;'
service_2:
image: ubuntu
volumes:
- Docker-Compose-Startup-Order:/Startup-Order
command: |
bash -c '
while [[ ! -f /Startup-Order/service_1 || /Startup-Order/service_1 -ot /proc/1/cmdline ]]; do sleep 1; done;
echo Service 2 Start;
sleep 10;
echo Service 2 Up;
touch /Startup-Order/service_2;'
service_3:
image: ubuntu
volumes:
- Docker-Compose-Startup-Order:/Startup-Order
command: |
bash -c '
while [[ ! -f /Startup-Order/service_2 || /Startup-Order/service_2 -ot /proc/1/cmdline ]]; do sleep 1; done;
echo Service 3 Start;
sleep 10;
echo Service 3 Up;'
volumes:
Docker-Compose-Startup-Order:
结果
PS C:\Users\huzh\OneDrive\Docker\Docker-Compose-Startup-Order> docker-compose up
Starting dockercomposestartuporder_service_1_1 ...
Starting dockercomposestartuporder_service_3_1 ...
Starting dockercomposestartuporder_service_3_www.feihuanyule.com1 ... done
Attaching to dockercomposestartuporder_service_1_1, dockercomposestartuporder_service_2_1, dockercomposestartuporder_service_3_1
service_1_1 | Service 1 Start
service_1_1 | Service 1 Up
dockercomposestartuporder_service_1_1 www.feihuanyule.com exited with code 0
service_2_1 | Service 2 Start
service_2_1 | Service 2 Up
dockercomposestartuporder_service_2_1 www.feihuanyule.com exited with code 0
service_3_1 | Service 3 Start
service_3_1 | Service 3 Up
dockercomposestartuporder_service_www.gouyiflb.cn 3_1 exited with code 0
PS C:\Users\huzh\OneDrive\Docker\Docker-Compose-Startup-Order>
控制Docker Compose的启动顺序的一个思路的更多相关文章
- docker compose 服务启动顺序控制
概要 docker-compose 可以方便组合多个 docker 容器服务, 但是, 当容器服务之间存在依赖关系时, docker-compose 并不能保证服务的启动顺序. docker-comp ...
- asp.net core容器&mysql容器network互联 & docker compose方式编排启动多个容器
文章简介 asp.net core webapi容器与Mysql容器互联(network方式) docker compose方式编排启动多个容器 asp.net core webapi容器与Mysql ...
- Docker Compose 启动mysql,redis,rabbitmq
这里使用的centos7,首先切换到root. sudo -s 首先去设置下载镜像,否则下载这三个东西要很久,而且可能失败. vim /etc/docker/daemon.json 内容如下: { & ...
- Docker学习笔记之常用的 Docker Compose 配置项
0x00 概述 与 Dockerfile 一样,编写 Docker Compose 的配置文件是掌握和使用好 Docker Compose 的前提.编写 Docker Compose 配置文件,其本质 ...
- docker-compose下的java应用启动顺序两部曲之二:实战
上篇回顾 本文是<docker-compose下的java应用启动顺序两部曲>的终篇,在上一篇<docker-compose下的java应用启动顺序两部曲之一:问题分析>中,我 ...
- 5种常见的Docker Compose错误
在构建一个容器化应用程序时,开发人员需要一种方法来引导他们正在使用的容器去测试其代码.虽然有几种方法可以做到这一点,但 Docker Compose 是最流行的选择之一.它让你可以轻松指定开发期间要引 ...
- Docker学习笔记之使用 Docker Compose 管理容器
0x00 概述 通过之前的介绍,我们已经基本掌握了构建.运行容器的方法,但这还远远不够,由于 Docker 采用轻量级容器的设计,每个容器一般只运行一个软件,而目前绝大多数应用系统都绝不是一个软件所能 ...
- docker-compose下的java应用启动顺序两部曲之一:问题分析
在docker-compose编排多个容器时,需要按实际情况控制各容器的启动顺序,本文是<docker-compose下的java应用启动顺序两部曲>的第一篇,文中会分析启动顺序的重要性, ...
- docker和docker compose安装使用、入门进阶案例
一.前言 现在可谓是容器化的时代,云原生的袭来,导致go的崛起,作为一名java开发,现在慌得一批.作为知识储备,小编也是一直学关于docker的东西,还有一些持续继承jenkins. 提到docke ...
随机推荐
- Android事件分发机制浅析(1)
本文来自网易云社区 作者:孙有军 事件机制是Android中一个比较复杂且重要的知识点,比如你想自定义拦截事件,或者某系组件中嵌套了其他布局,往往会出现这样那样的事件冲突,坑爹啊!!事件主要涵盖onT ...
- 「日常训练」Kefa and Dishes(Codeforces Round #321 Div. 2 D)
题意与分析(CodeForces 580D) 一个人有\(n\)道菜,然后要点\(m\)道菜,每道菜有一个美味程度:然后给你了很多个关系,表示如果\(x\)刚好在\(y\)前面做的话,他的美味程度就会 ...
- Windows运行机理——窗口句柄和消息
Windows运行机理这系列文章都是来至于<零基础学Qt4编程>——吴迪,个人觉得写得很好,所以进行了搬运和个人加工 现在我们将消息与句柄联系起来.假如有一个窗口,且拥有该窗口的一个句柄( ...
- Qt-QML-Loader初步接触
先说说为什么用到了QML的Loader,这里我就要先扯点别的,那就是QML自带的ColorDialog,QML的机制 是优先调用系统提供的ColorDialog,如果系统的ColorDialog的不可 ...
- keepalived+nginx实现高可用+tomcat
1.keepalived的yum安装 安装依赖包[root@localhost ~]# yum install -y curl gcc openssl-devel libnl3-devel net-s ...
- lesson 24 A skeleton in the cupboard
lesson 24 A skeleton in the cupboard conceal sth from sb 对某人隐藏某事 He conceals his girlfriend from his ...
- Dos命令以及相关文件的访问
1.转到相关目录 有时候想从当前目录转到D盘,用此目录cd d:是没有用的, 最好用cd /d d:是可以的 2.查看目录文件 dir 3.往服务器上传文件文件 通过文件浏览器上传文件,只适用于Win ...
- 随机森林random forest及python实现
引言想通过随机森林来获取数据的主要特征 1.理论根据个体学习器的生成方式,目前的集成学习方法大致可分为两大类,即个体学习器之间存在强依赖关系,必须串行生成的序列化方法,以及个体学习器间不存在强依赖关系 ...
- Ubuntu14.04下部署FastDFS 5.08+Nginx 1.9.14
最新的版本可以在这里获取,目前下载的最新版本是5.08,更新于2016-02-03.在这里可以找到更多的说明. 下载好后,server端分为两个部分,一个是tracker,一个是storage.顾 ...
- Memory及其controller芯片整体测试方案(上篇)
如果你最近想买手机,没准儿你一看价格会被吓到手机什么时候偷偷涨价啦! 其实对于手机涨价,手机制造商也是有苦难言,其中一个显著的原因是存储器芯片价格的上涨↗↗↗ >>> 存储器memo ...