【K8s】专题十五(6):Kubernetes 网络之 Pod 网络调试
本文内容均来自个人笔记并重新梳理,如有错误欢迎指正!
如果对您有帮助,烦请点赞、关注、转发、订阅专栏!
专栏订阅入口
| 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 |
往期精彩文章
【Docker】(全网首发)Kylin V10 下 MySQL 容器内存占用异常的解决方法
【Docker】(全网首发)Kylin V10 下 MySQL 容器内存占用异常的解决方法(续)
【K8s】专题十五(5):Kubernetes 网络之 CoreDNS
目录
一、基本介绍
二、Pod 网络调试
1、调试工具
2、调试原理
3、调试过程
三、nsenter 常用参数
一、基本介绍
在实际工作中,我们经常会遇到一些疑似网络方面的故障问题,从而需要对 Kubernetes 集群中的 Pod 进行网络调试。
但是由于最小化原则,Pod 的容器镜像中通常并不会安装 ping、curl、telnet、tcpdump 等调试工具,或者在 Pod 容器中可以临时安装工具但是效率不高,都给 Pod 网络调试带来困难。
针对上述场景的问题,笔者将在本文介绍一种 Pod 网络调试方法,以灵活应对网络调试需求。
二、Pod 网络调试
1、调试工具
nsenter 是 Linux 操作系统的一种命令行工具,允许用户进入指定进程的某个命名空间,并在该命名空间下灵活使用主机的命令行工具、执行特权操作等。
命名空间则是 Linux 内核的一种功能,用于将进程的资源隔离在不同的环境中,从而提高安全性和可靠性。常见的命名空间包括:
- Mount:文件系统命名空间
- UTS:主机名和域名命名空间
- IPC:进程间通信命名空间
- PID:进程命名空间
- Network:网络命名空间
- User:用户命名空间
通常在 Linux 操作系统中,默认安装有 nsenter。手动安装命令如下:
yum install -y util-linux || apt install -y util-linux
2、调试原理
在文章【Docker】专题一:Docker 基本架构 中提到,容器的本质是进程,但可以运行于独立的命名空间,拥有自己的 root 文件系统、网络配置、进程空间,甚至用户 ID 空间。
由此可见,我们可以通过 nsenter 进入 Pod 中容器(进程)的网络命名空间,利用 Node 节点已有的命令行工具实现对 Pod 进行网络调试。
3、调试过程
调试过程在使用 Containerd 作为运行时的 Kubernetes 集群中进行验证
- 作为对比,进入 Pod 内容器查看是否安装有 ping、curl、telnet、tcpdump 等调试工具,可以看到相关命令都不存在
kubectl exec -it <pod_name> bash
- 确定 Pod 所在 Node 节点
kubectl get po <pod_name> -owide
- 登录到 Pod 所在 Node 节点
- 在 Node 节点上操作,获取 Pod 内某个容器的 ID
crictl ps | grep <pod_name>
- 根据容器 ID 获取容器 PID
crictl inspect <container_id> | grep -i pid
- 进入容器网络命名空间,并验证
nsenter -t <pid> -n
- 使用 Node 节点已安装的 ping、curl、telnet、tcpdump 等工具进行网络调试接口
三、nsenter 常用参数
-t <pid>:指定要进入的目标进程的 ID
-m:进入目标进程的文件系统命名空间
-u:进入目标进程的用户命名空间
-i:进入目标进程的 IPC 命名空间
-n:进入目标进程的网络命名空间
-p:进入目标进程的 PID 命名空间
--root=/path/to/root:指定容器根文件系统路径(仅在进入挂载命名空间时有效)
--wd=/path/to/workdir:指定工作目录
=======================================================================
nsenter -h
Usage:
nsenter [options] [<program> [<argument>...]]
Run a program with namespaces of other processes.
Options:
-a, --all enter all namespaces
-t, --target <pid> target process to get namespaces from
-m, --mount[=<file>] enter mount namespace
-u, --uts[=<file>] enter UTS namespace (hostname etc)
-i, --ipc[=<file>] enter System V IPC namespace
-n, --net[=<file>] enter network namespace
-p, --pid[=<file>] enter pid namespace
-C, --cgroup[=<file>] enter cgroup namespace
-U, --user[=<file>] enter user namespace
-S, --setuid <uid> set uid in entered namespace
-G, --setgid <gid> set gid in entered namespace
--preserve-credentials do not touch uids or gids
-r, --root[=<dir>] set the root directory
-w, --wd[=<dir>] set the working directory
-F, --no-fork do not fork before exec'ing <program>
-Z, --follow-context set SELinux context according to --target PID
-h, --help display this help
-V, --version display version
For more details see nsenter(1).