vcluster icon indicating copy to clipboard operation
vcluster copied to clipboard

Load Balancer IP is not synced to host after editing `spec.loadBalancerIP` from vcluster

Open akbarkn opened this issue 3 years ago • 5 comments

What happened?

I'm trying to create and edit a service from the cluster with LoadBalancer type. The host is using Calico and Metallb for the network. Here is the Metallb configmap:

apiVersion: v1
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.56.10-192.168.56.20
kind: ConfigMap
metadata:
  name: config
  namespace: metallb-system

Helm values:

{
  "api": {
    "image": "k8s.gcr.io/kube-apiserver:v1.23.1",
    "replicas": 1,
    "resources": {
      "limits": {
        "cpu": "500m",
        "memory": "512Mi"
      },
      "requests": {
        "cpu": "200m",
        "memory": "128Mi"
      }
    }
  },
  "etcd": {
    "image": "k8s.gcr.io/etcd:3.5.1-0",
    "storage": {
      "size": "5.0Gi"
    },
    "replicas": 1,
    "resources": {
      "limits": {
        "cpu": "500m",
        "memory": "512Mi"
      },
      "requests": {
        "cpu": "100m",
        "memory": "128Mi"
      }
    }
  },
  "sync": {
    "storageclasses": {
      "enabled": true
    },
    "networkpolicies": {
      "enabled": true
    },
    "priorityclasses": {
      "enabled": true
    },
    "serviceaccounts": {
      "enabled": true
    },
    "volumesnapshots": {
      "enabled": true
    },
    "persistentvolumes": {
      "enabled": true
    },
    "poddisruptionbudgets": {
      "enabled": true
    }
  },
  "syncer": {
    "replicas": 1,
    "resources": {
      "limits": {
        "cpu": "500m",
        "memory": "512Mi"
      },
      "requests": {
        "cpu": "100m",
        "memory": "128Mi"
      }
    }
  },
  "service": {
    "type": "ClusterIP"
  },
  "enableHA": false,
  "controller": {
    "image": "k8s.gcr.io/kube-controller-manager:v1.23.1",
    "replicas": 1,
    "resources": {
      "limits": {
        "cpu": "500m",
        "memory": "512Mi"
      },
      "requests": {
        "cpu": "200m",
        "memory": "128Mi"
      }
    }
  },
  "serviceCIDR": "10.1.0.0/16"
}

The service is successfully created and the ip is assigned at the first time. But, if I tried to edit the service and change the IP from vcluster, it's not getting synced with the host.

$ kubectl expose pod/test-pod --type LoadBalancer --port 80 --load-balancer-ip 192.168.56.10
service/test-pod exposed

Here I can see the service is created in the vcluster

$ kubectl --kubeconfig kubeconfig get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
kubernetes   ClusterIP      10.1.169.191   <none>          443/TCP        1h
test-pod     LoadBalancer   10.1.139.169   192.168.56.10   80:31911/TCP   67s

and also host

$ kubectl -n k8s-7157e2ee-afd5-4658-9086-d00bc4f74eee get svc
NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                  AGE
kube-dns-x-kube-system-x-mycluster   ClusterIP      10.1.204.189   <none>          53/UDP,53/TCP,9153/TCP   1h
mycluster                            ClusterIP      10.1.169.191   <none>          443/TCP                  1h
mycluster-api                        ClusterIP      10.1.244.33    <none>          443/TCP                  1h
mycluster-etcd                       ClusterIP      10.1.63.125    <none>          2379/TCP,2380/TCP        1h
mycluster-etcd-headless              ClusterIP      None           <none>          2379/TCP,2380/TCP        1h
mycluster-node-awid3                 ClusterIP      10.1.149.199   <none>          10250/TCP                1h
test-pod-x-default-x-mycluster       LoadBalancer   10.1.139.169   192.168.56.10  80:31911/TCP              2m53s

But, after editing spec.loadBalancerIP (using kubectl edit or kubectl apply or kubectl patch) from the vcluster to 192.168.56.11, The IP is not getting changed both in the cluster and host.

$ kubectl --kubeconfig kubeconfig get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
kubernetes   ClusterIP      10.1.169.191   <none>          443/TCP        1h
test-pod     LoadBalancer   10.1.139.169   192.168.56.10   80:31911/TCP   5m7s

host:

$ kubectl -n k8s-7157e2ee-afd5-4658-9086-d00bc4f74eee get svc
NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                  AGE
kube-dns-x-kube-system-x-mycluster   ClusterIP      10.1.204.189   <none>          53/UDP,53/TCP,9153/TCP   1h
mycluster                            ClusterIP      10.1.169.191   <none>          443/TCP                  1h
mycluster-api                        ClusterIP      10.1.244.33    <none>          443/TCP                  1h
mycluster-etcd                       ClusterIP      10.1.63.125    <none>          2379/TCP,2380/TCP        1h
mycluster-etcd-headless              ClusterIP      None           <none>          2379/TCP,2380/TCP        1h
mycluster-node-awid3                 ClusterIP      10.1.149.199   <none>          10250/TCP                1h
test-pod-x-default-x-mycluster       LoadBalancer   10.1.139.169   192.168.56.10  80:31911/TCP              7m5s

This is what I got from kubectl --kubeconfig kubeconfig get events

...
6m6s        Normal    IPAllocated        service/test-pod   Assigned IP ["192.168.56.10"]
6m6s        Normal    nodeAssigned       service/test-pod   announcing from node "awid"
19s         Normal    LoadbalancerIP     service/test-pod   192.168.56.10 -> 192.168.56.11
19s         Normal    LoadbalancerIP     service/test-pod   192.168.56.11 -> 192.168.56.10

If I change the value from the host, it works as expected:

$ kubectl --kubeconfig kubeconfig get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
kubernetes   ClusterIP      10.1.169.191   <none>          443/TCP        1h
test-pod     LoadBalancer   10.1.139.169   192.168.56.11   80:31911/TCP   9m50s

host:

$ kubectl -n k8s-7157e2ee-afd5-4658-9086-d00bc4f74eee get svc
NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                  AGE
kube-dns-x-kube-system-x-mycluster   ClusterIP      10.1.204.189   <none>          53/UDP,53/TCP,9153/TCP   1h
mycluster                            ClusterIP      10.1.169.191   <none>          443/TCP                  1h
mycluster-api                        ClusterIP      10.1.244.33    <none>          443/TCP                  1h
mycluster-etcd                       ClusterIP      10.1.63.125    <none>          2379/TCP,2380/TCP        1h
mycluster-etcd-headless              ClusterIP      None           <none>          2379/TCP,2380/TCP        1h
mycluster-node-awid3                 ClusterIP      10.1.149.199   <none>          10250/TCP                1h
test-pod-x-default-x-mycluster       LoadBalancer   10.1.139.169   192.168.56.11   80:31911/TCP             11m

What did you expect to happen?

The load balancer IP should be changed as specified if the value is edited from vcluster.

How can we reproduce it (as minimally and precisely as possible)?

  • Create a pod
  • Expose the pod and specify the load balancer IP
  • Edit the load balancer IP from vcluster
  • Observe the service both from vcluster and the host

Anything else we need to know?

The host using Calico and Metallb

Host cluster Kubernetes version

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.3", GitCommit:"816c97ab8cff8a1c72eccca1026f7820e93e0d25", GitTreeState:"clean", BuildDate:"2022-01-25T21:25:17Z", GoVersion:"go1.17.6", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.4+k3s1", GitCommit:"43b1cb48200d8f6af85c16ed944d68fcc96b6506", GitTreeState:"clean", BuildDate:"2022-02-24T22:38:17Z", GoVersion:"go1.17.5", Compiler:"gc", Platform:"linux/amd64"}

Host cluster Kubernetes distribution

kubeadm and k3s

vlcuster version

$ vcluster --version
vcluster version 0.7.1

Vcluster Kubernetes distribution(k3s(default)), k8s, k0s)

k8s

OS and Arch

OS: Linux Ubuntu 20.04.2 LTS
Arch: x86

akbarkn avatar Apr 15 '22 18:04 akbarkn

@akbarkn thanks for creating this issue! vcluster currently only handles the case that the host cluster is setting the load balancer ip, so setting it inside the vcluster only works on creation as values are copied to the host cluster for creation. But we might also want to allow setting it from inside the vcluster.

FabianKramm avatar Apr 19 '22 09:04 FabianKramm

@FabianKramm Thanks for the answer. Nice to hear that you will handle the case in the future.

akbarkn avatar Apr 20 '22 14:04 akbarkn

@FabianKramm I am able to replicate the same, can you please assign this bug to work on!

sandeep540 avatar Sep 01 '22 19:09 sandeep540

@sandeep540 Are you still working on this issue? If you got blocked and need help, please don't hesitate to reach out to us in vcluster channel in our Slack.

matskiv avatar Oct 13 '22 10:10 matskiv

Hi @matskiv , No I am currently not working on this! you can reassign it to someone

sandeep540 avatar Oct 13 '22 10:10 sandeep540