在debian拉伸图像中从容器内部使systemctl工作

时间:2019-01-07 18:10:29

标签: docker kubernetes debian systemd kops

目的-我要实现什么?

我想从运行kubernetes节点(ami:运行debian Stretch)的容器内部访问systemctl

工作设置:

  • Node AMI:kope.io/k8s-1.10-debian-jessie-amd64-hvm-ebs-2018-08-17

  • 节点目录安装在容器中以使systemctl工作:

    • / var / run / dbus
    • / run / systemd
    • / bin / systemctl
    • / etc / systemd / system

不起作用的设置:

  • Node AMI:kope.io/k8s-1.11-debian-stretch-amd64-hvm-ebs-2018-08-17

  • 节点目录安装在容器中以使systemctl工作:

    • / var / run / dbus
    • / run / systemd
    • / bin / systemctl
    • / etc / systemd / system

尝试解决问题的调试

要调试此问题,以debian-stretch映像不支持systemctl且安装次数与​​debian-jessie相同的

1)我首先通过在其中安装上述卷来精简nginx部署

kubectl apply -f https://k8s.io/examples/application/deployment.yaml

kubectl exec -it nginx-deployment /bin/bash

root@nginx-deployment-788f65877d-pzzrn:/# systemctl
systemctl: error while loading shared libraries: libsystemd-shared- 
232.so: cannot open shared object file: No such file or directory

2)如上述问题所示,找不到文件libsystemd-shared-232.so。我通过查看节点找到了实际路径。

admin@ip-10-0-20-11:~$ sudo find / -iname 'libsystemd-shared-232.so'
/lib/systemd/libsystemd-shared-232.so

3)将/lib/systemd安装在nginx吊舱中,然后再次运行systemctl

 kubectl exec -it nginx-deployment /bin/bash

 root@nginx-deployment-587d866f54-ghfll:/# systemctl
 systemctl: error while loading shared libraries: libcap.so.2:cannot 
 open shared object file: No such file or directory

4)现在systemctl失败,出现了一个新的错误提示

root@nginx-deployment-587d866f54-ghfll:/# systemctl
systemctl: error while loading shared libraries: libcap.so.2: cannot 
open shared object file: No such file or directory

5)为解决上述错误,我再次在节点中搜索libcap.so.2,并在以下路径中找到了它。

admin@ip-10-0-20-11:~$ sudo find / -iname 'libcap.so.2'
/lib/x86_64-linux-gnu/libcap.so.2 

6)看到以上目录未安装在我的Pod中。我将以下路径安装在Nginx吊舱中。

/lib/x86_64-linux-gnu mounted in the nginx pod(deployment)

7)添加以上安装后,nginx pod无法启动。出现以下错误:

$ k logs nginx-deployment-f9c5ff956-b9wn5
standard_init_linux.go:178: exec user process caused "no such file 
or directory"

请建议如何进一步调试。在debian Stretch环境中,要使systemctl从容器内部正常工作,需要执行所有安装操作。

任何进一步调试的指针都将有所帮助。

3 个答案:

答案 0 :(得分:2)

在将主机的/lib目录安装到容器中之后,您的Pod很可能不会启动,因为Docker映像的/lib目录包含Nginx服务器所需的一些应在该容器中启动的库。通过从主机安装/lib,将不再可以访问Nginx所需的库。尝试启动Nginx时,这将导致没有此类文件或目录错误。

要使systemctl在容器中可用,我建议您仅将其安装在容器中,而不要尝试将所需的二进制文件和库安装到容器中。这可以在您的容器的Dockerfile中完成:

FROM whatever

RUN apt-get update && apt-get install systemd

无需使用此解决方案安装/bin/systemd/lib/

答案 1 :(得分:2)

您可以仅在容器中安装systemd而不是从主机装载某些库文件。

$ apt-get -y install systemd

现在,这不一定会使systemctl运行。您需要systemd在容器中运行,该容器由系统上的/sbin/init产生。 /sbin/init需要以root用户身份运行,因此从本质上讲,您必须在Kubernetes上的pod或容器security context中使用privileged标志来运行它。现在,这是不安全的,there is a long history是关于在容器中运行systemd的情况,而Docker人员大多反对此操作(安全性),而Red Hat人员则表示需要这样做。

尽管如此,红帽人们还是想出了一种make it work without the unprivileged flag的方法。您需要:

  • /run作为tmpfs安装在容器中。
  • /sys/fs/cgroup以只读方式安装是可以的。
  • /sys/fs/cgroup/systemd/已安装为读/写。
  • 用于STOPSIGNAL SIGRTMIN+3

在Kubernetes中,您需要一个emptyDir才能安装一个tmpfs。其他的可以作为主机卷挂载。

答案 2 :(得分:0)

我遇到了类似的问题,其中Dockerfile中的一行是: 运行apt-get install -y --reinstall systemd 但是在docker重新启动后,当我尝试使用systemctl命令时。输出为: 无法连接到总线:没有这样的文件或目录。 我通过在docker-compose.yml中添加以下内容来解决此问题: 数量: -“ / sys / fs / cgroup:/ sys / fs / cgroup:ro” 也可以通过以下方法完成: sudo docker run -d -v / sys / fs / cgroup:/ sys / fs / cgroup:ro {其他选项}