灵活控制Docker容器中启动的进程

原创 2015年06月08日 13:45:53

Docker容器在创建时就会设定好CMD或者ENTRYPOINT,这会固定每次容器启动时所运行的命令或者脚本。
容器启动的时候,如果设定好的命令或者脚本运行发生错误,容器是无法正常启动的。

如何能避免这种情况呢?解决的思路有很多种。
一种是CMD或ENTRYPOINT设定为绝对不会运行失败的程序,例如/bin/bash。如果bash都无法启动,那到底是对这个容器做了什么丧尽天良的操作!运行绝对不会出错的程序后,进入容器,再手动启动应用,退出的话直接关闭远程的窗口。这种方式不方便。
另一种思路也类似,也是运行一个绝对不会失败的程序或脚本,然后通过这个程序或者脚本,来启动我们的应用。这种方式如果应用灵活,就可以很灵活的控制每次我们运行的容器要启动那些应用。

下面我们介绍一下需要用到的工具:
1、ENTRYPOINT,在进行DockerBuild的时候可以设定ENTRYPOINT,这个参数不会被CMD所覆盖,每次启动容器的时候都会运行。
2、bootstrap.sh,脚本详细内容见下文。这个脚本就放在ENTRYPOINT中,负责启动我们的应用。
3、docker run -v ,映射本机目录到容器中,这里是最重要的一环。根据容器启动的过程,是会先进行映射,再运行ENTRYPOINT中制定的脚本或命令。

在这个方式中,bootstrap.sh脚本会扫描容器中的/config/init/目录,执行其中的shell脚本,启动应用。我们将本机的一个目录映射为容器内部的/config/init/目录。只要每次修改本机目录中的shell脚本,即可以做到每次容器启动的时候都指定要运行的应用,是可以动态调整的。
假如我们进行了什么操作,导致一个应用无法启动,那我们直接把这个应用对应的启动脚本删了就行了。进入容器后再手动启动这个应用,排查下问题。不至于整个容器直接起不来了,想排查都没机会了。

具体的构建方式如下:

1、构建镜像

FROM centos-base:latest
MAINTAINER artemus717@gmail.com
ENTRYPOINT ["/config/bootstrap.sh"]
CMD ["/bin/bash"]

此处指定了ENTRYPOINT、CMD命令。CMD命令为bash,我们构建的镜像一定是有bash进程的,有问题可以直接进行排查。

2、准备bootstrap.sh
在容器内部,编写脚本,脚本内容直接复制

mkdir /config
mkdir /config/init
vi /config/bootstrap.sh
chmod 755 /config/bootstrap.sh

3、在容器内安装supervisord
这个进程可以设定监控哪些进程是否在运行,可以作为守护进程来使用。

yum install epel-release -y
yum install supervisor -y
cp /etc/supervisor.conf /etc/supervisor.conf.bak

4、其他修改
顺便说下,最好把容器内的时区也改了。

rm -rf /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

5、别忘了docker commit
这样一个可以随时控制容器内启动哪些应用的镜像就构建好了。

#!/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

/config/bootstrap.sh

转载请注明出处。

Docker容器内多进程管理(一)-Supervisor

导读 Docker在设计时并不推崇在一个容器中运行多个进程,但在一些实际的场景中很多都可能需要在一个容器中,同时运行多个程序。在非容器的环境下系统初始化的时候,都会启动一个init进程,其余的进程都...
  • Jack__CJ
  • Jack__CJ
  • 2016年10月30日 15:34
  • 2475

Docker容器内多进程管理(二)-Monit

Docker多进程管理主要有两个工具,一个是Supervisor,另一个是Monit。在之前的文章中,我们介绍了一个在Docker中常用的用于管理多进程的工具Supervisor,本篇再来介绍一个比s...
  • wh211212
  • wh211212
  • 2016年10月31日 09:11
  • 713

Docker系列文章--Docker容器内多进程管理(一)

本文转载自G云定制云订阅号“G云定制云”目录1、Supervisor介绍及原理2、Supervisor配置与实例3、参考文档从Docker的设计初衷来看,它并不推崇在一个容器中运行多个进程,但在一些实...
  • u012798391
  • u012798391
  • 2016年10月18日 18:30
  • 541

docker启动顺序

VMDocker: 用户名:root 密码:XXXXXXXXXXXXX docker run -i -t -d -p 8081:8080 -p 23:22 67591570dd29  /bin/bas...
  • hanghangaidoudou
  • hanghangaidoudou
  • 2017年01月13日 16:01
  • 872

docker容器的多应用开机启动

在普通的Ubuntu系统中,只需要将自己需要开机启动的脚本写在 /etc/rc.local 中,即可实现开机自启动。但是在docker中,则完全不是这样,那么应该如何实现开机启动多个应用程序呢?默认地...
  • nisxiya
  • nisxiya
  • 2015年01月21日 10:35
  • 13122

Docker容器自启动

容器restart policy,即docker run启动容器时使用的--restart标志
  • wennuanddianbo
  • wennuanddianbo
  • 2017年08月26日 08:35
  • 3324

Docker容器的重启策略及docker run的--restart选项详解

1. Docker容器的重启策略 Docker容器的重启策略是面向生产环境的一个启动策略,在开发过程中可以忽略该策略。 Docker容器的重启都是由Docker守护进程完成的,因此与守护进程息...
  • taiyangdao
  • taiyangdao
  • 2017年06月11日 23:39
  • 9156

docker启动Container进程之启动流程

docker启动Container进程之启动流程
  • u010822828
  • u010822828
  • 2015年03月20日 10:31
  • 2053

Docker容器内应用服务自启动

Docker容器内应用服务自启动如果想把Docker容器内的应用服务随着容器开启时自启动。只需要将服务启动的脚本写在Dockerfile里,然后用Dockerfile重构镜像即可实现: 编写应用服务自...
  • blog_liuliang
  • blog_liuliang
  • 2016年09月07日 14:40
  • 11293

如何避免Docker容器启动脚本运行后自动退出——一个cron定时任务docker镜像方案

近期想做一个cron定时任务的docker,在Dockerfile中做如下定义 FROM library/alpine:latest RUN apk --update add rsync openss...
  • jiangh_catr
  • jiangh_catr
  • 2016年10月10日 22:54
  • 8035
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:灵活控制Docker容器中启动的进程
举报原因:
原因补充:

(最多只允许输入30个字)