容器创建后,随意更改容器内启动脚本
自己创建一个可以随时修改容器内启动应用脚本的镜像。
Docker.io上有无数的镜像,但是很多用起来并不顺手。很多情况下有报错,容器起不来,而且没有办法进行排错。
个人感觉,好用的基础镜像应该满足几点:
1、安全,比如说官方的CentOS、Ubuntu镜像,选用软件用自己信得过的,或者官方的yum
2、有shell,Docker.io上很多镜像,但是貌似很多镜像运行起来会报错,没有shell,无法进行排错。如果把应用放到一个可能起不来的镜像中,我觉得并不好。
关于第一点,很简单,用Docker.io的镜像,或者有大神自己做纯净的;用yum或者github之类的下源码编译。
关于第二点,比较复杂,但是实现起来并不麻烦,用起来会很顺手,可以随时调整容器内部的启动脚本。
使用的工具如下:
1、Dockerfile,ENTRYPOINT、CMD
2、docker run -v,-v是个好参数,很灵活
3、supervisord,提供守护进程,防止容器内进程运行完毕退出
4、bootstrap.sh,从million12/supervisord这个容器中提取的,下面贴出来
按操作顺序说吧:
1、基础镜像,centos:latest,直接Docker.io下载就好,又新又安全。
2、yum install supervisor,先要安装epel-release源。
3、创建/config/init目录,把bootstrap.sh放到/config目录下。
4、docker commit > docker build
详细解释下各项:
1、bootstrap.sh:
通过ENTRYPOINT,启动容器的时候运行这个脚本,这个脚本有两个作用:
1)启动supervisord,作为守护进程,也可以通过这个进程监控应用是否运行。
2)将/config/init目录下的脚本运行,这个地方就可以写我们自己的应用的运行脚本。运行哪个写哪个。
#!/bin/bash
set -e
set -u
# Supervisord default params
SUPERVISOR_PARAMS='-c /etc/supervisord.conf'
# Create directories for supervisor's UNIX socket and logs (which might be missing
# as container might start with /data mounted from another data-container).
mkdir -p /data/conf /data/run /data/logs
chmod 711 /data/conf /data/run /data/logs
if [ "$(ls /config/init/)" ]; then
for init in /config/init/*.sh; do
. $init
done
fi
# We have TTY, so probably an interactive container...
if test -t 0; then
# Run supervisord detached...
supervisord $SUPERVISOR_PARAMS
# Some command(s) has been passed to container? Execute them and exit.
# No commands provided? Run bash.
if [[ $@ ]]; then
eval $@
else
export PS1='[\u@\h : \w]\$ '
/bin/bash
fi
# Detached mode? Run supervisord in foreground, which will stay until container is stopped.
else
# If some extra params were passed, execute them before.
# @TODO It is a bit confusing that the passed command runs *before* supervisord,
# while in interactive mode they run *after* supervisor.
# Not sure about that, but maybe when any command is passed to container,
# it should be executed *always* after supervisord? And when the command ends,
# container exits as well.
if [[ $@ ]]; then
eval $@
fi
supervisord -n $SUPERVISOR_PARAMS
fi
2、Dockerfile
FROM centos:latest
MAINTAINER artemus717@gmail.com
ENTRYPOINT ["/config/bootstrap.sh"]
CMD ["/bin/bash"]
很简单,只修改需要修改的,毕竟是作为基础镜像。
CMD保证我们一定是有bash的,也不用每次docker run都要在最后加一个/bin/bash。
3、supervisord
作用在上面说了,详细的配置很多,直接连接个官网
http://www.supervisord.org
4、docker run -v path:/config/init/
这一步是最重要的,镜像运行为容器后,运行的命令或脚本是被写死的,无法灵活的调整,但是可以通过bootstrap.sh这个脚本和docker run -v 来实现应用的灵活启动。
将本机的一个目录映射到容器内部,我们就把控制容器内部应用启动的目录映射出去。
目前判断,docker run -v 是会先于ENTRYPOINT执行的,所以可以通过这个操作,灵活控制、随时更改容器内部的应用启动。
如果做了什么丧尽天良、惨无人道的操作,应用启动就报错,导致容器起不来,那就把本机目录中的启动脚本删掉,只启动容器的系统,然后通过shell来排查错误,保证能正常启动了再把启动脚本加到目录里就可以了;如果删掉了所有的启动脚本还是起不来,那就说明是容器基础的系统有问题了,我觉得可以直接重做容器了。
这样一个可以在创建容器后还可以随便修改容器启动脚本的镜像就诞生了。
更多推荐
所有评论(0)