为什么 kubectl port-forward 要求目标服务绑定到 localhost?

为什么 kubectl port-forward 要求目标服务绑定到 localhost?

我注意到,kubectl port-forward只有当转发到的进程正在监听127.0.0.1或时,端口转发才有效localhost。如果进程绑定到另一个地址(如 pod IP),则端口转发不起作用。

例如,假设我有一个程序在 pod IP 和端口 8080 上打开一个服务器套接字,那么这个端口转发不起作用:

kubectl port-forward hasura-console-5d48cdb974-sv4l8 8080:8080

当我尝试使用它时,它的日志如下:

E0314 21:11:33.613318   93858 portforward.go:400] an error occurred forwarding 8080 -> 8080: error forwarding port 8080 to pod 9902636a8681f668702476c9e4148d6e4cd63ba20f4b3270fdc3c57d9ef9cb97, uid : exit status 1: 2021/03/15 01:11:34 socat[1486564] E connect(5, AF=2 127.0.0.1:8080, 16): Connection refused

当我重新启动正在监听服务的 pod 时127.0.0.1,端口转发正常,并且未记录上述错误。

pod 中运行的服务是否需要在本地主机上监听?

答案1

如果仍然需要,澄清原始问题:

pod 中运行的服务是否需要在本地主机上监听?

它们不需要在本地主机上监听,但kubectl port-forward如果不指定选项--address并访问运行此命令的服务,则会设置127.0.0.1当您访问“您的”本地主机时,此命令将设置为目的地(根据官方的默认行为)文档)。

运行后,kubectl port-forward然后使用 Kubernetes API 将 TCP 流量从本地机器隧道传输到 Pod 和命令中提供的端口。

这就是为什么它在监听时可以工作localhost,但在 Pod 的 IP 上却不工作,因为您没有直接访问它。

请记住,Pod IP 在重新创建时会发生变化,并且通常无法直接访问,因为它主要用于 Kubernetes 集群内部使用,因此0.0.0.0如果您希望在访问集群的 IP 时从外部访问它,那么让服务监听它是有意义的。

通过当前临时 IP 直接访问 Pod 通常用于调试或测试目的,不用于生产。

答案2

我注意到,只有当转发到的进程正在监听 127.0.0.1 或 localhost 时,kubectl port-forward 才有效。如果进程绑定到其他地址(如 pod IP),则端口转发不起作用。

Kubernetes 中拥有 IP 地址的单元是. Pod 可以包含一个或多个容器,它们可以暴露端口。您可以使用以下方式连接到这些端口:

kubectl port-forward <pod-name> <your-local-port>:<container-port>

要查看 Pod(以您的 Pod 名称为例)中容器公开的端口,您可以运行以下命令:

kubectl get pod hasura-console-5d48cdb974-sv4l8 --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'

请注意,kubectl port-forward仅适用于 TCP。

也可以看看使用端口转发访问集群中的应用程序


容器中的主进程应该监听什么地址?

在 Kubernetes 中创建在容器内运行的进程时,它必须0.0.0.0。参见例如Stackoverflow 上的这个答案关于要听取什么IP。

相关内容