查看 Kubernetes 端口暴露的完整指南
以下是对 Kubernetes 环境中查看端口暴露情况的详细指南,涵盖从节点到 Pod 的各种检查方法。通过这些步骤,可以全面验证端口是否正常暴露并对外可达。
在节点层面,可以使用 netstat
、ss
和 lsof
等工具来检查端口监听情况。这些工具能够显示所有 TCP/UDP 监听端口及其对应的 PID 和进程名,帮助确认节点上是否有进程在监听期望的端口。接着,在 Pod 或容器内部,通过 kubectl exec
命令获取 Pod 的 Shell,然后使用 netstat
、ss
或 lsof
等命令检查容器内部的端口监听情况。此外,还可以利用 kubectl describe pod
命令查看 Pod 的端口声明,了解容器配置的端口信息。为了进一步验证应用是否正常监听端口,可以在容器内部使用 curl
或 telnet
等工具进行连通性测试,直接访问应用端口并检查响应。
若需从集群外部验证端口暴露情况,可以使用 telnet
或 curl
测试节点 IP 和端口的连通性,或者借助 nmap
进行端口扫描,查看端口是否处于开放状态。在涉及 Kubernetes Service 或 HostNetwork 模式时,需要特别注意 Pod 与节点之间的网络配置。例如,在 HostNetwork 模式下,Pod 与节点共享网络命名空间,容器直接绑定宿主机接口,此时节点层面的网络工具输出中,监听端口的进程即为容器进程。而使用 NodePort 或 LoadBalancer 类型的 Service 时,即使 Pod 非 HostNetwork 模式,也可以通过 Service 在节点层面暴露端口,此时可在节点上检查 Service 的端口监听情况。
在排查端口暴露问题时,常见的故障包括端口未监听、节点层未见监听、外部无法访问以及 Service 配置错误等。针对这些问题,可以分别采取检查容器内网络工具输出、确认 HostNetwork 或 HostPort 配置、检查防火墙设置以及查看 Service 的端口映射和 Endpoints 等方法进行排查。通过这些详细的检查步骤和方法,可以有效验证 Kubernetes 环境中端口的暴露情况,确保系统的正常运行和连通性。
查看端口暴露
下面给出一个概要,然后分几个方面详细说明在节点和 Pod 两端如何检查端口是否正常暴露。
概要
要验证端口是否暴露,通常需要在节点层面和Pod/容器层面分别检查:
- 在 节点 上确认进程是否监听了期望端口(如用
netstat
、ss
、lsof
等)。 - 在 Pod/容器 内部确认应用是否在监听,并测试连通性(如用
kubectl exec
+curl
/telnet
)。 - 如需从集群外部验证,可以用 Nmap、telnet 或 curl 等工具测试节点 IP:端口 的可达性。
1. 在节点上检查端口监听
1.1 使用 netstat
netstat -tulpen | grep <端口号>
-tulpen
:显示所有 TCP/UDP 监听端口及其 PID/进程名。(Server Fault)
1.2 使用 ss
ss -ltnp | grep <端口号>
-ltnp
:列出监听的 TCP 端口及对应进程。(andreasgerstmayr.at)
1.3 使用 lsof
sudo lsof -nP -iTCP:<端口号> -sTCP:LISTEN
-nP
:禁用域名和端口号解析,加快输出。(Unix & Linux Stack Exchange)
2. 在 Pod/容器内验证
2.1 获取 Pod Shell
kubectl exec -it <pod-name> -- sh
或
kubectl exec -it <pod-name> -- bash
- 进入容器内部后,同样可以用前述
netstat
/ss
/lsof
命令检查监听。(Kubernetes)
2.2 查看 Pod 端口声明
kubectl describe pod <pod-name>
在输出的 Containers → Ports 部分,会显示容器声明的端口列表。(Kubernetes)
2.3 直接测试应用端口
-
curl
(HTTP 服务)curl -v localhost:<端口号>
可查看 HTTP 响应头与状态。(Medium)
-
telnet
(任意 TCP 服务)telnet localhost <端口号>
若能连上,则说明监听正常。(Acronis)
3. 从节点/集群外部测试连通性
3.1 使用 telnet
或 curl
telnet <节点IP> <端口号>
# 或针对 HTTP
curl -v http://<节点IP>:<端口号>
若能建立 TCP 连接或收到 HTTP 响应,则暴露正常。(Acronis)
3.2 使用 nmap
端口扫描
nmap -p <端口号> <节点IP>
能扫描到 “open” 状态即代表端口对外开放。(Server Fault)
4. 配合 Kubernetes Service / HostNetwork 情况
- HostNetwork 模式:Pod 与节点共享网络命名空间,容器直接绑定宿主机接口。此时节点层面的
netstat
/ss
输出里,监听端口的进程即为容器进程,无需额外的 DNAT/Proxy。(Server Fault, SigNoz) - NodePort/LoadBalancer:即使 Pod 非 HostNetwork 模式,也可通过 Service 在节点层面暴露端口;此时可在节点上也用上述工具检查 Service 的端口。
5. 常见故障与排查
问题 | 排查方法 |
---|---|
端口未监听 | 检查容器内 netstat /ss /lsof ;确认应用启动命令 |
节点层未见监听 | 确认是否启用 HostNetwork 或设置了 HostPort |
外部无法访问 | 检查防火墙(iptables、Security Group)、云提供商网络 |
Service 配置错误 | 查看 kubectl describe svc 中的端口映射与 Endpoints |
通过上述节点层与容器层的组合检查,并辅以常用网络工具,即可全面验证端口是否正常暴露并对外可达。
bind()
以下方法可以帮助你确认容器运行时(containerd/CRI-O + crun/runc)在 “hostNetwork” 模式下是如何 bind()
到宿主机接口的,并验证绑定是否生效。
概览:
- 使用主机级网络工具(
ss
/netstat
/lsof
)直接查看宿主机上哪个进程监听了端口。- 通过
crictl
+nsenter
找到容器的 Pause 或应用进程 PID,再用strace
跟踪其bind()
调用。- 使用 Linux Audit 框架 (
auditd
/auditctl
) 对bind
系统调用进行审计,捕获所有相关事件。
1. 在宿主机层面验证监听进程
1.1 使用 ss
ss -ltnp | grep :<端口号>
-ltnp
显示所有 TCP 监听端口及其进程名/PID。若容器在 HostNetwork 模式下绑定<端口号>
,你会直接看到对应的 runc/crun 或应用进程。 (GitHub)
1.2 使用 netstat
netstat -tulpen | grep <端口号>
-tulpen
除显示监听端口,还列出 UID/PID 与进程信息。 (Stack Overflow)
1.3 使用 lsof
sudo lsof -nP -iTCP:<端口号> -sTCP:LISTEN
- 直接列出哪个程序(及其 PID)在监听该端口,若为容器进程则可确认 bind() 成功。 (Docker Community Forums)
2. 找到容器进程并 Strace 跟踪 bind()
2.1 获取容器 PID
-
使用
crictl ps
找到目标容器或 Sandbox(Pause)ID。 -
然后执行:
crictl inspect --output go-template --template '{{.info.pid}}' <容器或SandBox ID>
可获取该容器在宿主机上的主进程 PID。 (Kubernetes)
2.2 直接跟踪 bind()
sudo strace -f -e trace=network -p <PID>
-f
跟踪子进程,trace=network
会捕获bind()
、connect()
等网络相关系统调用。- 在输出中查找诸如
bind(3, {sa_family=AF_INET, sin_port=htons(<端口号>)…}, …) = 0
的条目,确认进程确实调用了bind()
并成功返回。 (Reddit)
2.3 在网络命名空间内 Strace
如果应用运行在单独的网络命名空间中(非 HostNetwork 模式),可先使用 nsenter
进入该命名空间再跟踪:
# 找到 Pause 容器的 PID,假设为 $PAUSE_PID
nsenter -t $PAUSE_PID -n strace -f -e bind -p $PAUSE_PID
-n
指定网络命名空间,确保你看到的是容器内部的bind()
情况。 (红帽)
3. 用 Auditd 审计所有 bind()
调用
-
安装并启动
auditd
:sudo apt-get install auditd sudo systemctl enable --now auditd
-
添加审计规则捕获所有
bind
系统调用:sudo auditctl -a exit,always -S bind -F success=1 -k container-bind
-k container-bind
是自定义的关键字标签,便于过滤日志。 (Medium)
-
查看审计日志:
sudo ausearch -k container-bind | aureport -f
- 日志条目会显示调用进程的 PID、可执行文件路径、
bind()
参数等,能全面追踪哪个进程在哪个接口上做了绑定。 (Red Hat Customer Portal)
- 日志条目会显示调用进程的 PID、可执行文件路径、
4. 验证与排查要点
- 进程名称:在
ss
/lsof
/strace
中确认监听的进程名是否为crun
、runc
、或你的应用二进制。 - PID 对应:用
ps -fp <PID>
核对进程属主及命令行,排除其它同端口进程干扰。 - 网络策略:若使用了
hostNetwork
,CNI 插件不会为该 Pod 创建独立网络命名空间,故无需检查 CNI 配置。 (Super User) - 权限:对
strace
和auditctl
操作需要CAP_SYS_ADMIN
或 root 权限。
通过以上三种手段——主机网络工具、系统调用跟踪、以及审计日志——你可以系统化地查看并确认容器在 HostNetwork 模式下对宿主机接口的 bind()
行为。