![](/img/trans.png)
[英]How to check the status of loadbalancer with AWS Java Elastic Load Balancer SDK
[英]kubectl wait for Service on AWS EKS to expose Elastic Load Balancer (ELB) address reported in .status.loadBalancer.ingress field
作为kubernetes.io 文档 state 关于LoadBalancer
类型的Service
:
在支持外部负载均衡器的云提供商上,将 type 字段设置为 LoadBalancer 会为您的服务提供负载均衡器。 负载均衡器的实际创建是异步发生的,有关已配置均衡器的信息发布在服务的
.status.loadBalancer
字段中。
在 AWS Elastic Kubernetes 服务 (EKS) 上,预置了一个 AWS 负载均衡器来负载均衡网络流量( 请参阅 AWS 文档和GitHub 上的示例项目,使用 Pulumi 预置 EKS 集群)。 假设我们已经使用选择器app=tekton-dashboard
准备好Deployment
(它是您可以按照文档中所述部署的默认 Tekton 仪表板),在tekton-dashboard-service.yml
中定义的LoadBalancer
类型的Service
可能如下所示:
apiVersion: v1
kind: Service
metadata:
name: tekton-dashboard-external-svc-manual
spec:
selector:
app: tekton-dashboard
ports:
- protocol: TCP
port: 80
targetPort: 9097
type: LoadBalancer
如果我们使用kubectl apply -f tekton-dashboard-service.yml -n tekton-pipelines
在集群中创建服务,AWS ELB 会自动创建:
只有一个问题: .status.loadBalancer
字段由ingress[0].hostname
字段异步填充,因此无法立即使用。 如果我们一起运行以下命令,我们可以检查这一点:
kubectl apply -f tekton-dashboard-service.yml -n tekton-pipelines && \
kubectl get service/tekton-dashboard-external-svc-manual -n tekton-pipelines --output=jsonpath='{.status.loadBalancer}'
output 将是一个空字段:
{}%
因此,如果我们想在 CI 管道中运行此设置(例如GitHub 操作,请参阅示例项目的工作流provision.yml
),我们需要以某种方式等到.status.loadBalancer
字段填充了 AWS ELB 的主机名。 我们如何使用kubectl wait
来实现这一点?
TLDR;
在 Kubernetes v1.23
之前,无法使用kubectl wait
,但要与until
一起使用, grep
所示:
until kubectl get service/tekton-dashboard-external-svc-manual -n tekton-pipelines --output=jsonpath='{.status.loadBalancer}' | grep "ingress"; do : ; done
甚至使用超时( brew install coreutils
在 Mac 上)来增强命令,以防止命令无限运行:
timeout 10s bash -c 'until kubectl get service/tekton-dashboard-external-svc-manual -n tekton-pipelines --output=jsonpath='{.status.loadBalancer}' | grep "ingress"; do : ; done'
kubectl wait 的问题&详细解释的解决方案
如本文所述, 因此问答和kubernetes 问题kubectl wait cannot not wait for service ready #80828 & kubectl wait on任意 jsonpath #83094使用kubectl wait
for 这在当前的 Kubernetes 版本中是不可能的。
主要原因是, kubectl wait
假设使用kubectl get service/xyz --output=yaml
查询的 Kubernetes 资源的status
字段包含conditions
列表。 Service
没有。 在此处使用 jsonpath 将是一种解决方案,并且可以从 Kubernetes v1.23
开始(请参阅此合并的 PR )。 但在此版本广泛用于托管 Kubernetes 集群(如 EKS)之前,我们需要另一种解决方案。 它也应该像kubectl wait
一样作为“单线”提供。
一个好的起点可能是关于“观察”命令的 output 直到观察到特定字符串然后退出的超级用户回答:
until my_cmd | grep "String Im Looking For"; do : ; done
如果我们将这种方法与kubectl get
一起使用,我们可以制作一个命令,该命令将等待字段ingress
填充到我们的Service
中的status.loadBalancer
字段中:
until kubectl get service/tekton-dashboard-external-svc-manual -n tekton-pipelines --output=jsonpath='{.status.loadBalancer}' | grep "ingress"; do : ; done
这将等到ingress
字段被填充,然后打印出 AWS ELB 地址(例如,通过使用kubectl get service tekton-dashboard-external-svc-manual -n tekton-pipelines --output=jsonpath='{.status.loadBalancer.ingress[0].hostname}'
之后):
$ until kubectl get service/tekton-dashboard-external-svc-manual -n tekton-pipelines --output=jsonpath='{.status.loadBalancer}' | grep "ingress"; do : ; done
{"ingress":[{"hostname":"a74b078064c7d4ba1b89bf4e92586af0-18561896.eu-central-1.elb.amazonaws.com"}]}
现在我们有了一个单行命令,其行为就像一个kubectl wait
我们的Service
通过 AWS 负载均衡器变得可用。 我们可以仔细检查这是否与以下命令组合使用(确保在执行之前使用kubectl delete service/tekton-dashboard-external-svc-manual -n tekton-pipelines
,否则服务包括。 AWS LoadBalancer 已经存在):
kubectl apply -f tekton-dashboard-service.yml -n tekton-pipelines && \
until kubectl get service/tekton-dashboard-external-svc-manual -n tekton-pipelines --output=jsonpath='{.status.loadBalancer}' | grep "ingress"; do : ; done && \
kubectl get service tekton-dashboard-external-svc-manual -n tekton-pipelines --output=jsonpath='{.status.loadBalancer.ingress[0].hostname}'
如果您有兴趣, 这里还有一个完整的 GitHub Actions 管道运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.