Hunter Carnes
Hunter Carnes

Reputation: 1

How to deploy kubernetes helm environments that cross-reference services via blue/green approach?

I've got multiple applications deployed in a kubernetes cluster, across namespaces, and some apps reference another app's service to communicate with it. All apps are deployed with helm, and I'm wanting to use a blue/green approach to deployments...

I've seen several solutions where you pull the service outside of the helm chart (as in, in their own separate file) and have 2 services - one live and one staging. Then your ingress url's for live and staging point to its corresponding service. Then to swap traffic back and forth between deployment pods created from a blue helmrelease and green helmrelease, you'd simply update the selector label tags on the service. However, this doesn't work if one application references a service for another application. I have a near-hard-requirement that the service has to remain within the helm chart/helmrelease because of this. Also, not every application gets deployed at the same time. i.e. appA could get released and blue is live, but appB that references appA's service could not have a release.

I need to be able to stand up the staging environment for appA and QA test against it and potentially against appB as well, before cutting over traffic. I can't just leave appB always referencing, say, the blue service because we don't always know that blue is live or blue is staging. Do I just need to make it a requirement that both, appA and appB get "released" every cycle, even if we just stand up the same app image as what's already in the live environment, if there's no new build to deploy? Then every app would always have blue is live, green is staging, and vice versa? I'd imagine this would complicate rollbacks if one app needs to rollback but another doesn't.

I've already got a POC working where I pulled the service out of the helm chart, then deployed the chart as a blue helmrelease and a green helmrelease, separately. I can swap traffic almost instantaneously by updating the services' selector labels. It's the cross-app service name references that complicate things.

Upvotes: 0

Views: 180

Answers (1)

David Maze
David Maze

Reputation: 159761

Let's say you've deployed two copies of your application in the same namespace.

helm install -n app-a app-a-blue ./app-a --set color=blue
helm install -n app-a app-a-green ./app-a --set color=green

Each Helm release owns a set of resources. You need a single Service that points at the live copy of the application, and you need it to always exist. That means it can't be attached to either copy of the application; it needs to be separate.

I'd create a separate chart just containing the Service

apiVersion: v1
kind: Service
metadata:
  name: {{ include "app-service.fullname" . }}
  labels:
    {{- include "app-service.labels" . | nindent 4 }}
spec:
  ports:
    - name: http
      port: 80
      targetPort: http
  selector:
    {{- include "app-service.selectorLabels" . | nindent 4 }}
    color: {{ .Values.color }}  # <-------

The three included templates come the _helpers.tpl that helm create gives you; aside from the color: at the end this is almost the same as the generated templates/service.yml. You will need to edit the selectorLabels helper to match what your application is deploying. You can delete almost all of the rest of the chart.

Now to switch from blue to green, you just need to redeploy this Service-only chart, specifying its color.

helm upgrade --install -n app-a app-a-live ./app-a-service --set color=green

Upvotes: 0

Related Questions