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

如何,一个,docker,同时,运行,多个,程序,进程 · 浏览次数 : 0

小编点评

# Generate Content **Step 1: Define a Standard Volume for Logs** ``` VOLUME [\"/var/log/services\"] ``` **Step 2: Set Entrypoint for S6-Based Init** ``` ENTRYPOINT [\"/init\"] ``` **Step 3: Create a Docker Volume for App Files** ``` VOLUME -p /etc/app/ /etc/app/ ``` **Step 4: Create Docker Images for App and S6** ``` RUN mkdir -p /etc/app/ RUN docker run -d --name app --volume app:/etc/app app /init RUN docker run -d --name s6 --volume s6:/etc/s6 --entrypoint s6-overlay --volume -p /etc/app/:/etc/app/ app ``` **Step 5: Set Up a Systemd Service for S6-Based Init** ``` RUN systemd -create --name s6 -exec /init ``` **Step 6: Create a Docker Container Entrypoint Script** ``` RUN cat run.sh ``` **Step 7: Define a Docker Container Entrypoint Script** ``` RUN cat run.sh ``` **Step 8: Create a Docker Container Entrypoint Script for S6-Based Init** ``` RUN cat run.sh ``` **Step 9: Run the Docker Container Entrypoints** ``` CMD [run.sh] ```

正文

https://cloud.tencent.com/developer/article/1683445

 

我们都知道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"]

参考资料

Alpine里的go应用,你猜他能有多小? http://blog.csdn.net/sisiy2015/article/details/50350261 如何运行多进程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/ [译] runit 快速入门 https://segmentfault.com/a/1190000006644578

与[转帖]如何在一个Docker中同时运行多个程序进程?相似的内容:

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

https://cloud.tencent.com/developer/article/1683445 我们都知道Docker容器的哲学是一个Docker容器只运行一个进程,但是有时候我们就是需要在一个Docker容器中运行多个进程 那么基本思路是在Dockerfile 的CMD 或者 ENTRYP

[转帖]庐山真面目之十三微服务架构中如何在Docker上使用Redis缓存

https://www.cnblogs.com/PatrickLiu/p/14518160.html 一、介绍 1、开始说明 在微服务器架构中,有一个组件是不能少的,那就是缓存组件。其实来说,缓存组件,这个叫法不是完全正确,因为除了缓存功能,它还能完成其他很多功能。我就不隐瞒了,今天我们要探讨的就是

[转帖]Docker限制容器的资源

docker在默认运行容器的情况下,是不会对运行的容器进行资源限制的,在自己的实验环境的话是随便你怎么弄的,不过在生产中是一定会对docker运行的容器进行资源限制的,如果不限制的话在生产中会带来很多弊端的。例如当资源没有做限制时,资源用完了后会导致其他的容器无法运行,在生产中的话是会部署几十个或者

[转帖]设置docker/daemon.json 文件

一、创建daemon.json文件 一、创建daemon.json文件 sudo touch /etc/docker/daemon.json 二、在daemon文件中增加如下内容 { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn"

[转帖]通过yum展示安装包依赖关系,下载rpm包

https://www.cnblogs.com/hellxz/p/13212392.html 背景 平时测试环境中,服务器是可以访问外网的,而在内网环境,想要安装一些软件,比如docker,就需要离线安装,需要提前准备好需要的rpm安装包以及其依赖包 本文记录下如何使用yum展示软件包的依赖关系,以

[转帖]docker 镜像分层原理及容器写时复制

https://xie.infoq.cn/article/19c98e8b15ff9f610a2ee26bd 一、镜像分层与容器层 在进行docker pull 下载镜像的时候,通过下图可以看到镜像是分层下载并解压的。如 nginx:1.20.2 的镜像,其镜像是分为 6 层。 当我们运行一个新的容

【转帖】Seccomp、BPF与容器安全

语音阅读2022-06-30 20:26 本文详细介绍了关于seccomp的相关概念,包括seccomp的发展历史、Seccomp BPF的实现原理已经与seccomp相关的一些工具等。此外,通过实例验证了如何使用seccomp bpf 来保护Docker的安全。 简介 seccomp(全称secu

[转帖]如何在 CentOS 中添加、启用和禁用一个仓库

https://linux.cn/article-10219-1.htmlyum repolistyum-config-manager --enable --disable 在基于 RPM 的系统上,例如 RHEL、CentOS 等,我们中的许多人使用 yum 包管理器来管理软件的安装、删除、更新、

[转帖]如何在 Linux 中创建和管理归档文件

https://linux.cn/article-13126-1.html 简而言之,归档是一个包含一系列文件和(或)目录的单一文件。归档文件通常用于在本地或互联网上传输,或作为一个一系列文件和目录的备份副本,从而允许你使用一个文件来工作(如果压缩,则其大小会小于所有文件的总和)。同样的,归档也用于

[转帖]如何为多个字符串和模式使用Grep

[日期:2020-05-14] 来源:Linux公社 作者:醉落红尘 [字体:大 中 小] grep是一个功能强大的命令行工具,可让您在一个或多个输入文件中搜索与正则表达式匹配的行,并将每个匹配的行写入标准输出。 在本文中,我们将向您展示如何使用GNU grep搜索多个字符串或模式。 Grep多种模