kubectl端口转发超时问题

问题描述 投票:0回答:8

使用 kubectl 端口转发功能时,我能够成功将本地端口转发到远程端口。然而,似乎闲置几分钟后连接就断开了。不知道为什么会这样。

以下是用于 portforward 的命令:

kubectl --namespace somenamespace port-forward somepodname 50051:50051

错误信息:

Forwarding from 127.0.0.1:50051 -> 50051
Forwarding from [::1]:50051 -> 50051
E1125 17:18:55.723715    9940 portforward.go:178] lost connection to pod

希望能够保持连接

kubernetes kubectl
8个回答
46
投票

将 kube 的

streaming-connection-idle-timeout
设置为 0 应该是一个正确的解决方案,但如果你不想改变任何东西,你可以使用 while-do 构造

格式:

while true; do <<YOUR COMMAND HERE>>; done

因此只需在 CLI 中输入:

while true; do kubectl --namespace somenamespace port-forward somepodname 50051:50051; done
就应该让 kubectl 在连接丢失时重新连接


42
投票

我通过保持连接活跃来解决这个问题,例如使用curl或nc。

转发端口:

kubectl --namespace somenamespace port-forward somepodname 50051:50051

在另一个终端中,每 10 秒访问一次端口以保持连接处于活动状态:

while true ; do nc -vz 127.0.0.1 50051 ; sleep 10 ; done

38
投票

似乎有 5 分钟超时,可以用

kubelet
参数覆盖:

https://github.com/kubernetes/kubernetes/issues/19231

如果您想将超过 5 分钟(或无限制)的内容传递到 kubelet 中,您可以指定

streaming-connection-idle-timeout
。例如。
--streaming-connection-idle-timeout=4h
将其设置为 4 小时。或者:
--streaming-connection-idle-timeout=0
使其不受限制。 (已弃用:此参数应通过 Kubelet 的 --config 标志指定的配置文件设置。有关更多信息,请参阅 https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/。 )


18
投票

为Windows制作这样的蝙蝠(上帝原谅我)

:1
oc port-forward PODNAME 8003:8080
goto 1

1
投票

如果您在负载均衡器(例如 HAProxy)后面运行 Kubernetes 集群,则 kubelet 中配置的超时可能会大于 HAProxy 中配置的超时。

例如,Kubelet 中的

streamingConnectionIdleTimeout
默认设置为 4h:

$ kubectl proxy --port=8001 &
$ NODE_NAME="XXXX"; curl -sSL "http://localhost:8001/api/v1/nodes/${NODE_NAME}/proxy/configz" | jq '.kubeletconfig|.kind="KubeletConfiguration"|.apiVersion="kubelet.config.k8s.io/v1beta1"' | grep streaming
  "streamingConnectionIdleTimeout": "4h0m0s",

但是,如果在 HAProxy(或您首选的 LB)中,您有以下设置:

defaults
  timeout client 1m
  timeout server 1m
...

如果您在应用程序上没有任何活动,尝试执行端口转发将会超时:

$ date; kubectl port-forward service/XXXX 1234:80
Mon Jul  5 10:58:20 CEST 2021
Forwarding ...
# after a minute
E0705 10:59:21.217577   64160 portforward.go:233] lost connection to pod

为了解决此问题,解决方案是增加超时(请小心,因为根据您的集群,它可能会产生不良影响)或在直接连接到 API 服务器的端口转发时绕过 LB(如果您的环境允许)。


1
投票

这是我使用的 bash 函数,用于绕过超时问题的端口转发:

function pfpod(){
pod=$1
portloc=$2
portrem=$3
while true
  do
    podname=`kubectl get pods -o name | awk -F'/' '{print $2}'| grep "$pod"| head -1`
    kubectl port-forward $podname $portloc:$portrem
done
}

我添加了一个 kubectl 调用来匹配部分 podname,如果您有许多 pod 需要部署,您可以只提供部分名称,然后将使用顶部 pod。否则,您也可以提供完整的 Pod 名称。

用法示例:

pfpod弹性搜索9201 9200


0
投票

简单的

while true
方法的问题是
kubectl port-forward
在超时的情况下不会崩溃 - 有时,但不是每次超时。

我正在使用受 https://github.com/kubernetes/kubernetes/issues/78446#issuecomment-1497776898 启发的以下解决方法,它会检测

kubectl port-forward
输出中的超时并主动终止并重新启动命令 -我尝试过的许多解决方案中唯一有效的解决方案。

仍然出现故障,但连接恢复,大多数应用程序都可以很好地处理。

NAMESPACE=$1
SERVICE=$2
LOCAL_PORT=$3
K8S_SERVICE_PORT=$4

command="kubectl -n $NAMESPACE port-forward svc/$SERVICE $LOCAL_PORT:$K8S_SERVICE_PORT"
while true; do
      echo "--> $command"
      $command 2>&1 >/dev/null |
      while IFS= read -r line
      do
            echo "### $line"
            if [[ "$line" == *"portforward.go"* ]]; then
                  echo "Restarting port forwarding $command"
                  exit 1
            else
                  exit 0
            fi
      done
      if [ $? -eq 0 ]; then
            break;
      fi
done

0
投票

感谢@Pigueiras的回答,我使用minikube解决了这个问题。

在 minikube 中配置 kubelet
streamingConnectionIdleTimeout

删除当前集群:

minikube delete

使用新的 kubelet 配置启动新集群:

streamingConnectionIdleTimeout
设置为
0
,以禁用超时。

minikube start --extra-config=kubelet.streaming-connection-idle-timeout=0

您可以查看配置:

打开代理,访问api:

kubectl proxy --port 8000 &

查看

streaming-connection-idle-timeout
的新值:

curl -k http://localhost:8000/api/v1/nodes/minikube/proxy/configz | jq '.kubeletconfig|.kind="KubeletConfiguration"|.apiVersion="kubelet.config.k8s.io/v1beta1"' | grep streamingConnectionIdleTimeout
© www.soinside.com 2019 - 2024. All rights reserved.