将docker容器作为进程来使用

本文探讨了将Docker容器视为进程,并利用其环境隔离特性执行命令或任务的想法。通过确保容器内的前台进程标准输出能在宿主机上获取,以及验证容器退出状态码与进程退出状态码的一致性,证明了该思路的可行性。在生产环境中,这种方法能有效解决环境冲突问题,便于管理和监控任务执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 容器只是一个进程

使用docker部署一个mysql服务,或者一个nginx服务,这些服务是持久存在的,加上环境的隔离特性,我一直都将docker容器的使用限定在容器这个范围内。在容器内,启动某个程序对外提供服务。

但本质上,容器相对于宿主机,不过是一个进程而已。用进程的视角去看待它,我突然有了一个想法,或许早已经有人在这样做,或许我的这个思路存在一些问题,如果你对此有自己的经验和看法,欢迎你能够与我交换意见。

我的想法很简单,对于一些任务,或者一些命令,如果执行他们需要特定的环境,那么就可以将这个环境制作成docker 镜像,需要执行命令或启动任务时,启动容器,待任务或者命令执行结束后,容器自然也会退出。

前面所说的命令,你可以理解为类似spark-submit这样的命令,它需要spark环境的支持,任务,可以是一个可执行程序,一个pyhton脚本,或者一个jar包,任务不是持久存在的,任务完成进程也就随之结束。这样的思路正是想利用docker容器技术所带来的环境隔离,尤其在生产环境,一旦两个程序所依赖的环境有冲突,使用docker很容易就能够解决。

想要将想法变为现实,有两个问题需要解决:

  1. 在宿主机上获得容器内前台进程的标准输出
  2. 容器退出状态码必须和前台进程的退出状态码保持一致

2. 前台进程

容器内部必须有一个前台进程,否则容器就会退出,在使用容器部署nginx等其他服务时,都必须指定前台运行参数。

在宿主机运行前台进程时,进程的输出内容,都会输出到你的屏幕上。容器里所运行的前端进程的标准输出,你在进入容器后是看不到的,但在宿主机里,可以通过docker logs container_id 来查看。如果在使用docker run 命令启动容器时,不使用-d选项,那么docker run 启动的容器于你而言就是前台进程,容器内前台进程的标准输出会成为容器的标准输出,这样,在宿主机上,就获得了容器内前台进程的标准输出。

这份标准输出是十分有必要获得的,你可能需要根据这份标准输出来对程序的运行状态进行判断。

标准输出的问题解决了,接下来要看容器的退出状态码和容器内前台进程的退出状态码是否保持一致。先说结论,两者一致,如果不一致,那么利用docker容器执行命令或者任务的想法就是不可实施的,原因在于,需要通过这个状态码来判断命令是否被正确执行。

(base) [root]# docker run -it --rm --name test_exit centos:7 ls /root
anaconda-ks.cfg
(base) [root]# echo $?
0

ls /root 是可以被正确执行的,这个命令的退出状态码是0, 使用echo $?命令查看的是最近一条命令(docekr run)的退出状态码,也是0。接下来验证命令无法正常执行的情况

(base) [root]# docker run -it --rm --name test_exit centos:7 ls /rootsdf
anaconda-ks.cfg
(base) [root]# echo $?
2

/rootsdf 是不存在的目录,ls 不能正常执行,退出码是2,docker run命令的退出码也是2,由此可以证明,docker run 退出的状态码就是容器内前台进程的退出状态码。除此外,还有一些状态码需要关注

状态码描述
0正常退出
非0表示异常退出(退出状态码采用 chroot 标准)
125Docker 守护进程本身的错误
126容器启动后,要执行的默认命令无法调用
127容器启动后,要执行的默认命令不存在
137表明容器收到了 SIGKILL 信号,进程被杀掉,对应kill -9
139表明容器收到了 SIGSEGV 信号,无效的内存引用,对应kill -11
143表明容器收到了 SIGTERM 信号,终端关闭,对应kill -15

两个问题都得到了解决,那么在此思路下,启动某个命令或者某个任务,就变成了使用docker run 启动一个docker容器,命令或任务结束后,docker容器也就退出,通过查看docker run 命令的退出码就可以知道命令或任务是否正确执行。

Supervisorctl 是 Supervisor 的命令行工具,用于管理和监控 Docker 容器中的进程。以下是使用它来正确管理 Docker 容器的步骤: 1. **安装 Supervisor 和 Supervisorctl**: 首先,你需要在你的系统上安装 Supervisor 和 Supervisorctl。如果你正在使用 Debian 或 Ubuntu,可以运行 `sudo apt-get install supervisor supervisorctl`。对于 CentOS/RHEL,则可以通过 `sudo yum install supervisor supervisorctl`。 2. **配置 Supervisor**: 创建一个 Supervisord 的配置文件(通常是 `/etc/supervisord.conf`),添加相关的 Docker 进程配置。例如,你可以添加一个新的 `[program]` 节点,指定启动命令、工作目录、环境变量等。示例配置如下: ```ini [program:my_docker_container] command=/usr/bin/docker run -d --name my_container_name my_image:tag user=root directory=/path/to/container/root autostart=true autorestart=true ``` 3. **更新配置并重启 Supervisor**: 使用 `sudo supervisord -c /etc/supervisord.conf` 启动 Supervisor 并应用新配置。如果需要,可以重启 `supervisorctl reread; supervisorctl update`. 4. **监控和管理进程**: 使用 `supervisorctl` 来查看、启动、停止、重启或检查容器进程状态。比如,要列出所有程序: ``` supervisorctl status ``` 要启动特定进程: ``` supervisorctl start my_docker_container ``` 要停止进程: ``` supervisorctl stop my_docker_container ``` 5. **日志管理**: 默认情况下,Supervisor 将会记录每个容器的日志到 `/var/log/supervisor/*.log`。你可以通过 `tail -f /var/log/supervisor/my_docker_container.log` 实时查看进程日志。 6. **异常处理**: 如果容器意外退出,Supervisor 会尝试自动恢复(如配置中设置的那样)。若需定制错误处理策略,可以在配置中设置 `stopasgroup` 和 `killasgroup` 参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值