我编写了一个脚本,该脚本启动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
在脚本中放入sleep
的简短内容,如何在运行port-forward之前检查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}
答案 0 :(得分:2)
尽管我还没有找到使用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
答案 1 :(得分:0)
但是我发现即使kubelet准备就绪,该ss命令也找不到它。我不知道这是由于127.0.1.1 ip地址引起的还是我遗漏了其他东西。
minikube在计算机上的VM上运行,该VM具有自己的接口和IP地址。您可以使用minikube ip
因此,如果您这样做:
curl -X GET http://$(minikube ip):10250/healthz
假设您已经配置了following options:
--healthz-bind-address 0.0.0.0
The IP address for the healthz server to serve on (set to 0.0.0.0 for all IPv4 interfaces and `::` for all IPv6 interfaces) (default 127.0.0.1)
--healthz-port int32
The port of the localhost healthz endpoint (set to 0 to disable) (default 10248)