最近在开发一款小型游戏的服务端,目前基本完成开发了,就打算把它们部署到服务器上面。最终选择的方案是使用docker来完成,这个这过程中对我这个docker新人来说遇到了很多问题,当然也学习和成长了很多。今天来说的如何来保证docker中服务的启动顺序问题。
Issue
例如我现在有个和数据交互的db服务,依赖数据服务mysql_db。我使用docker工具是docker-compose,使用其中的depends_on来想解决问题。
db:
build: ./db
volumes:
- /host/path/:/data/log/
command: /cmd
depends_on:
- mysql_db
expose:
- "10050"
是的,这样的配置可以保证db服务会在mysql_db服务启动以后再启动,一定程度来说如果mysql_db能立马完成启动,并准备好对外服务,那么就没有什么问题了。可是不得不面对的一个问题是,mysql_db启动是一个比较耗时的服务,当db服务启动时mysql_db其实还是在服务的启动过程中,并没有准备好来接受db的数据库连接,这样一来就导致了db服务的异常,进而导致所有依赖db服务都会异常。
Solution
docker-compose目前貌似并没有相应的配置参数来解决类似的问题,在google中找到了一个局限性的替代方案,使用entrypoint.sh脚本。在脚本中增加判断依赖服务是否已经准备完毕的判断,如果没有启动就一直等待,直到依赖服务启动以后,再启动脚本。他这里使用nc命令,对于没有nc命令的镜像就需要自己想办法来解决了。例如可以使用golang中的net.Dial来写个尝试连接的工具,当然其他语言类似的库也可以。
#!/bin/sh
#set -x
: ${SLEEP_SECOND:=1}
# 等待服务启动
wait_for() {
echo Waiting for $1 to listen on $2...
while ! nc -z $1 $2; do echo waiting...; sleep $SLEEP_SECOND; done
}
wait_for mysql_db 3306
/go/bin/db --config /data/etc/config.json
Dockerfile修改
...
ADD entrypoint.sh /data/script/entrypoint.sh
...
docker-compose.yml修改
db:
build: ./db
volumes:
...
command: /data/script/entrypoint.sh
depends_on:
- mysql_db
expose:
- "10050"
至此就可以明确保证我们db服务会在mysql_db准备好以后再来进行启动。
参考文章:《docker compose 服务启动顺序控制》
这两天在考虑给我们4个人的小团队使用什么好的知识共享软件?第一个进入我的视野就是大名鼎鼎的confluence,无论从哪个角度考虑,confluence都是首选,而且我也装了,不过由于云服务器配置实在是太差,做一个操作就要卡上半天(cpu跑满了)。因此无奈,confluence被我pass掉了!接下来我考虑了一下Doku,这是一个php开发的小型wiki系统,其实它很不错,各方面都不错,而且插件也比较丰富。但是它有自己的一套语法系统,使用插件的话可以支持Markdown,但是相对比较麻烦一些,主要还是内心对它并不是特别喜欢吧,也被我pass掉了。最后进入我的视野的gollum(咕噜),这gollum和指环王中的是同一个词,不知道当初起名时,是不是作者比较喜欢电影中的咕噜。gollum是ruby开发的一套wiki系统,它支持Markdown语法、轻量级、结构清晰,看起来是不错的选择。
Docker安装Gollum
首先这里假设你已经成功安装docker了,如果你还没有安装,可以自行搜索一下资料,还是很简单的,这里就不再叙说了。
Dockerfile文件
FROM ruby
RUN apt-get -y update && apt-get -y install libicu-dev cmake && rm -rf /var/lib/apt/lists/*
RUN gem install github-linguist
RUN gem install gollum-rugged_adapter
RUN gem install gollum
RUN gem install org-ruby # optional
WORKDIR /wiki
ENTRYPOINT ["gollum", "--port", "80", "--adapter", "rugged"]
EXPOSE 80
Docker-compose文件
version: "2"
services:
gamemodr_wiki:
build: ./gollum
volumes:
- /data/wiki/gamemodr:/wiki
expose:
- 80
ports:
- 8888:80
运行”docker-compose up -d “就可以让容器服务运行了,注意挂载的”/data/wiki/gamemod”目录需要是一个git初始化过的目录。
如果需要在线编辑,可以用nginx做一个反向代理,然后加一个http用户认证,当然权限部分就没办法了。如果不需要在线编辑,可以去掉gollum在线编辑功能,然后和类似jenkins集成工具整合,也是不错的选择。
docker技术原来越普及,那么我们怎么进入一个正在运行中的docker容器哪?
目前常用的有4种方式:
1、docker attach
2、SSH
3、nsenter
4、docker exec
目前比较推荐使用第4中docker exec的方式,当然这篇博客主要目的是学习记忆,我自己也是这方面的新人。
启动php-fpm容器
docker run -d --name="king_php72" php:7.2.4-fpm
进入容器
上面的命令我们在启动时已经给docker命名了,所以可以直接通过名字的方式通过exec进入。
docker exec -it king_php72 /bin/bash
如果我们不清楚docker容器的名字,我们可以通过docker ps来获取容器的ID,通过容器ID进入容器。
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76c6cbb1a025 php:7.2.4-fpm "docker-php-entrypoi…" 5 minutes ago Up 5 minutes 9000/tcp king_php72
# docker exec -it 76c6cbb1a025 /bin/bash
参考文章:《如何进入Docker容器》
近期评论