实现真正意思上的多docker容器自定义启动顺序

我们在docker运维的过程中经常会遇到一个问题,我们启动一个docker-compose.yml文件时,虽然我们使用depends_on属性用依赖关系定义了两个容器的启动顺序,但这个顺序仅仅是docker创建启动的顺序,而并不是在上一个容器完全启动成功的情况下启动下一个容器。
比如一个docker-compose.yml脚本中有mysql和依赖此mysql的一个java程序a容器,虽然a容器在mysql启动之后启动,但还是存在a容器启动的时候mysql容器还在启动中,还无法提供可用的数据库连接,这就导致一个问题,a容器此时启动异常或者失败,虽然部分有做异常情况快速失败停止程序触发docker重启机制,但也会导致a容器多次重启。
甚至在部分服务器资源有限的情况下,多个容器同时启动,但因为数据库等容器还未启动导致其他服务多次重启互相抢占系统资源,导致数据库容器也无法正常启动,陷入死循环,甚至严重的导致docker服务直接无响应。

为了实现上诉a容器在mysql容器完全启动可以提供数据库连接的情况下再启动,就需要在a容器中加入一个逻辑来检查等待mysql的3306端口已经打开,然后执行a容器的启动程序语句。

在这里用到了github上的一个开源项目wait-for-it,可以看到其中有一个shell文件wait-for-it.sh,这个自行去github项目中下载,这里以下面的docker-compose.yml为例:

version: '2.2'
services:
  mysql:
    restart: always
    image: mysql:5.6
    ports:
      - "3306:3306"
    env_file:
      - env/mysql.env
  app:
    image: app:latest
    restart: always
    env_file:
      - env/mysql.env
    ports:
      - 8054:8054
    depends_on:
      - mysql
    volumes:
      - ./wait-for-it.sh:/wait-for-it.sh
    command: ["/wait-for-it.sh", "-t", "0", "mysql:3306", "--", "java", "-jar", "/app.jar"]

这里将wait-for-it.sh挂载到app容器内,然后设置执行语句command: ["/wait-for-it.sh", "-t", "0", "mysql:3306", "--", "java", "-jar", "/app.jar"],其中mysql:3306代表检查mysql容器的3306端口是否可用,-t 0代表设置超时为0代表禁用超时功能,即wait-for-it脚本一直等mysql服务可用之后再执行后续命令,java -jar app.jar就是app容器原本的java程序启动命令。

你可能感兴趣的:(实现真正意思上的多docker容器自定义启动顺序)