首页 > 解决方案 > 如何在运行 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.1IP地址还是我缺少其他东西。

主脚本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}

标签: kubernetesminikube

解决方案


虽然我还没有找到使用 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

推荐阅读