使用 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
希望能够保持连接
将 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 在连接丢失时重新连接
我通过保持连接活跃来解决这个问题,例如使用curl或nc。
转发端口:
kubectl --namespace somenamespace port-forward somepodname 50051:50051
在另一个终端中,每 10 秒访问一次端口以保持连接处于活动状态:
while true ; do nc -vz 127.0.0.1 50051 ; sleep 10 ; done
似乎有 5 分钟超时,可以用
kubelet
参数覆盖:
https://github.com/kubernetes/kubernetes/issues/19231
如果您想将超过 5 分钟(或无限制)的内容传递到 kubelet 中,您可以指定
。例如。streaming-connection-idle-timeout
将其设置为 4 小时。或者:--streaming-connection-idle-timeout=4h
使其不受限制。 (已弃用:此参数应通过 Kubelet 的 --config 标志指定的配置文件设置。有关更多信息,请参阅 https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/。 )--streaming-connection-idle-timeout=0
为Windows制作这样的蝙蝠(上帝原谅我)
:1
oc port-forward PODNAME 8003:8080
goto 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(如果您的环境允许)。
这是我使用的 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
简单的
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
感谢@Pigueiras的回答,我使用minikube解决了这个问题。
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