首页 > 系统相关 >如何在一个Docker中同时运行多个程序进程?

如何在一个Docker中同时运行多个程序进程?

时间:2022-12-20 10:37:37浏览次数:55  
标签:bin 程序 s6 fdholder etc && 进程 Docker

我们都知道Docker容器的哲学是一个Docker容器只运行一个进程,但是有时候我们就是需要在一个Docker容器中运行多个进程

那么基本思路是在Dockerfile 的CMD 或者 ENTRYPOINT 运行一个”东西”,然后再让这个”东西”运行多个其他进程
简单说来是用Bash Shell脚本或者三方进程守护 (Monit,Skaware S6,Supervisor),其他没讲到的三方进程守护工具同理

Bash Shell脚本

入口文件运行一个Bash Shell 脚本, 然后在这个脚本内去拉起多个进程
注意最后要增加一个死循环不要让这个脚本退出,否则拉起的进程也退出了
run.sh

 

 

#!/bin/bash

# start 1
start1 > /var/log/start1.log 2>&1 &
# start 2
start2 > /var/log/start2.log 2>&1 &

# just keep this script running
while [[ true ]]; do
sleep 1
done

 


 

在Dockerfile的入口中运行run.sh

 

ENTRYPOINT  ["run.sh"]

 

 

用Bash Shell 的方式,任意发行版的linux都支持,缺点是不能拉起crash的进程,也就是只能拉起运行不能”守护”
如果不关心进程crash问题那么可以用这种方式

三方容器进程初始化之-dumb-init

​dumb-init官方​​​A minimal init system for Linux containers
一个最小化的Linux容器初始化系统
dumb-init是一个简单的进程监控器和init系统,设计为在最小容器环境(如Docker)中作为PID 1运行。它被部署为一个用C编写的小型静态链接二进制文件。
Dockerfile 参考

 

# Runs "/usr/bin/dumb-init -- /my/script --with --args"
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

# or if you use --rewrite or other cli flags
# ENTRYPOINT ["dumb-init", "--rewrite", "2:3", "--"]

CMD ["/my/script", "--with", "--args"]

 

 

ServiceMesh的数据平面Envoy Proxy的容器镜像就是使用的dumb-init

三方容器进程初始化之-tini

​tini官方​​​A tiny but valid ​​init​​ for containers
容器的一个小而有效的​​init​

三方进程守护之-Monit

Monit和Supervisor还是有很大区别的,Supervisor管理的都是前台执行的进程,Monit既可以管理前台进程也可以管理后台进程,简单的说,在CentOS中使用service xxx start 启动的程序,使用Monit可以直接管理,这就解决了很多没有前台方式启动的程序不能用Supervisor来管理的问题。
Dockerfile 参考

 

ENTRYPOINT ["/usr/bin/monit","-I"]

 

 

三方进程守护之-Supervisor

大名鼎鼎的 Supervisor
如果有多种版本的linux要用那么可以用Supervisor做统一进程守护管理,网上资料一大堆
注意要以前台程序运行,配置文件中要有,如果是后台的方式docker会退出

 

 

[supervisord]
nodaemon=true

 

Dockerfile 参考

 

ENTRYPOINT ["supervisord", "-c", "/etc/supervisor/conf.d/youconf.conf"]

 

 

三方进程守护之-Skaware S6

Supervisor是常见的进程守护程序,不过程序文件太大,想要容器镜像尽量小,在特别是用Alpine作为基础镜像的时候推荐使用Skaware S6
参考这个微服务基础镜像 https://github.com/nicholasjackson/microservice-basebox 他就是用 Skaware 作为进程守护程序运行多个进程的
如果基础容器镜像是本身就是Alpine,那就再合适不过了
Dockerfile 参考

 

# skaware s6 daemon runner
RUN mkdir /s6 \
&& wget --no-check-certificate https://github.com/just-containers/skaware/releases/download/v1.21.2/s6-2.6.1.1-linux-amd64-bin.tar.gz \
&& tar -xvzf s6-2.6.1.1-linux-amd64-bin.tar.gz --directory /s6 --strip-components=1 \
&& mv /s6/bin/* /usr/bin \
&& rm -rf s6-2.6.1.1-linux-amd64-bin.tar.gz \
&& rm -rf /s6 \
&& cd /usr/bin/ \
&& chmod -R 755 s6-accessrules-cdb-from-fs s6-accessrules-fs-from-cdb \
s6-applyuidgid s6-cleanfifodir s6-connlimit s6-envdir s6-envuidgid \
s6-fdholder-daemon s6-fdholder-delete s6-fdholder-deletec s6-fdholder-getdump \
s6-fdholder-getdumpc s6-fdholder-list s6-fdholder-listc s6-fdholder-retrieve \
s6-fdholder-retrievec s6-fdholder-setdump s6-fdholder-setdumpc s6-fdholder-store \
s6-fdholder-storec s6-fdholder-transferdump s6-fdholder-transferdumpc s6-fdholderd \
s6-fghack s6-ftrig-listen s6-ftrig-listen1 s6-ftrig-notify s6-ftrig-wait s6-ftrigrd \
s6-ioconnect s6-ipcclient s6-ipcserver s6-ipcserver-access s6-ipcserver-socketbinder \
s6-ipcserverd s6-log s6-mkfifodir s6-notifyoncheck s6-setlock s6-setsid s6-setuidgid \
s6-softlimit s6-sudo s6-sudoc s6-sudod s6-supervise s6-svc s6-svlisten s6-svlisten1 \
s6-svok s6-svscan s6-svscanctl s6-svstat s6-svwait s6-tai64n s6-tai64nlocal s6lockd ucspilogd \
&& cd -

# 预处理s6配置文件
RUN mkdir -p /etc/s6/.s6-svscan \
&& ln -s /bin/true /etc/s6/.s6-svscan/finish \
&& mkdir -p /etc/s6/cron \
&& mkdir -p /etc/s6/app \
&& ln -s /bin/true /etc/s6/cron/finish \
&& ln -s /bin/true /etc/s6/app/finish

# corotab 文件内容
ADD cronfile /var/spool/cron/root
# 运行Bash 脚本
ADD cron.run /etc/s6/cron/run
ADD app.run /etc/s6/app/run

ENTRYPOINT ["/usr/bin/s6-svscan","/etc/s6"]

 


 

cron.run example

 

 



#!/usr/bin/env bash
exec crond-n


 

app.run example

 

 




#!/usr/bin/env bash
exec app


 

三方进程守护之-s6-overlay

s6-overlay 是基于 Skaware S6适用于容器的进程守护工具
s6-overlay 官网 https://github.com/just-containers/s6-overlay
Dockerfile 参考

 

 

# Install s6-overlay 进程守护管理.
ENV S6_VERSION v1.21.4.0
RUN curl -L "https://github.com/just-containers/s6-overlay/releases/download/$S6_VERSION/s6-overlay-amd64.tar.gz" > /tmp/s6-overlay-amd64.tar.gz
RUN tar xzf /tmp/s6-overlay-amd64.tar.gz -C / --exclude="./bin" && \
tar xzf /tmp/s6-overlay-amd64.tar.gz -C /usr ./bin \
&& rm /tmp/s6-overlay-amd64.tar.gz
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS 1

# Set up a standard volume for logs.
VOLUME ["/var/log/services"]


# 设置入口为 s6-based init.
ENTRYPOINT ["/init"]

 


 

三方进程守护之-runit

runit官网http://smarden.org/runit/
具体的使用方法见官网
在Docker生态圈, phusion/baseimage-docker, gitlab 在使用runit作为进程管理工具

下面以要运行cron 和 ssh 为例
/etc/service/ 为配置文件目录

/etc/service/sshd 为要运行的程序目录
/etc/service/sshd/run 为需要运行的程序入口脚本文件
cat run

 

 

#!/bin/sh
set-e
exec/usr/sbin/sshd-D


 

/etc/service/cron 为要运行的程序目录
/etc/service/cron/run 为需要运行的程序入口脚本文件
cat run

 

 



#!/bin/sh
exec/usr/sbin/cron-f

 


 

Dockerfile 参考

 

 




ENTRYPOINT["/usr/bin/runsvdir","-P","/etc/service"]

 


 

三方进程守护之-Systemd

在 docker 中使用 Systemd 需要在 docker run 的时候开启特权模式 –privileged ,所以不推荐
这个直接放弃了
Dockerfile 参考

 

 

ENTRYPOINT["/usr/sbin/init"]

 

参考资料


如何运行多进程Docker容器? http://dockone.io/article/951
在Docker Container中启动定时任务 http://dockone.io/article/1070
Docker容器内多进程管理(一)-Supervisor http://www.linuxprobe.com/docker-process-management1.html
Docker容器内多进程管理(二)-Monit http://www.linuxprobe.com/docker-process-management2.html
关于S6和Runit的论坛讨论 S6 or Runit, not systemd https://www.linuxquestions.org/questions/slackware-14/s6-or-runit-not-systemd-4175465428/

作者:​​sunsky303​​


标签:bin,程序,s6,fdholder,etc,&&,进程,Docker
From: https://blog.51cto.com/u_15715098/5954218

相关文章

  • 解决安全生产知识题库小程序加载超大数据无法渲染的问题
    遇到问题在搭建安全生产知识竞赛题库小程序的时候,由于题库的题量太大了,一次性加载setData或者多次concat后setData,其实它俩都是一次性setData,这样就会造成加载超大数据无法......
  • 用Python来写个小型购物车程序
    0x1前言Python语言能做很多东西的,像数据分析啊、自动化、开发、爬虫(真的很棒哟,初学者玩很有成就感的啊哈哈)等等还有挺多。0x2用Python编写的一个小型购物车程序impor......
  • 面向对象程序设计理解
    面向对象的疑惑与理解1.为什么要设计接口,为什么会有抽象类?意义和设计理由理解在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对......
  • 20、electron 主进程与渲染进程之间的通讯ipcMain
    1、主进程代码1letelectron=require('electron')2const{ipcMain,BrowserWindow}=require('electron')34letapp=electron.app//引用APP5letm......
  • 程序员的十层楼
    作者简介:周伟明先生毕业于上海交通大学,1994年开始从事专业软件开发,曾工作于美国加州硅谷的DASCOMInc公司(现为IBM的全资子公司)和华为技术有限公司等企业。在网络安全软件、......
  • linux 中记录程序运行的时间
     001、[root@pc1test1]#start=$(date+%s)##记录程序的开始时间[root@pc1test1]#echo$start1671529118[root@pc1test1]#end=$(date+%s)##......
  • 无法停止服务、无法终止 PID 4100 的进程
    服务中无法停止服务。先查出服务对应的进程MicrosoftWindows[版本10.0.19043.1348](c)MicrosoftCorporation。保留所有权利。C:\Users\cj218>scqueryexVipSoft......
  • docker介绍及基本操作命令
    docker1.介绍#虚拟化虚拟化是一种资源管理技术,打破实体结构间的不可切割的障碍。虚拟化技术:VMware,VirtualBox,阿里云服务器,docker虚拟化技术#虚拟化相关名词 -......
  • docker镜像操作、容器操作
    dockerdocker入门#虚拟化在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打......
  • docker-部署tomcat
    dockerpulltomcat:8#拉取镜像dockerrun-d-p8080:8080tomcat:8#创建容器dockerps-a#可以查看容器iddockerexec-ittomcat的容器id/bin/bash#进入容器do......