public

Gitlab CI/CD with Kubernetes

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

Latest Post Speed kills software engineering. by Matthew Davis public

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

This process consists of the following steps:

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..

Your Project -> Settings -> CI / CD

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:

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":

Your Project -> Settings -> Repository -> Deploy Tokens

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
              ...
deployment.yaml

.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
.gitlab-ci.yml

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.

Matthew Davis

Published 4 years ago