下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

教大家怎样运行多进程Docker容器

作者:课课家教育     来源: http://www.kokojia.com点击数:1875发布时间: 2017-06-27 08:30:15

标签: Docker容器技术

  欢迎大家阅读本篇文章Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。

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

教大家怎样运行多进程Docker容器_Docker_容器_技术_课课家教育

  然而,很多时候我们需要在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

  下图显示了我在Ubuntu主机上运行单机版Kubernetes的架构。可知,我一共运行了7个容器,分别运行Kubernetes的各个组件。

下图显示了我在Ubuntu主机上运行单机版Kubernetes的架构。可知,我一共运行了7个容器,分别运行Kubernetes的各个组件。

  使用单个Docker容器运行Kubernetes

  GitHub地址:

kiwenlau/kubernetes-shell 
kiwenlau/kubernetes-supervisor 

  该项目中,我将kubernetes的所有组件:etcd, controller manager, apiserver, scheduler, kubelet, proxy以及docker daemon均运行在同一个Docker容器之中。

  容器启动时,各个组件由shell脚本或者supervisor启动。

  容器启动时,各个组件由shell脚本或者supervisor启动。

  知识分享:

  由于其基于LXC的轻量级虚拟化的特点,docker相比KVM之类最明显的特点就是启动快,资源占用小。因此对于构建隔离的标准化的运行环境,轻量级的PaaS(如dokku), 构建自动化测试和持续集成环境,以及一切可以横向扩展的应用(尤其是需要快速启停来应对峰谷的web应用)。

  构建标准化的运行环境,方案大多是在一个baseOS上运行一套puppet/chef,或者一个image文件,其缺点是前者需要base OS许多前提条件,后者几乎不可以修改(因为copy on write 的文件格式在运行时rootfs是read only的)。并且后者文件体积大,环境管理和版本控制本身也是一个问题。

  PaaS环境是不言而喻的,其设计之初和dotcloud的案例都是将其作为PaaS产品的环境基础

  因为其标准化构建方法(buildfile)和良好的REST API,自动测试和持续集成/部署能够很好的集成进来

  因为LXC轻量级的特点,其启动快,而且docker能够只加载每个container变化的部分,这样资源占用小,能够在单机环境下与KVM之类的虚拟化方案相比能够更加快速和占用更少资源

      参考:

  1. Using Supervisor with Docker

  2. How To Install and Manage Supervisor on Ubuntu and Debian VPS

  3. 基于Docker搭建单机版Kuberntes

  4. kiwenlau/single-kubernetes-docker

     小结:Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。当然如果大家还想更深入的学习相关方面的知识的话呢,请登录课课家教育平台共同学习哦~

赞(10)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程