如何运行多进程Docker容器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何运行多进程Docker容器相关的知识,希望对你有一定的参考价值。

运行多进程Docker容器的方法如下:

1、使用Shell脚本依次启动Kubernetes的各个组件即可。

以下为start-kubernetes.sh

2、然后在Dockerfile中,将start-kubernetes.sh指定为Docker容器默认执行的命令即可。

3、需要注意的一点在于,start-kubernetes.sh脚本将作为Docker容器的1号进程运行,必须始终保持运行。因为Docker容器仅在1号进程运行时保持运行,换言之,Docker容器将在1号进程退出后Exited。由于Kubernetes的各个组件都以后台进程方式执行,在脚本末尾添加了死循环,以保持start-kubernetes.sh脚本始终处于运行状态。

4、Supervisor是进程管理工具。这时,需要编写supervisor的配置文件kubernetes.conf:

5、将Kubernetes的各个组件的启动命令设为command即可。autorestart参数设为true,意味着supervisor将负责重启意外退出的组件。stdout_logfile和stderr_logfile参数则可以用于设置命令的标准输出文件和标准错误输出文件。

6、然后在Dockerfile中,将supervisord指定为Docker容器默认执行的命令即可:

7、此时, supervisord是Docker容器中的1号进程,也需要始终保持运行状态。nodaemon设为true时,表示supervisor保持前台运行而非在后台运行。若supervisor在后台运行,则Docker容器也会在执行supervisord命令后立即Exited.

参考技术A 一般来说,Docker容器比较适合运行单个进程。例如,项目"使用多个Docker容器运行Kubernetes",Kubernetes的各个组件分别运行在各个容器之中,每个容器只运行单个进程。

然而,很多时候我们需要在Docker容器中运行多个进程。例如,项目"使用单个Docker容器运行Kubernetes",kubernetes的各个组件均运行在同一个容器中,该容器中运行了多个进程。那么,如何运行多进程Docker容器?
一种方法是使用Shell脚本,另一种方法是使用进程管理工具Supervisor。kiwenlau/kubernetes-shell和kiwenlau/kubernetes-supervisor分别采用了这两种方法,用于启动多个进程来运行Kubernetes的各个组件,从而实现"使用单个Docker容器运行Kubernetes"。下面我将分别介绍两种不同方法。
使用Shell脚本运行多进程Docker容器
这个方法大家应该会比较熟悉,使用Shell脚本依次启动Kubernetes的各个组件即可。以下为start-kubernetes.sh
!/bin/bashstart docker daemondocker daemon > /var/log/docker.log 2>&1 & start etcdetcd --data-dir=/var/etcd/data > /var/log/etcd.log 2>&1 & wait for ectd to setupsleep 5 start apiserverkube-apiserver --service-cluster-ip-range=10.0.0.1/24 --insecure-bind-address=0.0.0.0 --etcd_servers=http://127.0.0.1:4001 > /var/log/kube-apiserver.log 2>&1 & wait for apiserver to setupsleep 5 start controller manager, sheduler, kubelet and proxykube-controller-manager --master=http://0.0.0.0:8080 > /var/log/kube-controller-manager.log 2>&1 & kube-scheduler --master=http://0.0.0.0:8080 > /var/log/kube-scheduler.log 2>&1 & kubelet --api_servers=http://0.0.0.0:8080 --address=0.0.0.0 --cluster_dns=10.0.0.10 --cluster_domain="kubernetes.local" --pod-infra-container-image="kiwenlau/pause:0.8.0" > /var/log/kubelet.log 2>&1 & kube-proxy --master=http://0.0.0.0:8080 > /var/log/kube-proxy.log 2>&1 & just keep this script runningwhile [[ true ]]; do sleep 1 done

然后在Dockerfile中,将start-kubernetes.sh指定为Docker容器默认执行的命令即可:
CMD ["start-kubernetes.sh"]

需要注意的一点在于,start-kubernetes.sh脚本将作为Docker容器的1号进程运行,必须始终保持运行。因为Docker容器仅在1号进程运行时保持运行,换言之,Docker容器将在1号进程退出后Exited。由于Kubernetes的各个组件都以后台进程方式执行,我在脚本末尾添加了死循环,以保持start-kubernetes.sh脚本始终处于运行状态。
just keep this script runningwhile [[ true ]]; do sleep 1 done

使用supervisor运行多进程Docker容器
Supervisor是进程管理工具。这时,需要编写supervisor的配置文件kubernetes.conf:
[supervisord] nodaemon=true [program:etcd] command=etcd --data-dir=/var/etcd/data autorestart=true stdout_logfile=/var/log/etcd.stdout.log stderr_logfile=/var/log/etcd.stderr.log [program:kube-apiserver] command=kube-apiserver --service-cluster-ip-range=10.0.0.1/24 --insecure-bind-address=0.0.0.0 --etcd_servers=http://127.0.0.1:4001 autorestart=true stdout_logfile=/var/log/kube-apiserver.stdout.log stderr_logfile=/var/log/kube-apiserver.stderr.log [program:kube-controller-manager] command=kube-controller-manager --master=http://0.0.0.0:8080 autorestart=true stdout_logfile=/var/log/controller-manager.stdout.log stderr_logfile=/var/log/controller-manager.stderr.log [program:kube-scheduler] command=kube-scheduler --master=http://0.0.0.0:8080 autorestart=true stdout_logfile=/var/log/kube-scheduler.stdout.log stderr_logfile=/var/log/kube-scheduler.stderr.log [program:kubelet] command=kubelet --api_servers=http://0.0.0.0:8080 --address=0.0.0.0 --cluster_dns=10.0.0.10 --cluster_domain="kubernetes.local" --pod-infra-container-image="kiwenlau/pause:0.8.0" autorestart=true stdout_logfile=/var/log/kubelet.stdout.log stderr_logfile=/var/log/kubelet.stderr.log [program:kube-proxy] command=kube-proxy --master=http://0.0.0.0:8080 autorestart=true stdout_logfile=/var/log/kube-proxy.stdout.log stderr_logfile=/var/log/kube-proxy.stderr.log [program:docker] command=docker daemon autorestart=true stdout_logfile=/var/log/docker.stdout.log stderr_logfile=/var/log/docker.stderr.log

可知,将Kubernetes的各个组件的启动命令设为command即可。autorestart参数设为true,意味着supervisor将负责重启意外退出的组件。stdout_logfile和stderr_logfile参数则可以用于设置命令的标准输出文件和标准错误输出文件。
然后在Dockerfile中,将supervisord指定为Docker容器默认执行的命令即可:
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/kubernetes.conf"]

此时, supervisord是Docker容器中的1号进程,也需要始终保持运行状态。nodaemon设为true时,表示supervisor保持前台运行而非在后台运行。若supervisor在后台运行,则Docker容器也会在执行supervisord命令后立即Exited.
[supervisord] nodaemon=true

总结
使用Shell脚本运行多进程Docker容器,优势是大家比较熟悉。由于需要保持Docker容器的1号进程始终运行,这一点比较容易出错。若要实现进程意外退出后自动重启的话,使用shell脚本比较麻烦。
使用supervisor运行多进程Docker容器,非常方便。另外,保持1号进程保持运行,以及进程意外退出后自动重启,实现起来都很简单。
使用多个Docker容器运行Kubernetes
GitHub地址
kiwenlau/single-kubernetes-docker

使用单个Docker容器运行Kubernetes
GitHub地址:
kiwenlau/kubernetes-shell kiwenlau/kubernetes-supervisor

该项目中,我将kubernetes的所有组件:etcd, controller manager, apiserver, scheduler, kubelet, proxy以及docker daemon均运行在同一个Docker容器之中。
容器启动时,各个组件由shell脚本或者supervisor启动。本回答被提问者采纳

如何保证 docker 后台进程重启,而不引起容器关闭

前言

平常在进行docker 实验时,经常会需要修改一些配置参数,有些参数修改后,是需要重启docker 后台进程 daemon 才能生效的,但是docker 后台进程重启后,可能会造成正在运行的容器强制关闭。如果容器正在跑着重要的测试,这样就不太方便了。所以,有必要了解一下如何使docker 后台进程在重启的情况下,容器不会强制关闭,保持运行。

服务器环境

ubuntu 14.04
docker 17.12.0-ce

修改docker 配置文件

sudo   vim  /etc/docker/daemon.json
添加"live-restore": true选项,比如:
{

    "live-restore": true,

}

说明: 在我做测试的机器,没有什么多余的配置,如果你的机器有,请添加就可以了。

重启

sudo   service     docker   restart   


在/etc/systemd/system/multi-user.target.wants/docker.service文件下添加配置

技术图片

注意:--live-restore 和 Swarm Mode 不兼容,所以在集群环境中不要使用。实际上集群环境也不用担心某个服务器重启的问题,因为其上的服务都会被调度到别的节点上,因此服务并不会被中断。

 

以上是关于如何运行多进程Docker容器的主要内容,如果未能解决你的问题,请参考以下文章

如何检查一个进程是不是在 docker 容器内运行?

如何查看docker 里某个容器的的启动命令

如何保证 docker 后台进程重启,而不引起容器关闭

如何保证 docker 后台进程重启,而不引起容器关闭

如何保证 docker 后台进程重启,而不引起容器关闭

Docker多容器部署LNMP环境