我可以在Docker容器环境中运行主机命令吗?

时间:2018-10-19 07:36:14

标签: linux docker

许多docker镜像没有基本命令,例如ifconfigipps等。 因此,我想找到一种在Docker容器环境中运行主机命令的方法,这样我就不需要将每个命令都复制/打包到Docker映像中。

我知道命令ip netns exec [ns] ifconfig,该命令可以在新的网络名称空间中运行命令ifconfig。码头集装箱有类似的方法吗?

1 个答案:

答案 0 :(得分:1)

这个问题错过了内核没有“容器”概念的事实-从它的角度来看,容器是一组不同的抽象(不同的命名空间,cgroup等)。在主机上具有足够的权限,您可以独立管理这些抽象(例如,输入容器的任何单个名称空间,或输入几个)。也就是说,问题的完整答案取决于“在容器中执行主机的二进制文件”的含义(要在容器的 all 名称空间中执行此二进制文件,还是仅在中执行此二进制文件?重要的,会影响您想要获得的结果吗?)。

从技术上讲,您可以在容器的命名空间(mnt命名空间除外)内执行任意主机的二进制文件,而无需将该二进制文件复制或安装到容器的文件系统中。根据您要实现的目标,它可能会也可能不会解决您的问题。

例如,仅输入容器的ip名称空间后做一些net的事情,可能会给您带来预期的结果:

$ sudo nsenter -t $CONTAINERIZED_PROCESS_PID -n ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
33: eth0@if34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0

来自主机的命令在容器的网络名称空间中执行,并正确显示其网络接口。

或者您可以在容器的UTS名称空间内执行hostname二进制文件来获取正确的容器主机名:

$ sudo nsenter -t $CONTAINERIZED_PROCESS_PID -u hostname
d65269ecf908

但是,在进入容器的ps名称空间之后执行pid并不会为您提供容器进程的列表,而是您可以从主机看到的所有进程的列表,因为ps/proc获取信息,因此要查看正确的进程集,您必须输入容器的mnt名称空间(反过来会使您无法使用运行主机二进制文件,因为您将不再看到它们。

也就是说,这实际上取决于您要执行什么以及最终要得到什么。