如何运行多进程Docker容器?

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

一般来说,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

 
  1. !/bin/bashstart docker daemondocker daemon > /var/log/docker.log 2>&1 & 
  2. start etcdetcd --data-dir=/var/etcd/data > /var/log/etcd.log 2>&1 & 
  3. wait for ectd to setupsleep 5  
  4. 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 & 
  5. wait for apiserver to setupsleep 5 
  6. start controller manager, sheduler, kubelet and proxykube-controller-manager --master=http://0.0.0.0:8080 > /var/log/kube-controller-manager.log 2>&1 & 
  7. kube-scheduler --master=http://0.0.0.0:8080 > /var/log/kube-scheduler.log 2>&1 & 
  8. 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 & 
  9. kube-proxy --master=http://0.0.0.0:8080 > /var/log/kube-proxy.log 2>&1 & 
  10. just keep this script runningwhile [[ true ]]; do 
  11. sleep 1 
  12. done 

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

 
  1. CMD ["start-kubernetes.sh"

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

 
  1. just keep this script runningwhile [[ true ]]; do  
  2. sleep 1  
  3. done 

使用supervisor运行多进程Docker容器

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

 
  1. [supervisord]  
  2. nodaemon=true  
  3. [program:etcd] 
  4. command=etcd --data-dir=/var/etcd/data 
  5. autorestart=true  
  6. stdout_logfile=/var/log/etcd.stdout.log 
  7. stderr_logfile=/var/log/etcd.stderr.log 
  8. [program:kube-apiserver] 
  9. 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 
  10. autorestart=true 
  11. stdout_logfile=/var/log/kube-apiserver.stdout.log 
  12. stderr_logfile=/var/log/kube-apiserver.stderr.log 
  13. [program:kube-controller-manager] 
  14. command=kube-controller-manager --master=http://0.0.0.0:8080 
  15. autorestart=true 
  16. stdout_logfile=/var/log/controller-manager.stdout.log 
  17. stderr_logfile=/var/log/controller-manager.stderr.log 
  18. [program:kube-scheduler] 
  19. command=kube-scheduler --master=http://0.0.0.0:8080 
  20. autorestart=true 
  21. stdout_logfile=/var/log/kube-scheduler.stdout.log 
  22. stderr_logfile=/var/log/kube-scheduler.stderr.log 
  23. [program:kubelet] 
  24. 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" 
  25. autorestart=true 
  26. stdout_logfile=/var/log/kubelet.stdout.log 
  27. stderr_logfile=/var/log/kubelet.stderr.log 
  28. [program:kube-proxy] 
  29. command=kube-proxy --master=http://0.0.0.0:8080 
  30. autorestart=true 
  31. stdout_logfile=/var/log/kube-proxy.stdout.log 
  32. stderr_logfile=/var/log/kube-proxy.stderr.log 
  33. [program:docker] 
  34. command=docker daemon 
  35. autorestart=true 
  36. stdout_logfile=/var/log/docker.stdout.log 
  37. stderr_logfile=/var/log/docker.stderr.log 

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

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

 
  1. CMD ["supervisord""-c""/etc/supervisor/conf.d/kubernetes.conf"

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

 
  1. [supervisord] 
  2. nodaemon=true 

总结

使用Shell脚本运行多进程Docker容器,优势是大家比较熟悉。由于需要保持Docker容器的1号进程始终运行,这一点比较容易出错。若要实现进程意外退出后自动重启的话,使用shell脚本比较麻烦。

使用supervisor运行多进程Docker容器,非常方便。另外,保持1号进程保持运行,以及进程意外退出后自动重启,实现起来都很简单。

使用多个Docker容器运行Kubernetes

GitHub地址

 
  1. kiwenlau/single-kubernetes-docker 

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

single-kubernetes-docker.png

使用单个Docker容器运行Kubernetes

GitHub地址:

 
  1. kiwenlau/kubernetes-shell 
  2. kiwenlau/kubernetes-supervisor 

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

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

kubernetes-shell-supervisor.png

参考

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


本文作者:刘凯

来源:51CTO

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
5天前
|
存储 安全 数据安全/隐私保护
【Docker 专栏】Docker 容器化应用的备份与恢复策略
【5月更文挑战第9天】本文探讨了Docker容器化应用的备份与恢复策略,强调了备份在数据保护、业务连续性和合规要求中的关键作用。内容涵盖备份的重要性、内容及方法,推荐了Docker自带工具和第三方工具如Portainer、Velero。制定了备份策略,包括频率、存储位置和保留期限,并详细阐述了恢复流程及注意事项。文章还提及案例分析和未来发展趋势,强调了随着技术发展,备份与恢复策略将持续演进,以应对数字化时代的挑战。
【Docker 专栏】Docker 容器化应用的备份与恢复策略
|
5天前
|
监控 Kubernetes Docker
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
【5月更文挑战第9天】本文探讨了Docker容器中应用的健康检查与自动恢复,强调其对应用稳定性和系统性能的重要性。健康检查包括进程、端口和应用特定检查,而自动恢复则涉及重启容器和重新部署。Docker原生及第三方工具(如Kubernetes)提供了相关功能。配置检查需考虑检查频率、应用特性和监控告警。案例分析展示了实际操作,未来发展趋势将趋向更智能和高效的检查恢复机制。
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
|
1天前
|
Prometheus 监控 Cloud Native
构建高效稳定的Docker容器监控体系
【5月更文挑战第13天】在微服务架构和容器化部署日益普及的背景下,对Docker容器的监控变得尤为重要。本文将探讨一种构建高效稳定Docker容器监控体系的方法,通过集成Prometheus和cAdvisor工具,实现对容器资源使用情况、性能指标和运行状态的实时监控。同时,结合Grafana进行数据可视化,为运维人员提供直观的分析界面,以便及时发现和解决潜在问题,保障系统的高可用性和稳定性。
14 6
|
1天前
|
存储 安全 开发者
如何删除 Docker 镜像、容器和卷?
【5月更文挑战第11天】
12 2
如何删除 Docker 镜像、容器和卷?
|
3天前
|
NoSQL Redis Docker
Mac上轻松几步搞定Docker与Redis安装:从下载安装到容器运行实测全程指南
Mac上轻松几步搞定Docker与Redis安装:从下载安装到容器运行实测全程指南
14 0
|
5天前
|
缓存 关系型数据库 数据库
【Docker 专栏】Docker 与容器化数据库的集成与优化
【5月更文挑战第9天】本文探讨了Docker与容器化数据库集成的优势,如快速部署、环境一致性、资源隔离和可扩展性,并列举了常见容器化数据库(如MySQL、PostgreSQL和MongoDB)。讨论了集成方法、注意事项、优化策略,包括资源调整、缓存优化和监控告警。此外,强调了数据备份、恢复测试及性能评估的重要性。未来,随着技术发展,二者的集成将更紧密,为数据管理带来更多可能性。掌握此技术将应对数字化时代的机遇与挑战。
【Docker 专栏】Docker 与容器化数据库的集成与优化
|
7月前
|
关系型数据库 MySQL 应用服务中间件
Docker容器常用命令大全:熟练掌握使容器优化更加高效
Docker容器常用命令大全:熟练掌握使容器优化更加高效
171 0
|
7月前
|
Prometheus 监控 Cloud Native
【云原生】Docker容器命令监控+Prometheus监控平台
【云原生】Docker容器命令监控+Prometheus监控平台
224 0
【云原生】Docker容器命令监控+Prometheus监控平台
|
4月前
|
Linux 开发者 Docker
如何构建在 Docker 容器中运行命令?
【1月更文挑战第6天】
61 0
|
19天前
|
存储 Ubuntu 安全
Docker容器常用命令
Docker容器常用命令
24 1