Migrating an IP-based service in GKE

2 min read

Let’s say you want to migrate a service in GKE from one cluster to another (including between Standard and Autopilot clusters), and keep the same external IP while you do. DNS might be the ideal way to update your service address, for whatever reason you need to keep the IP the same. Fortunately, it is possible to preserve the IP and assign it to a new service in a different cluster in Kubernetes.

Migrating an Ingress IP

Ingress (L7 load balancer) IPs in GKE are global. The first step to migrating an IP between clusters is to promote the ephemeral IP attached to an existing Ingress into a global static IP in the following way:

EPHEMERAL_IP_ADDRESS=203.0.113.1
gcloud compute addresses create ingress-ip \
    --addresses=$EPHEMERAL_IP_ADDRESS --global

Make sure it is now shown in this list as “Static”. Double check this, because if you perform the next step without that IP being static, you won’t be able to get it back.

Once the IP is converted, you can delete the ingress resource in the old GKE cluster (kubectl delete ing INGRESS_NAME), and create a new one in the new cluster. The deletion is needed before you can re-assign the IP to a new resource.

When creating the new Ingress, you can assign the static IP that you created above from the old Ingress to the new one by referring to its resource name like so:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: basic-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "ingress-ip"
spec:
  defaultBackend:
    service:
      name: web
      port:
        number: 8080

Migrating a Load Balancer IP

For Services of type LoadBalancer (L4 load balancers), the steps are similar, but you instead convert the ephemeral IP attached to the load balancer into a regional static IP, of the same region of your cluster.

EPHEMERAL_IP_ADDRESS=203.0.113.2
REGION=us-west1
gcloud compute addresses create lb-ip \
    --addresses=$EPHEMERAL_IP_ADDRESS \
    --region=$REGION

As with Ingress, make sure the IP is now shown in this list as “Static”. Double check this, because if you perform the next step without that IP being static, you won’t be able to get it back.

Once the IP is static, you can delete the service resource in the old GKE cluster (kubectl delete svc SERVICE_NAME), and create a new one in the new cluster. The deletion is needed before you can re-assign the IP to a new resource.

When creating the new Service of type LoadBalancer you specify the IP itself (referring to the IP address, not the resource name) in the loadBalancerIP field:

apiVersion: v1
kind: Service
metadata:
  name: timeserver
spec:
  selector:
    pod: timeserver-pod
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  type: LoadBalancer
  loadBalancerIP: 203.0.113.2</strong>