Docker容器内多进程管理(一)——supervisor

注:本文基于CentOS 6.6

背景

Docker容器的设计并不推荐容器内运行多个进程,它希望的是一个进程一个容器,走微服务方向。然而实际生产过程中并没有这么理想,总是会有需要多个进程运行在同一容器的需要。因此,我们今天来介绍一下容器内的多进程管理——supervisor,还有另一个工具——monit,同样可以用于容器内多进程管理,不过我们后面再介绍它。

安装

1、使用yum方式

yum install -y epel-release && yum install -y supervisor

CentOS 6.5自带的yum repo没有supervisor,需要安装epel repo。但是6系列中supervisor的版本是2.x,有些功能没有,比如需要将所有进程配置放到主配置中,无法按进程独立出配置文件,然后一把include。

因此我们可以使用pip的方式安装supervisor。

2、使用pip方式

yum install -y epel-release && yum install -y python-pip && pip install supervisor setuptools==36.7.0

同样需要先安装epel repo,然后安装pip工具,之后就是使用pip安装supervisor了。不过这里有个坑,如果安装supervisor不升级setuptools组件,则执行命令时会有以下报错:

[root@6-6 /]# supervisord -h
Traceback (most recent call last):
  File "/usr/bin/supervisord", line 5, in <module>
    from pkg_resources import load_entry_point
  File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 2655, in <module>
    working_set.require(__requires__)
  File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 648, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 546, in resolve
    raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: meld3>=0.6.5

但是你如果直接升级又不行。如果你使用以下命令升级到最新版本,

pip install setuptools --upgrade

恭喜你,这下子pip命令报错了,原因就是setuptools在37版本之后就不再支持python 2.6了。。。

因此上面我们指定了升级setuptools组件的版本。

配置

安装好supervisor之后,我们就可以开始配置了。首先,我们说一下我们的需求,期望容器启动的时候sshd进程和crond进程也一并启动。

1、生成supervisor默认配置
supervisor并没有给我们提供现成的配置,需要我们自己执行命令生成模板。

echo_supervisord_conf > supervisord.conf

执行命令后在当前目录下生成了一份默认的supervisor配置。其实大部分都可以沿用默认配置,只要加入需要管理程序的配置就可以了。我们将配置文件注释部分剔除,做个简单介绍。

[unix_http_server]
file=/tmp/supervisor.sock   ; the path to the socket file

[supervisord]
logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false               ; start in foreground if true; default false
minfds=1024                  ; min. avail startup file descriptors; default 1024
minprocs=200                 ; min. avail process descriptors;default 200

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

;[program:theprogramname]
;command=/bin/cat              ; the program (relative uses PATH, can take args)
;autostart=true                ; start at supervisord start (default: true)
;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
;startretries=3                ; max # of serial start failures when starting (default 3)
;autorestart=unexpected        ; when to restart if exited after running (def: unexpected)

[include]
files = supervisord_sshd.conf supervisord_crond.conf

其中,
[unix_http_server]:用于配置http服务监听的socket,因为supervisor实际上是一个C/S服务架构,因此该配置让客户端supervisorctl能连接服务端supervisord的http server获取进程状态信息。
[supervisord]:用于配置supervisord进程的行为,包括日志存放及其转储等。
[supervisorctl]:客户端程序supervisorctl的相关配置,基于进程间通信,使用UNIX domain socket。
[program:x]:用于定于用户需要管理的进程信息,一般不在主配置里配置,而是每个进程一个配置文件,使用include包含,便于管理,其中x为唯一进程名。
[include]:用于指明用户进程配置文件路径,这也就是我们需要修改的地方。

关于配置有几点要注意的,

  1. 配置注释符号使用的是分号";"
  2. 如果需要使用模块配置,需要先把配置块开头的分号删除,否则整个块的配置不会生效;
  3. include字段的配置即为我们添加的管理服务的配置,配置文件使用空格分隔,也可以使用绝对路径和通配符,但是切记不要重复包含主配置文件——supervisord.conf。

supervisor的详细配置可以参考官网手册:[http://www.supervisord.org/index.html]。

docker镜像打包

创建Dockerfile,将supervisor和sshd及crond的相关配置文件都放在与Dockerfile同级目录中,打包时一同提交给docker daemon进程。

#使用CentOS 6.6官方镜像
FROM centos:6.6
#安装epel repo,以及pip命令,之后安装supervisor和升级setuptools
RUN yum install -y epel-release && yum install -y python-pip && pip install supervisor setuptools==36.7.0
#安装openssh组件和cron组件
RUN yum install -y openssh-server openssh-clients openssh cronie
#暴露22号端口用于ssh连接
EXPOSE 22
#设置机器密码
RUN echo "root:root" | chpasswd
#拷贝supervisor、sshd、crond配置到相关目录
COPY supervisord.conf /etc/supervisor/
COPY supervisord_sshd.conf /etc/supervisor/
COPY supervisord_crond.conf /etc/supervisor/
#设置容器启动时执行的命令
ENTRYPOINT ["/usr/bin/supervisord", "-nc", "/etc/supervisor/supervisord.conf"]

需要注意的是supervisord默认是以后台方式启动的,因此使用docker方式管理时需要设定为前台执行,否则容器一启动就退出了,这也是最后启动supervisord时使用"-n"的用意。

supervisord_sshd.confsupervisord_crond.conf的配置比较简单,只配置了最基本的参数,同时这两个进程也必须设置为前台运行。
supervisord_sshd.conf 配置如下:

[program:sshd]
command=/usr/sbin/sshd -D             ; the program (relative uses PATH, can take args)
autostart=true                ; start at supervisord start (default: true)
startretries=3                ; max # of serial start failures when starting (default 3)
autorestart=unexpected        ; when to restart if exited after running (def: unexpected)

supervisord_crond.conf 配置如下:

[program:crond]
command=/usr/sbin/crond -n             ; the program (relative uses PATH, can take args)
autostart=true                ; start at supervisord start (default: true)
startretries=3                ; max # of serial start failures when starting (default 3)
autorestart=unexpected        ; when to restart if exited after running (def: unexpected

简单定义了进程名,以及设置进程前台运行的参数,并指定自动启动等配置。

效果

使用docker build构建镜像后,就可以运行起来了,使用本地8000号端口映射容器的22号端口,

docker run -d --name eee -h eee -p 8000:22 1ed4256823b6

运行后查看容器状态,以及容器内进程信息,

[root@localhost 6.6]# docker  ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                                NAMES
4798c2b9ea39        1ed4256823b6        "/usr/bin/supervisor   4 seconds ago       Up 3 seconds        0.0.0.0:8000->22/tcp                 eee                               
[root@localhost 6.6]# docker top eee
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                31783               2015                2                   17:21               ?                   00:00:00            /usr/bin/python /usr/bin/supervisord -nc /etc/supervisor/supervisord.conf
root                32149               31783               0                   17:21               ?                   00:00:00            /usr/sbin/sshd -D
root                32150               31783               0                   17:21               ?                   00:00:00            /usr/sbin/crond -n

可见,此时容器内sshd和crond进程已经在位,在其他机器通过宿主机ip及8000端口,ssh登录也正常。

参考资料:
1、http://www.supervisord.org/index.html

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值