本文介绍了如何使用nsenter工具在k8s中调试容器
需求:
我想进入容器中执行 curl 命令探测某个地址的连通性,但是容器镜像里默认没有 curl 命令。我这里是一个内网环境不太方便使用 yum 或者 apt 安装,怎么办?
这个需求比较典型,这里教大家一个简单的方法,使用 nsenter 进入容器的 net namespace,即可使用宿主机的 curl、ip、ifconfig 等命令,其效果,就跟进入容器中执行是一样的。
原理:
容器像是一个轻量级虚拟机,有自己的 IP,宿主机如果已经监听了 8080 端口,容器里的进程仍然可以重复监听 8080 端口。核心就是因为容器有自己的 namespace,和宿主机的 net namespace 互不影响。
通过 nsenter -t -n bash 即可进入 pid 指向的进程的 net namespace,并在这个 namespace 执行 bash 命令,之后,在这个 bash session 里执行 curl、ip、ifconfig 等命令,看到的网络信息就都是容器内部的网络信息。
找到容器的pid
然后使用 nsenter 进入容器
1
2
3
4
5
6
7
| crictl ps |grep console
crictl inspect ${containerid} |grep pid
nsenter -t ${pid} -n bash
# nsenter -t 62298 -n bash
|
例如查看console容器,能够看到已经进入容器空间,ip是pod容器的ip地址:10.230.96.236
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| [root@arm-master1 ~]# crictl ps |grep console
f7f790ca4093a 9c910f17dc73b 3 weeks ago Running ks-console 0 887ac0301a553 ks-console-6c45c8578b-7hqnd
[root@arm-master1 ~]#
[root@arm-master1 ~]#
[root@arm-master1 ~]# crictl inspect f7f790ca4093a |grep pid
"pid": 62298,
"pid": 1
"type": "pid"
[root@arm-master1 ~]#
[root@arm-master1 ~]# nsenter -t 62298 -n bash
Welcome to 5.10.0-136.12.0.86.ctl3.aarch64
System information as of time: Tue Mar 12 09:19:31 AM CST 2024
System load: 3.01
Processes: 462
Memory used: 65.3%
Swap used: 0.0%
Usage On: 83%
IP address: 10.230.96.236
Users online: 3
[root@arm-master1 ~]# ip a
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if980: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default qlen 1000
link/ether 36:da:f3:ec:b6:24 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.230.96.236/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::34da:f3ff:feec:b624/64 scope link
valid_lft forever preferred_lft forever
[root@arm-master1 ~]#
|
如上,使用 bash 命令进入 net namespace,然后执行 ifconfig,看到 IP:172.22.0.6,显然这就是容器的 IP,说明 nsenter 达成所愿,之后在这个 bash session 内执行 curl、telnet 之类的,就相当于在容器里执行一样的效果。完事执行 exit 命令可以退出这个 net namespace。