在构建镜像的时候,我总是倾向于极简构建,一切没有必要的软件包都不安装,以此来缩小镜像的容量。但是这种做法为后续运维带来了一些困难,如在日常查询、排查问题的时候发现很多命令用不了,不得不在容器中安装额外的命令软件包,本文使用nsenter
工具,实现既不在容器中安装软件包,又能使用命令的功能。
01 先来看看效果吧
-
创建一个容器,使用大小仅5.59MB的
alpine
镜像
docker run -it --rm -d --name test-nsenter alpine sleep 3600
-
进入容器,执行一些命令
docker exec -it test-nsenter /bin/sh
-
使用
nsenter
工具
# 1、找到容器的pid
[root@txy201-51 ~]# docker inspect test-nsenter -f "{{.State.Pid}}"
7327
# 2、使用nsenter进入这个命名空间
[root@txy201-51 ~]# nsenter -t 7327 -n
-
查看
nginx
服务器的日志,可以看到ip
地址是test-nsenter
的地址
02 来聊聊nsenter
是怎么工作的
在Linux
系统里,nsenter
是一个命令行工具,用于进入到另一个 namespace
。譬如,nsenter -n -t 1 bash
就是进入到pid
为1
的进程所在的网络namespace
里。
nsenter
不仅可以进入网络命名空间,还支持文件命名空间、PID
命名空间等。具体可以使用nsenter -h
查看
[root@txy201-51 ~]# nsenter -h
用法:
nsenter [options] [<program> [<argument>...]]
Run a program with namespaces of other processes.
选项:
-a, --all enter all namespaces
-t, --target <pid> 要获取名字空间的目标进程
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
-C, --cgroup[=<file>] enter cgroup namespace
-U, --user[=<file>] enter user namespace
-S, --setuid <uid> set uid in entered namespace
-G, --setgid <gid> set gid in entered namespace
--preserve-credentials do not touch uids or gids
-r, --root[=<dir>] set the root directory
-w, --wd[=<dir>] set the working directory
-F, --no-fork 执行 <程序> 前不 fork
-h, --help display this help
-V, --version display version
更多信息请参阅 nsenter(1)。
[root@txy201-51 ~]#
需要注意的是,如果需要查看容器内的日志,应该使用-m
进入文件系统的命名空间而不是网络空间,不然可能发生找不到文件的尴尬事情。
如果你的设备上没有nsenter
命令,赶紧使用以下命令进行安装吧:
yum install util-linux
我是运维少年,如果文章对您有帮助,欢迎关注我的同名公众号~