kubectl等待AWS EKS上的服务公开.status.loadBalancer.ingress字段中报告的弹性负载均衡器(ELB)地址 [英] kubectl wait for Service on AWS EKS to expose Elastic Load Balancer (ELB) address reported in .status.loadBalancer.ingress field
问题描述
ASthe kubernetes.io docs state about a Service
of type LoadBalancer
:
在支持外部负载均衡器的云提供商上,设置
LoadBalancer为您的提供负载平衡器的类型字段
服务。发生负载均衡器的实际创建
异步,有关所配置的均衡器的信息是
在服务的.status.loadBalancer
字段中发布。
在AWS Elastic Kubernetes Service(EKS)上,配置了AWS负载均衡器,用于负载平衡网络流量(see AWS docs&;the example project on GitHub provisioning a EKS cluster with Pulumi)。假设我们已准备好Deployment
和选择器app=tekton-dashboard
(它是default Tekton dashboard you can deploy as stated in the docs),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 GET将自动创建:
.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}'
输出将为空字段:
{}%
因此,如果我们要在配置项管道中运行此安装程序(例如GitHub Actions, see the example project's workflow provision.yml
),我们需要以某种方式等待,直到.status.loadBalancer
字段填充了AWS ELB的主机名。我们如何使用kubectl wait
实现此目的?
推荐答案
tldr;
Prior to 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
甚至增强命令using timeout(brew install coreutils
on a 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等待问题&详细说明的解决方案
如this so Q&A和Kubernetes问题kubectl wait unable to not wait for service ready #80828&;kubectl wait on arbitrary jsonpath #83094中所述,目前在Kubernetes当前版本中无法使用kubectl wait
实现此目的。
主要原因是kubectl wait
假设使用kubectl get service/xyz --output=yaml
查询的Kubernetes资源的status
字段包含conditions
列表。这是Service
所没有的。这里使用jsonpath将是一种解决方案,并且从Kubernetesv1.23
开始是可能的(请参见this merged PR)。但是,在这个版本广泛应用于像EKS这样的托管Kubernetes集群之前,我们需要另一个解决方案。并且它也应该像kubectl wait
一样作为&qot;一行程序&qot;可用。
一个很好的起点可能是这个超级用户关于"watching" the output of a command until a particular string is observed and then exit的答案:
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}'
VIA):
$ 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}'
Here's also a full GitHub Actions pipeline run如果您感兴趣。
这篇关于kubectl等待AWS EKS上的服务公开.status.loadBalancer.ingress字段中报告的弹性负载均衡器(ELB)地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!