hetznercloud / hcloud-cloud-controller-manager

Kubernetes cloud-controller-manager for Hetzner Cloud
Apache License 2.0
732 stars 118 forks source link

How does the loadbalancer integration works? #157

Closed beatkind closed 3 years ago

beatkind commented 3 years ago

I'm not quite sure if this is the correct place for such a question, but I couldn't think of a better one. I also don't know if I'm just completely too stupid.

About my setup:

I have two nodes and a load balancer deployed via Terraform.

Loba:

resource "hcloud_load_balancer" "name" {
  name       = "name.example"
  load_balancer_type = "lb11"
  location   = "nbg1"
  target {
    type = "server"
    server_id = hcloud_server.node01.id
  }
  target {
    type = "server"
    server_id = hcloud_server.node02.id
  }
}

Nodes:

resource "hcloud_server" "node01" {
  name = "node01"
  image = "ubuntu-20.04"
  server_type = "cx21"
  location = "nbg1"
  backups = false
  keep_disk = false

  user_data = file("cloud-init.yaml")

  network {
      network_id = hcloud_network.name.id
      ip         = "10.1.1.11"
  }

  ssh_keys = [...]

  labels = {
        [...]
  }

  depends_on = [ 
      [...]
   ]
}

resource "hcloud_server" "node02" {
  name = "node02"
  image = "ubuntu-20.04"
  server_type = "cx21"
  location = "nbg1"
  backups = false
  keep_disk = false

  user_data = file("cloud-init.yaml")

  network {
      network_id = hcloud_network.name.id
      ip         = "10.1.1.12"
  }

  ssh_keys = [...]
  labels = {
       [...]
  }

  depends_on = [ 
      [...]
   ]
}

So far so good. I set up the cluster using kubeadm and of course set the parameter "KUBELET_EXTRA_ARGS=--cloud-provider=external" before.

I have both the CSI and CNI addon installed in the cluster. If I now deploy a NGINX ingress controller using helm and add the following annotations to the server:

load-balancer.hetzner.cloud/health-check-port: "10254"
load-balancer.hetzner.cloud/name: "loba.k8s.devcdn.net"

I see the following event in the corresponding namespace: 3m8s Normal EnsuringLoadBalancer service/nginx-ingress-ingress-nginx-controller Ensuring load balancer however, no services are added in the Loba.

Does the load balancer need to be specially created by the cluster or specially imported? Or did I make something completely wrong here?

LKaemmerling commented 3 years ago

Hey,

when you use the Cloud Controller Manager, the CCM is responsible for creating a Load Balancer. You can use the name annotation (as you did) to reference the Load Balancer you created via Terraform. On the first look I would assume that there are a few annotations missing. Can you check the logs from the Cloud Controller Manager?

beatkind commented 3 years ago

Hi @LKaemmerling , thanks for taking time to have a look in my question. That was a misunderstanding on my side, thanks for making clear that the Loadbalancer is created via the cluster. I added the missing annotations and deleted the self created loadbalancer, that worked so far. I am now getting the error in the CCM logs:

E0222 06:30:13.773442       1 node_controller.go:237] hcloud/instances.InstanceID: instance not found
E0222 06:30:13.873447       1 node_controller.go:245] Error getting node addresses for node "node02": error fetching node by provider ID: hcloud/instances.NodeAddressesByProviderID: hcloud/providerIDToServerID: missing prefix hcloud://: , and error by node name: hcloud/instances.NodeAddresses: instance not found
I0222 06:32:01.688386       1 load_balancers.go:81] "ensure Load Balancer" op="hcloud/loadBalancers.EnsureLoadBalancer" service="nginx-ingress-ingress-nginx-controller" nodes=[node02]
I0222 06:32:01.688672       1 event.go:278] Event(v1.ObjectReference{Kind:"Service", Namespace:"ingress", Name:"nginx-ingress-ingress-nginx-controller", UID:"510bdb76-d04f-48d2-a51d-440d22a8ca08", APIVersion:"v1", ResourceVersion:"74205", FieldPath:""}): type: 'Normal' reason: 'EnsuringLoadBalancer' Ensuring load balancer
E0222 06:32:04.069788       1 controller.go:244] error processing service ingress/nginx-ingress-ingress-nginx-controller (will retry): failed to ensure load balancer: hcloud/loadBalancers.EnsureLoadBalancer: hcops/LoadBalancerOps.ReconcileHCLBTargets: hcops/providerIDToServerID: missing prefix hcloud://:
I0222 06:32:04.070430       1 event.go:278] Event(v1.ObjectReference{Kind:"Service", Namespace:"ingress", Name:"nginx-ingress-ingress-nginx-controller", UID:"510bdb76-d04f-48d2-a51d-440d22a8ca08", APIVersion:"v1", ResourceVersion:"74205", FieldPath:""}): type: 'Warning' reason: 'SyncLoadBalancerFailed' Error syncing load balancer: failed to ensure load balancer: hcloud/loadBalancers.EnsureLoadBalancer: hcops/LoadBalancerOps.ReconcileHCLBTargets: hcops/providerIDToServerID: missing prefix hcloud://:

That seems to be the error you mentioned in #80, but as I said the cluster is created with that option. The csi addon was able to set the node id.

When I search truth the logs to the point where the CCM was started and node2 was added I see the following:

failed to initialize node node02 at cloudprovider: failed to get instance ID from cloud provider: hcloud/instances.InstanceID: instance not found

(and both nodes have the taint node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule )

LKaemmerling commented 3 years ago

This looks like the name in the cloud console and the name of the node in the k8s cluster are not identically.

beatkind commented 3 years ago

Thanks for that. The nodes were named after their fqnd, changing that resolved the error! Thank you for taking time for that, appreciate it.