我注意到,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。