为什么主机端口没有显示在主机的Netstat输出中



我使用带有yaml文件的kubectl创建目标pod,发现pod中的进程正在按预期侦听目标端口。

令我惊讶的是,在主机的netstat -tunlpnetstat -alpnetstat -an的输出中没有看到端口。但如果我尝试telnet localhost targetPort,它会起作用!!!

为什么会发生这种情况??有人能解释一下吗?

这是因为docker。默认情况下,docker不会将容器网络名称空间添加到linux运行时数据(/var/run从/run装载为tmpfs(,这是您在运行ipnetns命令时看到的。

要查看网络名称空间,您需要使用nsenter

  1. 获取容器id
docker ps
  1. 获取容器进程id
docker inspect --format '{{ .State.Pid }}' <<container-id>>
  1. 现在使用nsenter来显示pod网络空间。与docker exec相比,使用nsenter的优势在于nsenter将使您能够执行pod内节点上可用的所有工具或命令,因为docker exec将只允许有限或受限的命令
nsenter -t <<container pid>> -n netstat -tunlp 

为了访问工作节点上的服务,您必须使用NodePort类型的服务公开工作节点的pod。在pod中运行的进程位于不同的网络名称空间中。您可以从pod内部访问应用程序,但不能从没有服务对象的节点访问。参见以下参考:

$ kubectl create deploy nginx --image=nginx
$ kubectl expose deploy nginx --target-port 80 --port 80 --type NodePort
$ NODE_PORT=$(kubectl get svc nginx -ojsonpath='{ .spec.ports[0].nodePort }')
$ netstat -an | grep $NODE_PORT
tcp46      0      0  *.31563                *.*                    LISTEN     
$ curl localhost:$NODE_PORT
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

HTH-

由于pod中的容器在其自己的网络命名空间中运行,因此netstat无法检测到它们。

要列出容器内侦听的端口,请使用nsenter。这个工具将帮助您在进程的不同命名空间上执行命令(在我们的例子中是所需容器的PID(。

  1. 在K8s工作节点上获取容器-SSH的PID并运行docker inspect <containerid>(如果docker是您的容器运行时(

从上面的命令获取PID后,运行

  1. $ nsenter -t <container-PID> -n netstat -nltp
nsenter -t <container-PID> -n netstat -nltp

该命令显示容器端口,而不是主机端口,现在仍然回答问题

传入连接可以使用iptable规则直接路由到k8s网络中(例如,当使用Calico CNI时(。

你可以试试

iptable -L -t nat

看看你的主机端口是否出现在那里。

请参阅此处的说明:

https://www.reddit.com/r/kubernetes/comments/kne734/help_demystify_hostport_networking_please/

相关内容

  • 没有找到相关文章

最新更新