How to Deploy to Kubernetes Using Gitlab CI
Published: 2022-05-17 15:38:36

---
title: How to Deploy to Kubernetes Using Gitlab CI
published: true
date: 2022-05-11 11:21:15 UTC
tags: 
canonical_url: https://malgasm.com/blog/166/how-to-deploy-to-kubernetes-using-gitlab-ci
---

Automatically deploy new revisions of your app to your Kubernetes cluster with the push of a button!

If you are not familiar with Kubernetes, I hope that this article can give you a deeper understanding of the power of Kubernetes. Regardless of your skill level, I hope that reading this article inspires you iterate on your infrastructure process.

This article assumes that you already have a Kubernetes cluster with a working Kubeconfig for a user that has permissions to access the cluster. It also assumes that Gitlab’s servers can access your cluster. We will cover these topics, including how to implement Kubernetes Role-Based Access Control in a future article. Let’s get started:

## **Prepare and download your Kubeconfig**

The [Kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) is a file that grants access to your Kubernetes cluster. The user that the Kubeconfig describes should have permission to **`update`** the `deployments` in your cluster.

## **Upload your Kubeconfig to Gitlab**

The first step is to provide Gitlab with your Kubeconfig.

Navigate to your project or group **CI/CD** Settings:

![Gitlab CI settings](https://malgasm.com/images/articles/kubeconfig-gitlab/gitlab-settings.png)
_Variables can be configured both at the Group and Project levels_

Click **Expand** on the **Variables** section:

![Gitlab CI variables dialog](https://malgasm.com/images/articles/kubeconfig-gitlab/variables.png)

and then, click the **Add Variable** button to reveal the following dialog:

![Gitlab CI add variables dialog](https://malgasm.com/images/articles/kubeconfig-gitlab/add-variable-dialog.png)
_The key MUST be KUBECONFIG_

Make sure that the **Type** of the variable is set to **File**.

Then, copy the contents of your Kubeconfig into the **Value** input box and finally, click the **Add Variable** button.

## **Create the Deploy Step**

Once you’ve added your Kubeconfig as a CI pipeline variable, you’re ready to update your **.gitlab-ci.yml** with a new `deploy` stage. Below is an example:

```
deploy:
  stage: deploy
  image:
    name: bitnami/kubectl:latest
    entrypoint: [""]
  when: manual
  script:
    - kubectl set image deployment/my-deployment my-deployment=my.registry.com/my-image/$CI_COMMIT_REF_SLUG
```

Let’s explore a few parts of this pipeline step:

## **image**

This definition uses **bitnami’s**  **kubectl** docker image. I do not want to maintain my own kubectl docker image, and bitnami’s kubectl image is the most reputable one I’ve found in my research. The info page on bitnami’s image is here: [https://bitnami.com/stack/kubectl/containers](https://bitnami.com/stack/kubectl/containers)

By default, the image will run `kubectl`, which will create unnecessary noise in our pipeline log. Thankfully, gitlab lets us override this behavior by specifying the **entrypoint** as an empty set `[""]`. This way, no command will be run when the image is run.

## **when**

This definition uses `when: manual`, which will pause the pipeline when it reaches the deploy step. Normally, the pipeline step would automatically execute, but with the **when** keyword, Gitlab will show a clickable play button that will start the job:

![Gitlab CI deploy button](https://malgasm.com/images/articles/kubeconfig-gitlab/deploy-button.png)
_You may want to remove the when: manual declaration when creating a pipeline to deploy to a test or staging server._

## **script**

The script section of the pipeline step is where the image switch is performed – we call the `kubectl` command and set the image of a deployment named `my-deployment` to `my.registry.com/my-image/$CI_COMMIT_REF_SLUG`. These values should be changed to reflect your build process.

The deployment name, specified in `deployment/my-deployment`, references the `metadata.name` property of your Kubernetes deployment. The image `set` command, which also uses the name `my-deployment`, references a different value, `spec.template.spec.initContainers[].name`, or `spec.template.spec.containers[].name`.

## **Bonus: Change Multiple Images in One Command**

You may have noticed that the `set` command above only contains the name of one image to change, and also that a Kubernetes deployment definition is allowed to have multiple images, specified through `containers` or `initContainers`. The `kubectl` command supports setting multiple images in one command by separating the images to be set by a space. I find this approach to be more clear and efficient than running multiple commands in the pipeline stage:

```
kubectl set image deployment/my-deployment my-deployment=my.registry.com/my-image/$CI_COMMIT_REF_SLUG my-other-deployment=my.registry.com/my-other-image/$CI_COMMIT_REF_SLUG
```

That’s it! Your Gitlab CI Pipelne should now be equipped with a new button that lets you deploy new revisions of your app! 🥳

Further Reading:

Kubernetes Deployments [https://kubernetes.io/docs/concepts/workloads/controllers/deployment/](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)

Using Kubeconfig Files [https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)

Gitlab .gitlab-ci.yml documentation [https://docs.gitlab.com/ee/ci/yaml/](https://docs.gitlab.com/ee/ci/yaml/)