systemctl status docker(docker中使用systemctl)

标题: Docker中单个容器开启多个服务时systemctl引发的血案及其解决过程日期: 2022-02-27 19336009:52标签3360-Docker-SystemD-systemctlcategory 3360-编程与开发-运维管理血案的由来以及Docker中单个容器开启多个服务时systemctl引发的解决案例的问题来源于移植的欲望最初的项目,我们暂且称之为Myproject,提供了install_centos7.sh和vagger的构建文件。流浪汉文件工作的很好,但是作者在虚拟机中完成了对流浪汉构造的验证,也遇到了很多问题,比如嵌套虚拟化的问题。但是虚拟机总觉得别扭,而且因为游民比较小,所以我把目标定在了Docker上。本来我觉得不是很简单。拉一个centos7的镜像,然后运行一个容器,bash一下子安装好。没想到这就开始了,痛苦的挖坑之旅。
docker安装Myproject的问题。因为docker的设计原则是一个容器只运行一个服务,所以对于Myproject有很多限制,需要多个服务(Redis、HTTPD、PSQL、Mongo、Rabbit MQ等。),在一个容器中使用。问题包括但不限于在docker _WELTest的专栏中执行systemctl命令的问题记录和解决方案-CSDN博客_ Docker systemctlnable on Ubuntu Docker容器上使用systemd堆栈溢出
有一个问题:未能获得d-bus连接:不允许操作。解决这个问题的一个方法是使用- privileged和/usr/sbin/init。
特权的作用是让docker的环境以管理员的身份运行。/usr/sbin/init是/usr/sbin/init。启动容器后,可以使用systemctl方法-privileged=true获取主机的root权限(特殊权限)-docker-privileged和/usr/sbin/init-lvph-blog park。
但是,使用这种方法后出现了以下问题:
~docker run-itd-privileged-name centos 7 centos :7/usr/sbin/init a2 f 71d 42 e 0 f 4c 5c 13 b 06 a 607 da 719 df 40 e 428305188 C1 a 3154889 a1 BC 4991 f 6d ~docker exec-it centos 7 PS auxuserpid % CPU % mem vsz RSS tty stat start time co mmandroot 1 0 . 4 . 0 . 1 42716 3888
~docker run-privileged-itd-v/sys/fs/cgroup :/sys/fs/cgroup : ro-name centos 7 centos :7/usr/sbin/init 7 ff 1 b 85 e 7 c 9 fecf 17 c 889 e 0 C2 a 25 ab 73203131 ecdcb 629180798 fa 1c 07 b4e 22 ~docker exec-it centos 7 PS aux userpid % CPU % mem vsz -volume/sys/fs/cgroup :/sys/fs/cgroup : ro \-RM centos :7/bin/bash[root@9c3b2edf75ff /]# system CTL未能获得D-Bus连接:不允许的操作[root @ 9 C3 B2 EDF 75 ff/]#未能连接到bus :在搜索信息的过程中未找到此类文件或目录本文。 这个问题解释的相当到位:如何在Docker中使用systemctl-Ehds容器。里面没有systemd进程,很多进程管理工具都需要和systemd通信。这里有我们的主角systemctl。Docker只提供进程隔离,不提供操作系统的虚拟化。
这是因为“systemctl”通过使用d-bus与systemd守护进程进行对话。容器中没有systemd-daemon。要求开始可能不太符合你的预期——开发映射需要更长一点。这是故意的。Docker应该在您的容器中前台运行一个进程,它将在容器的PID名称空间中作为PID 1生成。Docker是为进程隔离而设计的,而不是为操作系统虚拟化而设计的,所以容器中没有其他操作系统进程和守护进程在运行(如systemd、cron、syslog等),只有您运行的入口点或命令。如果它们包含systemd命令,您会发现很多东西都不起作用,因为您的入口点取代了init。Systemd还利用docker限制在容器内部的cgroups,因为更改cgroups的能力会使进程脱离容器的隔离。如果容器中没有systemd作为init运行,就没有守护进程来处理启动和停止命令。
给个解决办法,真的可以。
解决方案当我们启动容器时,我们可以在启动参数中添加/sbin/init使其生效。以centos为例:docker run-d-v/sys/fs/cgroup/3360/sys/fs/cgroup 3360 ro-cap-addsys _ admin-name systemd _ websrvcentos/sbin/init可以正常使用systemd,但是如果重新启动容器,可能会导致失败。替换systemctl使用docker-systemctl-replacement替换容器中的systemctl。以ubuntu图片为例:1)。安装python2sudo来安装python2)。替换systemcl(注意路径,可以使用whereis systemctl查看当前默认路径)wget https://raw . githubusercontent . com/gdraheim/docker-system CTL-replacement/master/files/docker/system CTL . py-o/bin/system CTL 3)。给定权限sudo chmod a x /bin/systemctl,您可以使用非systemd systemctl,但可能会有一些未知的问题,因为它是一个非官方的systemcl。最好使用docker作为进程隔离环境,单个app单个容器,但在非常特殊的情况下,可以使用以上两种解决方案。如果你有更好的解决方法,请提出来。
在单个容器和单个服务的情况下,上面所有的都工作得很好,但是作者的场景呢?情况不太好。
还没完呢。当我们要像虚拟机一样在一个容器中运行多个容器时,比如一般网站的配置,redis,httpd,mongo,rabbitmq等。我们该怎么办?别问我为什么不拆分容器,配置太麻烦了。笔者遇到了一个问题,就是按照上述的复制方法安装完container中的所有服务后,一切正常,但是问题出现了,重启container后,systemctl无法再启动一些服务,比如httpd,psql等。经过一番周折,和systemctl.py的作者沟通,终于发现这个问题的根源在systemctl。在centos系统中,systemctl需要使用d-bus与systemd通信并启动服务。但是docker的容器中没有systemd-daemon的守护进程,所以上面的通信不会完成。这导致了上面提到的两个问题:3360d-总线连接:不允许操作,没有这样的文件或目录。这里有一个例子。一般启动容器的进程使用Docker Run-T-I CentOS 33607/bin/bash,所以容器中的第一个进程是/bin/bash,而不是大家熟悉的systemd。
~多克拉centos:77:拉库473 b 07 cdd 53:下载7:拉库473 b 07 cdd 53:拉完整摘要: sha 2563: c 73 f 515d 06 b 0fa 07 bb 18d 8202035 e 739 a 494 ce 760 aa 73129 f 60 f 44对象都没有了,所以暴d总线的错误,就很容易解释了。上述描述是对这个问题的通俗解释,想要了解关于这个问题的根本原因可以看下面两个链接,进一步了解,基本都是在解释一号进程的问题linux -如何解决码头工人问题无法连接到总线:没有这样的文件或目录-堆栈溢出无法在ubuntu docker上使用系统d容器-堆栈溢出
解决方案问题的根源找到了,解决这个问题的思路就非常的清晰了,就是使服务的管理不依赖于系统d。
不要依赖系统d作为进程管理器,而是让码头工人容器在前台运行您想要的应用程序。
有一款工具,就能够实现执行启动脚本而不依赖于systemd,他就是GitHub-gdraheim/docker-系统CTL-更换: docker系统CTL更换-允许部署到系统d控制的容器,而无需启动实际的系统d守护进程(例如centos7、ubuntu16),这个开源代码库仓库专门在处理这个问题。同时,如果你不想写一些构建来实现上述过程,你也可以使用该作者的另一个仓库,docker-system CTL-images/centos-httpd。主gdraheim上的docker文件/docker-system CTL-images GitHub在这里,作者给出了很多版本的可以使用启动脚本的镜像,非常的有用。
在使用启动脚本的过程中,其实也踩了很多坑第一个问题是,什么时候拷贝的问题?最最朴素的想法是,拷贝一次就行了呗,当初我也是这样想的,结果,水很深。
大多数带有系统d服务的操作系统包都声明了对系统d的依赖。当您安装操作系统软件包时,它会更新systemd,这会覆盖/usr/bin/systemctl,从而取消替换功能。下一个”系统控制”再次由系统d执行,正如您所知,它在容器中不容易工作。因此,在操作系统软件包安装后,再次插入替换脚本会有所帮助。重新启动时无法启动服务问题# 137 gdraheim/docker-系统CTL-替换GitHub
这是与作者沟通时候,作者的解释,很容易懂,大致就是,安装软件时会更新systemctl,那么我们之前一次的拷贝不就失效了嘛。所以安装了软件之后,就拷贝一下吧!时机:
在” yum安装”之后和下一次”系统控制”执行之前。重新启动时无法启动服务问题# 137 gdraheim/docker-系统CTL-替换GitHub
第二个问题是,启动点设为启动脚本还是/bin/bash/还是/usr/sbin/init .首先给出答案,需要设置成systemctl,因为它负责移除对系统d的依赖,所以要让它成为一号进程。这个可以看看作者给出的构建
摘自centos :7 . 7 . 1908 label _ _ copyright _ _='(C)Guido Draheim,根据EUPL的“\ __version__=’1.4.4147”许可,EXPOSE 80 copy files/docker/system CTL . py/Usr/bin/systemctlRUN yum install-y httpd httpd-tools copy files/docker/system CTL . py/Usr/bin/systemctlRUN echo test _ ok/var/www/html/index . html运行systemctl enable这里我们使用一个systemctl.py的工具,在使用systemctl.py的时候需要注意复制的时机,以及设置systemctl作为容器1号进程的引用和注释1号进程的作用是什么?Docker的stop和kill命令用于向容器发送信号。注意,只有容器中的1号进程才能接收到信号,这很关键!谁是1号进程主要是由EntryPoint、CMD、RUN等指令的编写决定的,所以这些指令的使用是很有讲究的。docker容器中的capture Signal-spark dev-Blog Garden CMD和ENTRYPOINT命令都支持exec模式和shell模式的编写,所以要理解CMD和ENTRYPOINT命令的用法,首先要区分exec模式和shell模式。这两种模式主要用于将容器中的不同进程指定为1号进程。使用exec模式时,容器中的任务进程是容器中的头号进程,exec模式是推荐的使用模式。使用shell模式时,docker会以/bin/sh -c ‘task command ‘的形式执行任务命令。也就是说,容器中的1号进程不是任务进程,而是bash进程。CMD指令的目的是为容器提供默认的执行命令。使用CMD有三种方法,其中一种是为ENTRYPOINT提供默认参数:CMD [‘param1 ‘,’ param2′]。另外两种方式是exec模式和shell模式:cmd [‘executable ‘,’ param1 ‘,’ param 2 ‘]//这是编写exec模式的方式。注意需要双引号。cmd param 1 param 2//这是shell模式的编写方式。注意命令行参数可以覆盖CMD指令的设置,但是只能重写,不能通过命令行传递给CMD中的命令。ENTRYPOINT指令的目的还在于指定默认情况下要为容器执行的任务。ENTRYPOINT指令有两种使用方式,就是我们前面介绍的exec模式和shell模式:entry point [‘executable ‘,’ param1 ‘,’ param 2 ‘]//这是exec模式的编写方式。请注意,双引号是必需的。入口命令param 1 param 2//这是shell模式的编写方式。当ENTRYPOINT命令被指定为exec模式时,命令行中指定的参数将作为参数添加到ENTRYPOINT命令的参数列表中。ENTRYPOINT命令的shell模式会忽略命令行参数。https://www . CTL . io/developers/blog/post/docker file-entry point-vs-cmd/
其他引用无法在Ubuntu docker容器上使用systemd堆栈溢出

其他教程

小乔分享的字幕软件Arctime非常好用,但是edius无法导入,最后解决了。

2022-9-7 11:50:05

其他教程

被99%的留学生称为“高端实习”的AE实习到底有什么魅力?

2022-9-7 11:52:08

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索