许多docker镜像没有基本命令,例如ifconfig
,ip
,ps
等。
因此,我想找到一种在Docker容器环境中运行主机命令的方法,这样我就不需要将每个命令都复制/打包到Docker映像中。
我知道命令ip netns exec [ns] ifconfig
,该命令可以在新的网络名称空间中运行命令ifconfig。码头集装箱有类似的方法吗?
答案 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
名称空间(反过来会使您无法使用运行主机二进制文件,因为您将不再看到它们。
也就是说,这实际上取决于您要执行什么以及最终要得到什么。