Setup your repositories to auto-magically deploy to your kubernetes cluster with Gitlab like a boss.

This process consists of the following steps:
- Setup environment variables.
- Configure our
deployment.yaml
. - Configure a
.gitlab-ci.yml
file.
Environment Variables
We need to instruct our build process as to what the api url and token is when connecting to kubernetes. We'll do this using environment variables..

Go to your project settings in gitlab and under the "CI / CD" tab expand "Variables". These variables will be used later in our .gitlab-ci.yml
file.
Here we will create the following two variables:
K8_PROD_API_URL
K8_PROD_TOKEN
To retrieve your kubernetes API url run kubectl cluster-info
. It will output something like the following:

To retrieve the token of the default (or hopefully another user) run kubectl describe token <secret name>
. (You can get your secrets by running kubectl get secrets
. In this example we'll use the default-token-xxxxx
:

Deployment
Gitlab Deploy Token
In order for our kubernetes cluster to be able to pull the docker images down we need to create a "deploy token":

ImagePullSecret
Since we're using a private docker image repository we need to instruct our kubernetes deployment as to what Secret
to use for authentication.
Create the secret using the username and password from the previous step:
kubectl create secret docker-registry \
gitlab-docker-registry \
--docker-server="registry.gitlab.com" \
--docker-username="<username from gitlab>" \
--docker-password="<token from gitlab>"
deployment.yaml
Now we can update our deployment.yaml
to use imagePullSecrets
pointing to the secret we just created:
apiVersion: apps/v1
kind: Deployment
metadata:
name: yourapp
labels:
app: yourapp
spec:
selector:
matchLabels:
app: yourapp
replicas: 1
template:
metadata:
labels:
app: yourapp
spec:
imagePullSecrets:
- name: gitlab-docker-registry
containers:
- image: $IMAGE
name: $APP
imagePullPolicy: Always
ports:
- containerPort: $PORT
name: http
...
.gitlab-ci.yml
You can configure your pipelines using a file called .gitlab-ci.yml
. This file defines the structure and order of the build processes (https://docs.gitlab.com/ee/ci/yaml/).
Create this file in your project root:
image: docker:latest
services:
- docker:dind
stages:
- build
- deploy
before_script:
- apk --update add git
- git submodule update --init
build-master:
stage: build
only:
- master
script:
- docker build --build-arg NPM_TOKEN="$NPM_TOKEN" -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
deploy-master:
stage: deploy
image: mateothegreat/docker-alpine-gcloud-kubectl
only:
- master
script:
- kubectl config set-cluster kube-cluster --server="$K8_PROD_API_URL" --insecure-skip-tls-verify=true
- kubectl config set-credentials gitlab --token="$K8_PROD_TOKEN"
- kubectl config set-context default-context --cluster=kube-cluster --user=gitlab
- kubectl config use-context default-context
- apk --update add git
- git submodule update --init
- make install
The deployment stage uses my pre-built image mateothegreat/docker-alpine-gcloud-kubectl
which contains the kubectl
command along with the Google Cloud Platform SDK.