Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait until Kubernetes assigned an external IP to a LoadBalancer service?

Creating a Kubernetes LoadBalancer returns immediatly (ex: kubectl create -f ... or kubectl expose svc NAME --name=load-balancer --port=80 --type=LoadBalancer).

I know a manual way to wait in 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

This is however not ideal:

  • Requires at least 5 lines Bash script.
  • Infinite wait even in case of error (else requires a timeout which increases a lot line count).
  • Probably not efficient; could use --wait or --wait-once but using those the command never returns.

Is there a better way to wait until a service external IP (aka LoadBalancer Ingress IP) is set or failed to set?

like image 833
Wernight Avatar asked Feb 03 '16 14:02

Wernight


People also ask

How Loadbalancer service works in Kubernetes?

This kind of algorithm works by monitoring changes in response latency as the load adjusts based on server capacity. The Kubernetes load balancer sends connections to the first server in the pool until it is at capacity, and then sends new connections to the next available server.

Can a service have its own IP address in Kubernetes?

Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balance across them.

What is external load balancer in Kubernetes?

External Load Balancers - these are used to direct external HTTP requests into a cluster. An external load balancer in Kubernetes gives the cluster an IP address which will route internet traffic to specific nodes identified by ports.


2 Answers

Just to add to the answers here, the best option right now is to use a bash script. For convenience, I've put it into a single line that includes exporting an environmental variable.

Command to wait and find Kubernetes service endpoint

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'

I've also modified your script so it only executes a wait if the ip isn't available. The last bit will export an environment variable called "endpoint"

Bash Script to Check a Given Service

Save this as check-endpoint.sh and then you can execute $sh check-endpoint.sh SERVICE_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

Using this in a Codefresh Step

I'm using this for a Codefresh pipeline and it passes a variable $endpoint when it's done.

  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'
like image 84
Dan Garfield Avatar answered Nov 06 '22 20:11

Dan Garfield


This is little bit tricky by working solution:

kubectl get service -w load-balancer -o 'go-template={{with .status.loadBalancer.ingress}}{{range .}}{{.ip}}{{"\n"}}{{end}}{{.err}}{{end}}' 2>/dev/null | head -n1
like image 28
kvaps Avatar answered Nov 06 '22 20:11

kvaps