需求
我想进入容器中执行 curl 命令探测某个地址的连通性,但是容器镜像里默认没有 curl 命令。我这里是一个内网环境不太方便使用 yum 或者 apt 安装,怎么办?
这个需求比较典型,这里教大家一个简单的方法,使用 nsenter 进入容器的 net namespace,即可使用宿主机的 curl、ip、ifconfig 等命令,其效果,就跟进入容器中执行是一样的。
原理
容器像是一个轻量级虚拟机,有自己的 IP,宿主机如果已经监听了 8080 端口,容器里的进程仍然可以重复监听 8080 端口。核心就是因为容器有自己的 namespace,和宿主机的 net namespace 互不影响。关于容器的 namespace 相关知识,可以 Google 一下关键字:「容器 namespace 原理」。
nsenter,是个关键工具。其用法如下:
nsenter --help
用法:
nsenter [选项] [<程序> [<参数>...]]
以其他程序的名字空间运行某个程序。
选项:
-a, --all enter all namespaces
-t, --target <pid> 要获取名字空间的目标进程
-m, --mount[=<文件>] 进入 mount 名字空间
-u, --uts[=<文件>] 进入 UTS 名字空间(主机名等)
-i, --ipc[=<文件>] 进入 System V IPC 名字空间
-n, --net[=<文件>] 进入网络名字空间
-p, --pid[=<文件>] 进入 pid 名字空间
-C, --cgroup[=<文件>] 进入 cgroup 名字空间
-U, --user[=<文件>] 进入用户名字空间
-S, --setuid <uid> 设置进入空间中的 uid
-G, --setgid <gid> 设置进入名字空间中的 gid
--preserve-credentials 不干涉 uid 或 gid
-r, --root[=<目录>] 设置根目录
-w, --wd[=<dir>] 设置工作目录
-F, --no-fork 执行 <程序> 前不 fork
-Z, --follow-context 根据 --target PID 设置 SELinux 环境
-h, --help display this help
-V, --version display version
更多信息请参阅 nsenter(1)。
通过 nsenter -t <pid> -n bash 即可进入 pid 指向的进程的 net namespace,并在这个 namespace 执行 bash 命令,之后,在这个 bash session 里执行 curl、ip、ifconfig 等命令,看到的网络信息就都是容器内部的网络信息。
实战
在 Linux 上,通过夜莺的 docker-compose 拉起一套夜莺,使用 bridge 模式,做个演示。
1. 拉起夜莺
[root@aliyun-2c2g40g3m compose-bridge]# docker compose up -d
[+] Running 7/7
✔ Network compose-bridge_nightingale Created &n

本文介绍了如何在容器镜像中没有curl命令的情况下,通过nsenter工具进入容器的netnamespace,使用宿主机的curl命令进行网络探测。方法涉及理解容器namespace原理,以及在Linux环境下实战演示了如何通过nsenter和ipnetnsexec执行命令,实现与容器内部网络通信。
最低0.47元/天 解锁文章
1573

被折叠的 条评论
为什么被折叠?



