Kubernetes kubectl update service selector

2/17/2019

My Kubernetes cluster is running under Google Cloud. I have deployment which running with port 443 and LoadBalancer expose it to the internet.

I created it in this way:

kubectl expose deployment my-app --target-port=443 --port=443 --type=LoadBalancer

After running this command, the loadbalancer is pointing to my-app deployment. Now I created my-app2 and I want to change the loadbalancer to point the new deployment (my-app2).

Note: Delete and re-create the deployment is releasing the external IP address and I want to avoid it.

How to patch the existing service to point another deployment without loosing the external IP?

-- No1Lives4Ever
google-cloud-platform
google-kubernetes-engine
kubernetes

3 Answers

2/18/2019

Finally, found the solution:

kubectl patch service old-app -p '{"spec":{"selector":{"app": "new-app"}}}'
-- No1Lives4Ever
Source: StackOverflow

2/17/2019

This is covered in the tutorial for GKE here.

Firstly, you should reserve a static IP address, so that it is re-used between deployments.

You can do this in the GCP console or via the command, like so: gcloud compute addresses create helloweb-ip --region us-central1

Then you can find the static IP address you have been allocated: gcloud compute addresses describe helloweb-ip --region us-central1

Then you should use this IP address when setting up your LoadBalancer service. In "imperative" commands, you would type:

kubectl expose deployment my-app --target-port=443 --port=443 --type=LoadBalancer --loadBalancerIP=YOUR.IP.ADDRESS.HERE

The YAML "declarative" form is convenient as the setup gets more complex, this can also saved for re-use in future. For example:

apiVersion: v1
kind: Service
metadata:
  name: helloweb
  labels:
    app: hello
spec:
  selector:
    app: hello
    tier: web
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer
  loadBalancerIP: "YOUR.IP.ADDRESS.HERE"
-- Paul Annetts
Source: StackOverflow

2/17/2019

Yes, you can use already existing service to point new deployment.

All you've to do, edit the service YAML with newly deployed service's label.

Example

Suppose, you've newly deployed services yaml as below.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: my-app-2
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

It has label as

template:
    metadata:
      labels:
        app: my-app-2

If your service is as below:

kind: Service
apiVersion: v1
metadata:
  name: my-app
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

you only need to change selector section of service

selector:
    app: my-app

to

selector:
    app: my-app-2
-- Abu Hanifa
Source: StackOverflow