X
    Categories: Continuous integration

Continuous delivery to Kubernetes with Travis CI

Continuous delivery from Travis-ci to Kubernetes

Continuous delivery is a hot buzz-word in todays software world. Finding the right CI tool to fit your needs is not always easy. Travis CI might not provide you with a fancy UI or be as powerful as Jenkins, but it’s one of the simpler pipelines to setup, supports a lot of different languages and supports deployment to a variety of different services.

In this post I will show you how you can make Travis CI update your deployments in your Kubernetes cluster.

Travis does not come with “out-the-box” support to Kubernetes. But we can very easily add the tools we need to speak with our Kubernetes Cluster.

We need two things for that to work.

I will be using bash script files to do the appropriate commands but if you prefer, you can just add the commands directly to your .travis.yml file instead.

Installing the Kubernetes CLI

I usually have scripts for each of my steps on Travis. So first let’s create an install.sh script and add the commands to install the Kubernetes CLI.

#!/bin/sh

curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl


So with these three lines we have downloaded and installed the Kubernetes CLI and made kubectl accessible from the command line.

The next step will be to setup our config file for the Kubernetes CLI.

Accessing our cluster

There are multiple ways you could setup the access to your cluster. I’ll explain how I did it. Please let me know in the comments how you decided to do this.

The way I am doing it, is by having an incomplete config file in a private repository on Github. It is incomplete so that if it gets compromised, it wont provide access without the missing pieces.

So what we wanna do first is download the file. I do this by getting an access token and then download the raw file.

Now in the install.sh file I add the following line.

curl -o config https://$GITHUB_ACCESS_TOKEN@raw.githubusercontent.com/GithubOrganization/MySecretInfrastructureRepo/master/.kube/config

Notice the $GITHUB_ACCESS_TOKEN. We need to add this particular environment variable through the Travis repository settings. You can generate the access token under your GitHub account settings. (Click on your profile -> Settings -> Personal Access Token -> Generate new token).

Now the file needs to be copied to the correct position so let’s quickly add these two lines to the install.sh script:

mkdir ${HOME}/.kube
cp config ${HOME}/.kube/config

Now that we have the config file in the correct position, we need to learn what I meant by an “incomplete” file.

An example of how this incomplete config file could look like is shown below.

---
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: 
    server: https://kubernetes-group-xxxxx.westus.cloudapp.azure.com
  name: "kubernetes-group-xxxxx"
contexts:
- context:
    cluster: "kubernetes-group-xxxxx"
    user: "kubernetes-group-xxxxx-admin"
  name: "kubernetes-group-xxxxx"
current-context: "kubernetes-group-xxxxx"
kind: Config
users:
- name: "kubernetes-group-xxxxx-admin"
  user:
    client-certificate-data: 
    client-key-data:

So in the above config file there are three missing parameters.

  • certificate-authority-data
  • client-certificate-data
  • client-key-data

So we wanna set these three missing parameters through environment variables like so.

kubectl config set clusters.kubernetes-group-xxxxx.certificate-authority-data "$KUBE_CLUSTER_CERTIFICATE"
kubectl config set users.kubernetes-group-xxxxx-admin.client-certificate-data "$KUBE_CLIENT_CERTIFICATE"
kubectl config set users.kubernetes-group-xxxxx-admin.client-key-data "$KUBE_CLIENT_KEY"

So again in the Travis repository settings we wanna add another 3 environment variables that each contain their part of the missing config file.

So add KUBE_CLUSTER_CERTIFICATE, KUBE_CLIENT_CERTIFICATE and KUBE_CLIENT_KEY to the environment variables and paste in their values from your kube config file.

All of these steps will leave us with an install.sh script looking something like this.

# install.sh
#!/bin/sh

# Install kubernetes and set config
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
curl -o config https://$GITHUB_ACCESS_TOKEN@raw.githubusercontent.com/GithubOrganization/MySecretInfrastructureRepo/master/.kube/config

mkdir ${HOME}/.kube
cp config ${HOME}/.kube/config

# Fill out missing params in kubectl config file
kubectl config set clusters.kubernetes-kube-group-e1ea0b.certificate-authority-data "$KUBE_CLUSTER_CERTIFICATE"
kubectl config set users.kubernetes-kube-group-e1ea0b-admin.client-certificate-data "$KUBE_CLIENT_CERTIFICATE"
kubectl config set users.kubernetes-kube-group-e1ea0b-admin.client-key-data "$KUBE_CLIENT_KEY"

Now that access to Kubernetes is setup, you can go about doing all the other tasks you wanna do on Travis like testing, building, creating your new docker image and publishing it too your container registry.

When all that is set and done, you can easily deploy the new image like this.

kubectl set image deployment/<deplyoment name> <deplyoment name>=<your docker registry>/<image name>:<version>

Or as a rolling update like this.

kubectl rolling-update <image name> --image=<your docker registry>/<image name>:<version>

Roundup

So setting up access to Kubernetes from Travis is pretty simple. With some proper testing and staging you have a pretty easy to setup continuous delivery pipeline to your Kubernetes cluster.

Please let me know if this helped you by posting a comment below or reach out on @Karnich.

Jesper O. Christensen: Passionate Software Engineer and part-time DevOps guy. Enjoys long coding sessions by the beach
Disqus Comments Loading...