kubernetes - 如何在运行 kubectl port-forward 之前检查 kubelet 的准备情况?
问题描述
我编写了一个脚本,它启动 minikube 并用于kubectl port-forward
将本地端口转发到 kubernetes 集群中运行的服务之一。它kubectl port-forward
在后台运行,因此可以在 localhost 上运行 Web 服务器,并访问集群中的服务。
kubectl port-forward
因为 kubelet 还没有准备好接受连接,所以有一个竞争条件失败。
error upgrading connection: error dialing backend: dial tcp 127.0.1.1:10250: getsockopt: connection refused
如果没有在我的脚本中添加a sleep
,我如何在运行端口转发之前检查 kubelet 是否准备就绪?
由于错误消息表明我们希望 kubelet 正在侦听端口 10250 上的 tcp 连接,我想我可以这样做:
ss --listening --tcp --numeric --processes \
'( sport = 10250 )' \
| grep --quiet kubelet
但我发现即使 kubelet 准备好,该ss
命令也找不到它。我不知道这是由于127.0.1.1
IP地址还是我缺少其他东西。
主脚本run-server
, 看起来像:
#! /usr/bin/env bash
LOCAL_PORT=5678
cleanup() {
local pid=$(ss --listening --tcp --processes \
"( sport = ${LOCAL_PORT} )" \
| grep -oP 'pid=\K\d+')
[ -n "$pid" ] && kill "$pid"
}
trap 'cleanup' EXIT
minikube start
run-port-forward $LOCAL_PORT &
FOO_SERVICE_URL=localhost:${LOCAL_PORT} bin/rails server
看起来run-port-forward
像
#! /usr/bin/env bash
LOCAL_PORT=$1
pod=$(kubectl --context=minikube get pod \
| grep -m 1 -oP "foo-service\S*")
port=$(kubectl --context=minikube get pod ${pod} -o json \
| jq -r .spec.containers[0].ports[0].containerPort)
kubectl --context=minikube port-forward \
${pod} ${LOCAL_PORT}:${port}
解决方案
虽然我还没有找到使用 kubectl 检查 kubelet 准备情况的方法,但我想出了一个解决方法,可以重试几次。
这是我第一次在 bash 脚本中使用递归。我从中得到了启发。
try_port_forward() {
retries=$1
if (( retries > 0 )); then
sleep 1
kubectl --context=minikube port-forward \
${pod} ${LOCAL_PORT}:${port} \
2>/dev/null ||
try_port_forward $(( retries - 1 ))
fi
}
try_port_forward 10