一个容器中运行多个前台进程

#先说解决办法,多个前台运行文件直接用&连接,不要使用&&或者单个单个hold。有耐心的同学可以看看前因后果。欢迎大佬的评论与指教!

背景:
在docker容器中,如果一个容器只运行一个进程服务是蛮简单的,通过Dockerfile中CMD就可以实现,如果有参数也只需使用ENTERPOINT,CMD作为参数传入即可。

然而所有事物都不是一层不变的,由于业务的需要本将nodejs执行的任务改为用python执行,这样意味着一个python容器中需要hold住三个py任务进程(原先在执行的与后来业务需要的),并且这三个py文件运行过程中都是前台运行,作为单个运行正好符合docker容器必须前台运行的标准。但是三个就需要换一种方式解决了

这边大部分情况下,我们通过shell脚本,调用并执行任务。

正文:

一、 在真实服务器上py执行,shell调用

[root@docker-server ~]# cat restart,sh
#!/bin/sh
# 案件导出
kill -9 `ps -ef|grep export_case.py |grep -v grep|awk '{print $2}'`
nohup python3 -u export_case.py ${1} >> ../logs/export_case.log 2>&1 &
# 还款和减免
kill -9 `ps -ef|grep repayment_reduction_export.py |grep -v grep|awk '{print $2}'`
nohup python3 -u repayment_reduction_export.py ${1} >> ../logs/repayment_reduction_export.log 2>&1 &
# 催记
kill -9 `ps -ef|grep export_case_operation.py |grep -v grep|awk '{print $2}'`
nohup python3 -u export_case_operation.py ${1} >> ../logs/export_case_operation.log 2>&1 

#因为真实服务器不涉及必须前台运行,可以将前台运行的进程用& 后台运行。

二、 在python容器中运行py脚本

#首先看下未引入其他任务时的情况

[root@0eeec2741cbb py]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 08:58 ?        00:00:07 python3 export_case.py
root         8     0  0 16:44 ?        00:00:00 bash
root        23     8  0 16:44 ?        00:00:00 ps -ef

#附上Dockerfile

[root@docker-server python]# cat Dockerfile
FROM basecentos:1   #这里定义一些业务所需要的配置程序等

RUN wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz \  #如果觉得下载慢可以使用ADD 传入容器会自动解压
   && tar -xf Python-3.6.8.tar.xz \
   && yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make -y \
   && cd Python-3.6.8 \
   && ./configure prefix=/usr/local/python3 \
   && make \
   && make install \
   && ln -s /usr/local/python3/bin/python3.6 /usr/bin/python3 \
   && ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3 \
   && pip3 install pymysql  xlwt openpyxl \
   && mkdir -p /usr/local/duyansoft/ng/download/  /root/python/{py,logs}   /logs/export_case.log \
   && yum remove zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make -y \
   && yum clean all 
#这一步以上可以自动安装python环境,去掉&& \即可
WORKDIR /root/python/py
#COPY  export_case.py  export_case_operation.py  repayment_reduction_export.py  restart.sh /root/python/py/
#ENTRYPOINT python3 export_case.py  #[]可加可不加,加上去规范点
#这是单进程业务作业时候
#ENTRYPOINT bash restart.sh
#这是后来添加新业务后写法
#这边只进行镜像的编译过程

#我这边是通过jenkins自动构建镜像

[root@docker-server script]# cat python.sh
#!/bin/bash
id=$1
cat >> Dockerfile << EOF
FROM basepython:2
COPY  export_case.py  export_case_operation.py repayment_reduction_export.py restart.sh /root/python/py/ #只是开始时候添加,后期通过映射关系,修改文件重启下容器即可,无需重新制作镜像
WORKDIR /root/python/py/
ENTRYPOINT bash restart.sh 
EOF
if [ -d /usr/local/docker_registry/docker/registry/v2/repositories/python/_manifests/tags/$id ]
then
        rm -rf /usr/local/docker_registry/docker/registry/v2/repositories/python/_manifests/tags/$id
        docker rmi 127.0.0.1:5000/python:$id
fi

docker build --no-cache -t 127.0.0.1:5000/python:$id .
docker push 127.0.0.1:5000/python:$id
rm -rf Dockerfile

#如果用最先的restart.sh脚本则会出现如下情况,只启动了一个进程
在这里插入图片描述
结论:
#最后经过摸索研究,一方面py文件中如果导入为导入的模块则无报错无法通过docker logs查看,需要先导入模块,第二个就是启动任务进程的shell脚本不应该这样写。正确如下:

#!/bin/sh
# 案件导出
# 还款和减免
# 催记
python3  export_case.py  >> ../logs/export_case.log 2>&1  & python3  repayment_reduction_export.py  >> ../logs/repayment_reduction_export.log 2>&1 & python3  export_case_operation.py  >> ../logs/export_case_operation.log 2>&1  && tail -f /dev/null

#这样再去执行就OK了,用&连接,最后用tail卡在前台

一个容器中运行多个前台进程_第1张图片

你可能感兴趣的:(自动化运维,docker)