需要
失常状况下这种操作比拟反设计,须要审慎应用
有些时候咱们应用 docker
的时候会须要用到宿主机命令操作,比方
- 执行
netplan apply
失效机器网络配置 - 查看宿主机网络信息应用
ifconfig
或者ip addr
- 从容器收回命令重启宿主机
具体实现
最简略的实现
应用 docker
运行一个 ubuntu
容器
进入容器之后执行 nsenter
命令查看宿主机网络配置信息
$ sudo docker run -it --pid=host --privileged=true ubuntu /bin/bash
# 进入容器外部之后执行
/# nsenter -a -t 1 sh -c "ip addr"
实现原理
docker run
参数
--pid=host
- 应用宿主机命名空间,不便容器获取到宿主机所有过程信息
- 把宿主机的
/proc
文件夹挂载进入容器的/proc
门路,其中/proc/1
作为nsenter
的target
,作为容器向宿主机发送命令的要害局部
--privileged=true
- 使得
docker
容器有root
权限执行宿主机命令,确保从容器执行命令的时候不会产生权限有余谬误
nsenter
命令
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 -a -t 1 sh -c "ip addr"
-a
示意进入宿主机的所有命名空间-t 1
示意获取/proc/1
过程,就是pid=1
的过程,这个过程是docker
应用--pid=host
参数挂载进入容器外部的宿主机过程sh -c "ip addr"
就示意发送给宿主机的命令是ip addr
理论应用过程中如果呈现宿主机和容器命名空间不统一问题,次要产生起因是宿主机内核版本和容器
所默认的加载内核版本不统一
比方 cgroup
是在 Linux4.6
版本退出的,如果应用 Ubuntu20
或者其余 python3.10
等比拟新的镜像启动容器的时候,当 nsenter
应用参数 -a
,容器会加载所有命名空间,然而cgroup
命名空间在旧版本的零碎外面因为内核版本比拟旧,所以该命名空间是没有的,最终 nsenter
命令就会报错
须要依照宿主机有的命名空间来调整 nsenter
参数,能够调整如下
$ nsenter -m -u -i -n -p -t 1 sh -c "ip addr"
比方能够把 -a
参数替换成 -m -u -i -n -p
,明确指定进入mount
, UTS
,System V IPC
, 网络
,pid
命名空间
这几个命名空间蕴含了绝大多数的空间环境,linux
的大部分命令都能够失常执行
命名空间阐明
namespace
是 Linux
中一些过程的属性的作用域,应用命名空间,能够隔离不同的过程
Linux
在一直的增加命名空间,目前有
mount
:挂载命名空间,使过程有一个独立的挂载文件系统,始于Linux 2.4.19
ipc
:ipc
命名空间,使过程有一个独立的ipc
,包含音讯队列,共享内存和信号量,始于Linux 2.6.19
uts
:uts
命名空间,使过程有一个独立的hostname
和domainname
,始于Linux 2.6.19
net
:network
命令空间,使过程有一个独立的网络栈,始于Linux 2.6.24
pid
:pid
命名空间,使过程有一个独立的pid
空间,始于Linux 2.6.24
user
:user
命名空间,是过程有一个独立的user
空间,始于Linux 2.6.23
,完结于Linux 3.8
cgroup
:cgroup
命名空间,使过程有一个独立的cgroup
控制组,始于Linux 4.6
参考浏览
- nsenter 命令简介
- Linux manual page
- docker 官网文档