Docker容器拥有特权模式如何操作宿主机

问题

如何在容器中操作宿主机?例如,

  • 重启ssh服务
  • 查看网络配置等等

nsenter命令

简介

nsenter命令是一个可以在指定进程的命名空间下运行指定程序的命令。它位于util-linux包中。

用途

一个最典型的用途就是进入容器的网络命名空间。相当多的容器为了轻量级,是不包含较为基础的命令的,比如说ip address,ping,telnet,ss,tcpdump等等命令,这就给调试容器网络带来相当大的困扰:只能通过docker inspect ContainerID命令获取到容器IP,以及无法测试和其他网络的连通性。这时就可以使用nsenter命令仅进入该容器的网络命名空间使用宿主机的命令调试容器网络。

语法

# 用法:
 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

示例1

运行一个nginx容器,查看该容器的pid:

# 查看容器PID
docker inspect -f {
    
    {
    
    .State.Pid}} nginx
54325
# 进入net命名空间
nsenter -n -t54325
ip addr
# 进入容器nsenter -m -u -i -n -p -t
nsenter --target 54325 --mount --uts --ipc --net --pid
root@164f44ff58d1:/bin#
# 退出命名空间
exit

示例2

在容器内部执行:

# 特权模式启动ubuntu容器
docker run -it --pid=host --privileged=true --rm ubuntu /bin/bash
# 查看宿主机所有进程,引号中的内容就是在宿主机上执行的命令
nsenter -a -t 1 sh -c "ps -ef"

操作宿主机

示例2已非常清楚的举例说明,可以参考实现。具体操作可以参考这位大神的博客:docker容器操作宿主机执行命令

实现原理

参考上述nsenter命令。

Docker 参数介绍

--pid=host

  • 使用宿主机命名空间,方便容器获取到宿主机所有进程信息
  • 把宿主机的/proc文件夹挂载进入容器的/proc路径,其中/proc/1作为nsentertarget,作为容器向宿主机发送命令的关键部分

--privileged=true

  • 使得docker容器有root权限执行宿主机命令,确保从容器执行命令的时候不会产生权限不足错误

--rm

  • 退出容器时会自动将其删除

参考

  1. docker容器操作宿主机执行命令
  2. nsenter命令简介
  3. Linux manual page
  4. docker官方文档

猜你喜欢

转载自blog.csdn.net/ls0111/article/details/127473165