We need to set up our cluster by using the Gitlab UI interface. Gitlab allows us to install the helm tiller. We need Gitlab Runner to let Gitlab execute jobs and push back results to us.
On settings -> Variables, we need to set up some environment variables:
- GCP_PROJECT
- GCP_SERVICE_KEY
- GKE_CLUSTER_NAME
- GKE_CLUSTER_ZONE
GCP_SERVICE_KEY is the json from your service account. The other variables are pretty straightforward.
If you have any problem on installing tiller from Gitlab CI, for example a difference between the tiller server version and client version, you need to install the tiller from your command line. This happens sometimes.
Using Helm
The deployment will be made in two steps: build and deploy.
Build
At this phase, it gets the source code, build as a docker image and uploads it to the Gitlab Container Registry. The docker image is defined as a variable at the beginning of the yaml file:
variables:
IMAGE: “${CI_REGISTRY_IMAGE}/web:${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}”
CI_REGISTRY_IMAGE
,
CI_COMMIT_REF_SLUG
are variables from the Gitlab CI.
We also need to pass the commit short sha for the image, because we want to create a review app for each branch.
It runs the docker login into our Gitlab registry container and push our docker image to there.
build:
stage: build
script:
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
- docker pull ${IMAGE} || true
- docker build —cache-from ${IMAGE} -t ${IMAGE} -f ./Dockerfile .
- docker push ${IMAGE}
Deploy
The deploy will be made by helm. As we have the helm files inside of our repository, we can easily access them by using _k8s_manager. Manager in this case is the name of our files. Some people use to have a repository only to store this information, and then clone them here. We are not doing this, we are pushing the helm files in the same repository.
The stage name will be
deploy
, but its name will be
deploy_review
.
To run the deploy, the script should be connected to the cluster. To do so, it needs the GCP credentials that we have stored as environment variables in Gitlab.
- echo $GCP_SERVICE_KEY > /tmp/kubeadmin.json
- gcloud config set project $GCP_PROJECT
- gcloud auth activate-service-account —key-file /tmp/kubeadmin.json
- gcloud container clusters get-credentials $GKE_CLUSTER_NAME —zone $GKE_CLUSTER_ZONE —project $GCP_PROJECT
After this, we install helm tiller, in case we don’t have it installed(you probably don’t need this step, I’m putting here because we some cases we have problems with helm versions, feel free to remove it if you think you don’t need it).
- helm init —service-account tiller —force-upgrade
The image we are using should have access to the Gitlab container registry. We set the right variables in our cluster.
- ‘printf “apiVersion: v1\nkind: Secret\n$(kubectl create secret docker-registry gitlab-registry —docker-server=$CI_REGISTRY —docker-username=$CI_REGISTRY_USER —docker-password=$CI_REGISTRY_PASSWORD —docker-email=$GITLAB_USER_EMAIL -o yaml —dry-run)” | kubectl apply -f -‘
Once we have helm tiller installed, we can use the command
helm upgrade
and deploy our new app.
In this case, we set the name of the deployment appending the branch name:
manager-${CI_COMMIT_REF_SLUG}
.
With this, we have our script done for deploying a review app version.
deploy_review:
stage: deploy
image: franzejr/helm
script:
- echo $GCP_SERVICE_KEY > /tmp/kubeadmin.json
- gcloud config set project $GCP_PROJECT
- gcloud auth activate-service-account —key-file /tmp/kubeadmin.json
- gcloud container clusters get-credentials $GKE_CLUSTER_NAME —zone $GKE_CLUSTER_ZONE —project $GCP_PROJECT
- helm init —service-account tiller —force-upgrade
- echo $CI_REGISTRY_IMAGE
- echo $CI_COMMIT_REF_SLUG
- echo ${CI_COMMIT_SHORT_SHA}
- echo “${CI_REGISTRY_IMAGE}/web:${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}”
# Creating a docker registry secret so that kubernetes can connect to gitlab registry and pull the image
- kubectl config set-context —current —namespace=gitlab-managed-apps
- ‘printf “apiVersion: v1\nkind: Secret\n$(kubectl create secret docker-registry gitlab-registry —docker-server=$CI_REGISTRY —docker-username=$CI_REGISTRY_USER —docker-password=$CI_REGISTRY_PASSWORD —docker-email=$GITLAB_USER_EMAIL -o yaml —dry-run)” | kubectl apply -f -‘
- helm upgrade —install
—set image.repository_url=“${IMAGE}”
—force manager-${CI_COMMIT_REF_SLUG} ./k8s/manager
except:
refs:
- master
The complete gitlab-ci file you can see here:
image: docker:stable
services:
- docker:stable-dind
stages:
- build
- deploy
variables:
IMAGE: “${CI_REGISTRY_IMAGE}/web:${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}”
build:
stage: build
script:
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
- docker pull ${IMAGE} || true
- docker build —cache-from ${IMAGE} -t ${IMAGE} -f ./Dockerfile .
- docker push ${IMAGE}
deploy_review:
stage: deploy
image: franzejr/helm
script:
- echo $GCP_SERVICE_KEY > /tmp/kubeadmin.json
- gcloud config set project $GCP_PROJECT
- gcloud auth activate-service-account —key-file /tmp/kubeadmin.json
- gcloud container clusters get-credentials $GKE_CLUSTER_NAME —zone $GKE_CLUSTER_ZONE —project $GCP_PROJECT
- helm init —service-account tiller —force-upgrade
# Creating a docker registry secret so that kubernetes can connect to gitlab registry and pull the image
- kubectl config set-context —current —namespace=gitlab-managed-apps
- ‘printf “apiVersion: v1\nkind: Secret\n$(kubectl create secret docker-registry gitlab-registry —docker-server=$CI_REGISTRY —docker-username=$CI_REGISTRY_USER —docker-password=$CI_REGISTRY_PASSWORD —docker-email=$GITLAB_USER_EMAIL -o yaml —dry-run)” | kubectl apply -f -‘
- helm upgrade —install
—set image.repository_url=“${IMAGE}”
—force manager-${CI_COMMIT_REF_SLUG} ./k8s/manager
except:
refs:
- master
Comments for How to create a review app using Gitlab CI