I am working on some code that requires me to create a Kubernetes service with an external load balancer using the client-go api. The service itself is created right away, but it takes several seconds for the load balancer to be assigned an IP address. Once the IP address is assigned it will be written into the Status.LoadBalancer.Ingress
array of the service struct.
Currently, my code looks like this (minus some details for brevity):
func createService(id string) error {
servicesClient := c.clientset.CoreV1().Services(apiv1.NamespaceDefault)
service := &apiv1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: serviceNamePrefix + id,
},
Spec: apiv1.ServiceSpec{
Type: apiv1.ServiceTypeLoadBalancer,
Selector: map[string]string{"app": id},
},
}
service, err = servicesClient.Create(service)
if err != nil {
return err
}
go func() {
for len(service.Status.LoadBalancer.Ingress) == 0 {
time.Sleep(1 * time.Second)
}
db.UpdateServiceURL(id, service.Status.LoadBalancer.Ingress[0])
}
return nil
}
Ideally, I would use condition variable like in this question. However, I don't think that would be possible in this situation as I am not writing the code where the value is set. Is there some better way I can wait for the Ingress array to be populated without having to continually loop? Or has someone else had this problem and found a nicer solution?