nsenter命令簡介


nsenter命令簡介

nsenter命令是一個可以在指定進程的命令空間下運行指定程序的命令。它位於util-linux包中。

 

用途

一個最典型的用途就是進入容器的網絡命令空間。相當多的容器為了輕量級,是不包含較為基礎的命令的,比如說 ip address,ping,telnet,ss,tcpdump 等等命令,這就給調試容器網絡帶來相當大的困擾:只能通過 docker inspect ContainerID 命令獲取到容器IP,以及無法測試和其他網絡的連通性。這時就可以使用nsenter命令僅進入該容器的網絡命名空間,使用宿主機的命令調試容器網絡。此外,nsenter也可以進入 mnt, uts, ipc, pid, user 命令空間,以及指定根目錄和工作目錄。

 

原理

namespace

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

Linux的每個進程都具有命名空間,可以在/proc/PID/ns目錄中看到命名空間的文件描述符。

 

使用

nsenter [options] [program [arguments]]

options:
-t, --target pid:指定被進入命名空間的目標進程的pid
-m, --mount[=file]:進入mount命令空間。如果指定了file,則進入file的命令空間
-u, --uts[=file]:進入uts命令空間。如果指定了file,則進入file的命令空間
-i, --ipc[=file]:進入ipc命令空間。如果指定了file,則進入file的命令空間
-n, --net[=file]:進入net命令空間。如果指定了file,則進入file的命令空間
-p, --pid[=file]:進入pid命令空間。如果指定了file,則進入file的命令空間
-U, --user[=file]:進入user命令空間。如果指定了file,則進入file的命令空間
-G, --setgid gid:設置運行程序的gid
-S, --setuid uid:設置運行程序的uid
-r, --root[=directory]:設置根目錄
-w, --wd[=directory]:設置工作目錄

如果沒有給出program,則默認執行$SHELL。

 

示例:

這里我隨便運行了一個容器並查看容器pid

[root@Wshile ~]# docker inspect -f {{.State.Pid}} 091f114de06e
5645

然后,使用nsenter命令進入該容器的網絡命令空間:

[root@Wshile ~]# nsenter -n -t5645
[root@Wshile ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
18: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

進入成功。

在Kubernetes中,在得到容器pid之前還需獲取容器的ID,可以使用如下命令獲取:

[root@Wshile test]# kubectl get pod test -oyaml|grep containerID
  - containerID: docker://cf0873782d587dbca6aa32f49605229da3748600a9926e85b36916141597ec85

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM