Continuous Deployment of Docker Apps to Kubernetes

Written by: Zachary Flower

In the first post of this series, we introduced using Kubernetes for deployments. In this post, we'll get started with integrating Codeship into the workflow.

Given a functioning Kubernetes Deployment (remember our discussion from the last post about the difference between deployment and Kubernetes' Deployment), how do we integrate it into our Codeship workflow? The answer to this question ultimately depends on your Kubernetes host, but because the official documentation uses Google Cloud as an example, this is the platform I'll address.

Integrating Codeship with Kubernetes

Codeship has already built out some Google Cloud integrations into their CI Platform for Docker that we can use to authenticate and deploy new images to Google Cloud.

Before we can do anything, however, we need to create an encrypted environment file using Codeship's CLI tool in order to authenticate to Google Cloud. Codeship already has a tutorial of how to do this, so I won't go over it here. But the environment variables that need to be set are:

  • a Google Cloud Key - GOOGLE_AUTH_JSON

  • a Google Authentication Email - GOOGLE_AUTH_EMAIL

  • and a Google Project ID - GOOGLE_PROJECT_ID

Once we have an encrypted environment file (and have saved our Google Cloud environment variables to gc.env.encrypted), we next need to define the Google Cloud service in the codeship-services.yml file.

Notice that there are two services defined, rather than one. This is because one is for interacting with Google Cloud services (google_cloud_deployment), while another is used to enable Docker image push functionality to the Google Cloud Registry (gcr_dockercfg). We've built a turnkey version of this for you here.

This is only half of the puzzle, however. Although it creates the necessary services for interacting with Google Cloud, it doesn't automatically deploy newly built images or update a Kubernetes Deployment.

Google Container Registry Pushing

Thanks to Codeship's built-in push steps, deploying a Docker image to a remote registry is a pretty painless process. Using the gcr_dockercfg service defined above, all we need to do is add a step to the codeshipsteps.yml file with our Google Container Registry URL as the destination.

It's important to remember here that we will be deploying our application image, so be sure to replace the app service name with the name of the service your own application is running on.

The parameters above should be pretty self-explanatory, but the basic idea is that the app image gets pushed up to the Google Container Registry using the previously defined gcr_dockercfg service for authentication.

While this step does push updated images to the registry, there is a problem with it as currently defined. Without a set Docker image tag, Codeship will push updated images to the latest tag. Now, this isn't a bad thing in and of itself (in fact, it's expected), but in order to trigger automatic Kubernetes Deployment updates, we need to be able to set a distinct tag for each push.

To accomplish this, Codeship provides an image_tag declaration that allows us to set any tag other than latest to push our image up to. Codeship has a nice list of variables that can be used for this declaration; however, to keep things simple, let's use the current build's Unix timestamp because it's relatively unique and repeatable.

With the new image_tag declaration, the previous step should now look like this:

Now, when we push up our app image to the Google Container Registry, it will be tagged with the current build's Unix timestamp.

Check in next week when we finish out this series with a tutorial for how to update Kubernetes Deployments.

Interested in learning how you can deploy your apps with Kubernetes and Codeship Pro? Learn more here.

This has been Part Two of a series about Kubernetes, Docker and Codeship. Can't wait for Part Three? Download our free ebook, Continuous Deployment for Docker Apps to Kubernetes.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.