乐趣区

关于kubernetes:使用nsenter进行docker网络连通性测试

背景

在 docker 中,为了尽可能缩减镜像大小,经常不会蕴含一些罕用的工具,相似 ping,curl,tcpdump 等,尽管精简了镜像,但如果咱们须要在容器内部测试网络联通性时,没有这些工具就十分的头疼。其实容器外部和主机之间的网络环境是相互隔离的,处于独立的命名空间下,那如果能在主机上切换命名空间,就能够在主机上以容器的网络环境进行操作,就能够利用主机上的工具,可能实现这种需要的工具就是咱们明天要介绍的nsenter

应用

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。

ping

以 nginx 镜像为例,nginx 镜像默认是不蕴含 ping 命令,也不蕴含 ip,ifconfig 等常用命令

# docker run --name nginx-app -d nginx
2c0b7246f4a10d043e07527fdc4c3237c7af9d643741c954d4a84ece37976014
# docker exec -it nginx-app bash
root@2c0b7246f4a1:/# ping www.baidu.com
bash: ping: command not found
# ip addr
bash: ip: command not found
# ifconfig
bash: ifconfig: command not found

很多时候咱们须要晓得容器外部解析的域名 ip 信息,如果没有这些工具,原本很简略的事就变得很麻烦,通过以下步骤就能够通过 nsenter 解决以上问题

  • 获取容器 pid
# docker inspect nginx-app -f '{{.State.Pid}}'
23069
#也能够通过 ContainerID
docker inspect 2c0b7246f4a1 -f '{{.State.Pid}}'
23069
  • 执行 nsenter 命令
# nsenter -n -t23069
# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.5  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:5  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ac:11:00:05  txqueuelen 0  (Ethernet)
        RX packets 3  bytes 222 (222.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

这个命令没有任何输入,通过 ifconfig 命令查看以后 ip 能够确定咱们曾经进入了容器的网络空间

这时候主机上的命令都能够应用

]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.5/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:5/64 scope link 
       valid_lft forever preferred_lft forever
# ping www.baidu.com
PING www.a.shifen.com (180.101.49.12) 56(84) bytes of data.
64 bytes from 180.101.49.12 (180.101.49.12): icmp_seq=1 ttl=49 time=10.1 ms
64 bytes from 180.101.49.12 (180.101.49.12): icmp_seq=2 ttl=49 time=10.1 ms
  • 退出

如果想退出以后网络空间,返回零碎网络空间,输出 exit 就行

# exit
logout

kubernetes

如果是 kubernetes 的话事件会变得略微简单点,首先你得确定你的利用部署在哪个节点上,还要确定 containerid

# kubectl get po {pod 名称} -n {命名空间} -ojsonpath='{..nodeName}'
k8s-node-dev-1
# kubectl get po {pod 名称} -n {命名空间} -ojsonpath='{...containerStatuses[0].containerID}'
docker://6dee4b562504cd63480e56e65f692943ce368a85b08ed1090171afc2c4f0f6a7

拿到 containerid 后就能够登录到 pod 所在的主机上依照下面的步骤进行操作

在 kubernetes 中最罕用的应该是咱们须要一个 service 的地址,通过 nsenter 工具进入 pod 的网络空间后,能够通过 ping {服务名称} 获取服务 ip

nsenter是 Linux 平台上的工具,不实用 windows 和 Mac

退出移动版