kuberneteskubernetes-serviceblue-green-deployment

Kubernetes - Reconfiguring a Service to point to a new Deployment (blue/green)


I'm following along with a video explaining blue/green Deployments in Kubernetes. They have a simple example with a Deployment named blue-nginx and another named green-nginx.

The blue Deployment is exposed via a Service named bgnginx. To transfer traffic from the blue deployment to the green deployment, the Service is deleted and the green deployment is exposed via a Service with the same name. This is done with the following one-liner: kubectl delete svc bgnginx; kubectl expose deploy green-nginx --port=80 --name=bgnginx

Obviously, this works successfully. However, I'm wondering why they don't just use kubectl edit to change the labels in the Service instead of deleting and recreating it. If I edit bgnginx and set .metadata.labels.app & .spec.selector.app to green-nginx it achieves the same thing.

Is there a benefit to deleting and recreating the Service, or am I safe just editing it?


Solution

  • The problem with kubectl edit is that it requires a human to operate a text editor. This is a little inefficient and things do occasionally go wrong.

    I suspect the reason your writeup wants you to kubectl delete the Service first is that the kubectl expose command will fail if it already exists. But as @HarshManvar suggests in their answer, a better approach is to have an actual YAML file checked into source control

    apiVersion: v1
    kind: Service
    metadata:
      name: myapp
      labels:
        app.kubernetes.io/name: myapp
    spec:
      selector:
        app.kubernetes.io/name: myapp
        example.com/deployment: blue
    

    You should be able to kubectl apply -f service.yaml to deploy it into the cluster, or a tool can do that automatically.

    The problem here is that you still have to edit the YAML file (or in principle you can do it with sed) and swapping the deployment would result in an extra commit. You can use a tool like Helm that supports an extra templating layer

    spec:
      selector:
        app.kubernetes.io/name: myapp
        example.com/deployment: {{ .Values.color }}
    

    In Helm I might set this up with three separate Helm releases: the "blue" and "green" copies of your application, plus a separate top-level release that just contained the Service.

    helm install myapp-blue ./myapp
    # do some isolated validation
    helm upgrade myapp-router ./router --set color=blue
    # do some more validation
    helm uninstall myapp-green
    

    You can do similar things with other templating tools like ytt or overlay layers like Kustomize. The Service's selectors: don't have to match its own metadata, and you could create a Service that matched both copies of the application, maybe for a canary pattern rather than a blue/green deployment.