Bash 如何等待Kubernetes将外部IP分配给负载平衡器服务?
创建会立即返回(例如:Bash 如何等待Kubernetes将外部IP分配给负载平衡器服务?,bash,kubernetes,Bash,Kubernetes,创建会立即返回(例如:kubectl create-f…或kubectl expose svc NAME--NAME=LoadBalancer--port=80--type=LoadBalancer) 我知道在shell中手动等待的方法: external_ip="" while [ -z $external_ip ]; do sleep 10 external_ip=$(kubectl get svc load-balancer --template="{{range .sta
kubectl create-f…
或kubectl expose svc NAME--NAME=LoadBalancer--port=80--type=LoadBalancer
)
我知道在shell中手动等待的方法:
external_ip=""
while [ -z $external_ip ]; do
sleep 10
external_ip=$(kubectl get svc load-balancer --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}")
done
但这并不理想:
- 至少需要5行Bash脚本
- 即使在出现错误的情况下也会无限等待(否则需要超时,这会增加批次行计数)
- 可能效率不高;可以使用
或--wait
,但使用这些命令将永远不会返回--wait once
我们没有一个通用的“wait-for-expression”命令,因为它最终会变得任意复杂,最好用一种真正的语言编写它。在上面的bash循环中遍历。我们可以更好地使用“watch”命令,但最后还是超时。为了补充这里的答案,现在最好的选择是使用bash脚本。为了方便起见,我将其放在一行中,其中包括导出环境变量 等待并查找Kubernetes服务端点的命令
bash -c 'external_ip=""; while [ -z $external_ip ]; do echo "Waiting for end point..."; external_ip=$(kubectl get svc NAME_OF_YOUR_SERVICE --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}"); [ -z "$external_ip" ] && sleep 10; done; echo "End point ready-" && echo $external_ip; export endpoint=$external_ip'
我还修改了您的脚本,使其仅在ip不可用时执行等待。最后一位将导出名为“endpoint”的环境变量
检查给定服务的Bash脚本
将此保存为check endpoint.sh
,然后可以执行$sh check-endpoint.sh SERVICE\u NAME
#!/bin/bash
# Pass the name of a service to check ie: sh check-endpoint.sh staging-voting-app-vote
# Will run forever...
external_ip=""
while [ -z $external_ip ]; do
echo "Waiting for end point..."
external_ip=$(kubectl get svc $1 --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}")
[ -z "$external_ip" ] && sleep 10
done
echo 'End point ready:' && echo $external_ip
在Codefresh步骤中使用此选项
我将其用于Codefresh管道,完成后它将传递一个变量$endpoint
GrabEndPoint:
title: Waiting for endpoint to be ready
image: codefresh/plugin-helm:2.8.0
commands:
- bash -c 'external_ip=""; while [ -z $external_ip ]; do echo "Waiting for end point..."; external_ip=$(kubectl get svc staging-voting-app-vote --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}"); [ -z "$external_ip" ] && sleep 10; done; echo "End point ready-" && echo $external_ip; cf_export endpoint=$external_ip'
实际上,这只是对@Dan Garfield工作示例的清理;我的强迫症患者不会放过这一切。在这种情况下:
- 关于GCP
- 请求内部lb
- 在服务定义中使用注释
注意:我只能通过外部dns将名称与公共IP地址相关联
这已经被脚本化为接受一些参数,现在它是一个库;例如:
myServiceLB=$1
while true; do
successCond="$(kubectl get svc "$myServiceLB" \
--template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}")"
if [[ -z "$successCond" ]]; then
echo "Waiting for endpoint readiness..."
sleep 10
else
sleep 2
export lbIngAdd="$successCond"
pMsg """
The Internal LoadBalancer is up!
"""
break
fi
done
稍后,$lbIngAdd
可用于设置记录。似乎-o jsonpath=“{.status.loadBalancer.ingres[*].ip}”
也可以工作;只要行得通
感谢您让我们开始Dan:-)这是一个通用的bash函数,用于在给定命令的输出中查看任何regexp:
function watch_for() {
CMD="$1" # Command to watch. Variables should be escaped \$
REGEX="$2" # Pattern to search
ATTEMPTS=${3:-10} # Timeout. Default is 10 attempts (interval of second)
COUNT=0;
echo -e "# Watching for /$REGEX/ during $ATTEMPTS seconds, on the output of command:\n# $CMD"
until eval "$CMD" | grep -m 1 "$REGEX" || [[ $COUNT -eq $ATTEMPTS ]]; do
echo -e "$(( COUNT++ ))... \c"
sleep 1
done
if [[ $COUNT -eq $ATTEMPTS ]]; then
echo "# Limit of $ATTEMPTS attempts has exceeded."
return 1
fi
return 0
}
下面是我如何使用它来等待工作节点获得外部IP(这花费了一分钟多):
0。。。1.2.3.63... 64…
3.22.37.41这是一个有点棘手的工作解决方案:
kubectl get service-w load balancer-o'go template={{{with.status.loadBalancer.ingres}}{{range.}}{{.ip}}{{{{{n}}{{{end}}{{.err}{end}}2>/dev/null{head-n1
也许这不是您正在寻找的解决方案,但至少它的代码行更少:
until [ -n "$(kubectl get svc load-balancer -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" ]; do
sleep 10
done
“失败”是什么意思?整个系统将停止尝试?为什么?然后它是否应该将服务标记为失败?我不清楚您想要实现什么-您是否不知道环境是否支持LB?或者你认为云提供商会失败?不管怎样-你已经有办法做到这一点,你只是不喜欢循环:)失败意味着退出1,如果没有外部IP已在X秒内分配。是的,我不喜欢创建要部署的脚本。部署应该尽可能简单,以避免脚本中的错误造成严重损害,因为每个项目一个脚本比所有Kuberentes项目的通用脚本/功能更有可能出现错误。我不反对kubectl中的通用“等待条件,可选超时”命令,但概括起来很复杂,可能需要一段时间。通过将其包装在shell循环中,您将更快地获得结果。
kubectl get svc$1--output=“jsonpath={.status.loadBalancer.ingres[0].hostname}”
适用于我.status.loadBalancer.ingres[0].hostname>如果您在AWS或其他提供程序上运行k8s,而该提供程序的负载均衡器不受IP支持,而是由DNS名称支持
$ watch_for "kubectl get nodes -l node-role.kubernetes.io/worker -o wide | awk '{print \$7}'" \
"[0-9]" 100
until [ -n "$(kubectl get svc load-balancer -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" ]; do
sleep 10
done