Fully automated blue/green deployments in Kubernetes with Codefresh

Out of the box, Kubernetes supports some interesting deployment strategies. From those, the most useful for production deployments is the rolling update. This deployment strategy allows for zero-downtime application upgrades and also offers a gradual rollout of the new application to each pod instance.

Even though rolling updates sound great in theory, in practice, there are several drawbacks. The major one is the lack of easy rollbacks. Attempting to go to the previous version after a deployment has finished is not a straightforward process. A minor disadvantage is also the fact that not all applications are capable of having multiple versions active at the same time.

An alternative way of deployment comes in the form or blue/green (a.ka. red/black) deployments. With this strategy, a full set of both old and new instances exist at the same time. Active traffic is decided via the loadbalancer that selects one of the two sets. This means that doing a rollback is as simple as switching back the load balancer.

Blue green deploymentsBlue green deployments

Unfortunately, Kubernetes does not support blue/green deployments out of the box. It is the responsibility of an external tool or automation solution to implement such deployment. Hopefully, doing blue/green deployments is not that hard. Kubernetes already comes with the basic building blocks (deployments and services) that make a blue/green deployment very easy using plain kubectl commands. The challenge for a sound CI/CD solution is how to automate those kubectl commands so that blue/green deployments happen in a well controlled and repeatable manner.

We have already covered blue/green deployments in a previous Codefresh blog post. There, we explained a way to script a Codefresh pipeline to perform blue/green deployments. This approach works well for people that already know how kubectl works, but is not the most user-friendly way for designing a pipeline.

Blue/Green deployments with a declarative syntax

In this post, we will take blue/green deployments one step further by packaging the kubectl invocations into a pre-packaged Docker image offering a declarative way to do blue/green deployments.

The final result is that in order to deploy using blue/green you can just insert the following build step in your codefresh.yml:

blueGreenDeploy:

title: “Deploying new version ${}”

image: codefresh/k8s-blue-green:master

environment:

– SERVICE_NAME=my-service

– DEPLOYMENT_NAME=my-app

– NEW_VERSION=${}

– HEALTH_SECONDS=30

– NAMESPACE=colors

– KUBE_CONTEXT=myDemoAKSCluster

Here blue/green deployments happen in a completely declarative manner. All kubectl commands are abstracted.

The Blue/Green deploy step is essentially a docker image with a single executable that takes the following parameters as environment variables:

Environment Variable Description
KUBE_CONTEXT Name of your cluster in Codefresh dashboard
SERVICE_NAME Existing K8s service
DEPLOYMENT_NAME Existing k8s deployment
NEW_VERSION Docker tag for the next version of the app
HEALTH_SECONDS How many seconds both colors should coexist. After that new version pods will be checked for restarts
NAMESPACE K8s Namespace where deployments happen

Prerequisites

The blue/green deployments steps expect the following assumptions:

  • An initial service and the respective deployment should already exist in your cluster.
  • The service and the deployment need to use labels that define their version.

The second assumption is very important, as this is how the blue/green step detects the current version and can switch the load balancer to the next version.

You can use anything you want as a “version”, but the recommended approach is to use GIT hashes and tag your Docker images with them. In Codefresh this is very easy because the built-in variable CF_SHORT_REVISION gives you the git hash of the commit that was pushed.

The build step of the main application that creates the Docker image that will be used in the blue/green step is a standard build step that tags the Docker image with the git hash

BuildingDockerImage:

title: Building Docker Image

type: build

image_name: trivial-web

working_directory: ./example/

tag: ‘${}’

dockerfile: Dockerfile

For more details, you can look at the example application
that also contains a service and deployment with the correct labels as well as the full codefresh.yml file.

How to perform Blue/Green deployments

When you run a deployment in Codefresh the pipeline step will print information message on its actions.

Blue/Green deployment logsBlue/Green deployment logs

The blue/green step copies your existing deployment and changes its version, creating a second one with the updated Docker image. At this point, BOTH version (old and new) of your application are deployed in the Kubernetes cluster. All live traffic is still routed to the old application.

There is a waiting period (configurable as an environment parameter as we have seen in the previous section). During this period you are free to do any external checks on your own (e.g. check your health dashboard or run some kind of smoke testing). Once that period is finished, the script checks for the number of restarts in the pods of the new application. If there are any errors, it destroys the new deployment and your cluster is back to the initial state (your users are not affected in any way).

If there are are no pod restarts, the service is switched to point to the new deployment and the old deployment is discarded.

You can also see the changes in the Codefresh Kubernetes dashboard. I am using an Azure Kubernetes cluster, but any cluster will work as long as the labels are present in the manifest files.

Kubernetes DashboardKubernetes Dashboard

And there you have it! Now you can deploy your own application using the blue/green strategy. The blue/green Docker image is also
available in Dockerhub.

New to Codefresh? Create Your Free Account Today!

Source

Leave a Reply

Your email address will not be published. Required fields are marked *