Closed timoreimann closed 4 years ago
+1
I started working on that in https://github.com/digitalocean/digitalocean-cloud-controller-manager/pull/307
/cc @timoreimann
Hey @grzesiek , thanks for your PR! 🎉
Just wanted to let you know that I'm busy today but will try to find some time tomorrow to look into the change. Will get back to you as soon as I can.
Thanks for letting me know @timoreimann and no worries, this is not urgent :)
Okay, so we had a discussion in the pull request :arrow_right: https://github.com/digitalocean/digitalocean-cloud-controller-manager/pull/307 and more annotations seems to be not an option. For more details see https://github.com/digitalocean/digitalocean-cloud-controller-manager/pull/307#pullrequestreview-361093236.
I would like to keep the ball rolling, so I have a different proposal here. But before I delve into the proposal I would like to explicitly name problems I would like to solve here:
When a user creates a LoadBalancer resource, digitalocean-cloud-controller-manager mutates it by adding an annotation like load-balancer-id
.
This is not perfect, because if you are using a tool that has configuration drift detection built in, like Terraform Kubernetes provider, there is always some amount of noise involved and sometimes this also might lead to problems with reconciliation when Terraform tries to remove annotations it does not recognize on every run. kubectl diff
may detect this.
Creating a LoadBalancer
k8s resource will result in a DigitalOcean Load Balancer being provisioned, but it is difficult to use DO's API to get details of this resource, because a name of the load balancer being provisioned is random and the load balancer ID is assigned when the LoadBalancer service gets created.
Using Terraform data "digitalocean_loadbalancer"
can't be done without knowing the load balancer name.
load-balancer-id
with load-balancer-name
annotation, but keep the former for the backwards compatibilityload-balancer-id
annotation.What do you think about that @timoreimann?
hey @grzesiek. First of all, thanks for your follow up proposal.
We used to rely on LB names exclusively to link LB resources to Services. This posed two issues:
So a good question would be what a better place for the LB ID could be. We have been thinking about moving CCM to a CRD-based architecture so that tracking metadata such as the LB ID would not have to be maintained on the Service object. This could possibly address the concerns you mentioned, but the idea needs to be fleshed out more. And just to complete the picture, there's an ongoing upstream effort to change the way LBs are managed in Kubernetes.
I'm not super happy with the configuration drift we added by introducing the LB ID annotation, so I'd be happy to follow up on any of my thoughts above or new ones to address that matter. To me though, that's somewhat distinct from making LB names configurable: while they could serve to also eliminate configuration drift (though my concerns raised above pose a set of challenges), I'm inclined to treat that as a separate issue if we cannot leverage the LB name for that. The name still serves a more dedicated purpose, which is to make it easier for customers to find their LBs based on a human-readable name.
Happy to hear your thoughts.
@timoreimann Thanks for the reply!
We used to rely on LB names exclusively to link LB resources to Services
I've never said that we should use load balancer name to track a service / LB resource relationship. I merely think that mutating the service to do this might not be the best solution. I agree that using a LB ID is presumably still the best solution for now.
So a good question would be what a better place for the LB ID could be. We have been thinking about moving CCM to a CRD-based architecture so that tracking metadata such as the LB ID would not have to be maintained on the Service object.
This sounds interesting indeed! Please let me know when you know more about that, I would be happy to help here!
For the time being though, I wonder how can we proceed here. What would be the most reasonable iteration?
Do you think the way forward is introducing load-balancer-name
annotation and working on surfacing possible errors to users?
@grzesiek
Do you think the way forward is introducing
load-balancer-name
annotation and working on surfacing possible errors to users?
Yep, I think that's what we should do. There isn't much needed to do with regards to surfacing the errors because the DO LB API will already reject create/update requests if a different LB in the account has the same name already. Feel free to update your existing PR accordingly.
And re: "finding a better place for the LB ID": I'll do some upstream digging to see where SIG Networking stands today with regards to the Ingress v2 effort as this would determine if moving to CRDs still made sense.
Thanks for a really productive discussion @timoreimann :pray: ! I will try to allocate some time this week to update my PR and test it :+1:
Using Terraform
data "digitalocean_loadbalancer"
can't be done without knowing the load balancer name.
Since having to use the service.beta.kubernetes.io/do-loadbalancer-hostname
annotation to work around the bug in kube-proxy, the external IP of the load balancer is no longer provided to Kubernetes (kubernetes.digitalocean.com/load-balancer-ext-ip
perhaps??). This means that Terraform isn't able to use that IP to create the DNS record for the domain. I thought a possible workaround for that would be to use data "digitalocean_loadbalancer"
but indeed as mentioned here, there's no way to look up the DO LB since we don't have any programmatic access to its name from the data within Kubernetes. We're a little stuck at this point.
For me and other users coming across this issue, is there a current way of looking up the LB in Terraform using the information from the Kubernetes Service, since we can't set the LB name directly?
@flyte using kubernetes_service.my_load_balancer.load_balancer_ingress[0].ip
worked for me when I tried it the last time :thinking:
Sadly that's necessarily no longer populated when using the service.beta.kubernetes.io/do-loadbalancer-hostname
annotation.
@flyte the scheme to create an LB name today is very simple: it consists of the letter a
concatenated with the Service UID. The latter is a field on the Service object.
Strictly speaking, the naming scheme is an implementation detail of Kubernetes. I don't think it would be changed easily though, at least not without a proper deprecation process.
Load balancer names are based on Service object UIDs which consist of hard-to-read alphanumeric characters.
Some time ago, upstream provided the ability to specify custom names. We should take advantage of this and enable users to set their own names (through, say, an annotation).
One caveat to watch out for is that load balancer names must be unique. Consequently, we either need to surface any errors returning from the DO LoadBalancer API or ensure uniqueness on our end. The latter could be enforced by appending some kind of random hash (or one based off of the Service object UID).
The final piece to take into consideration are possible name length constraints, especially when thinking about adding a hash suffix.