The magic behind our build-pipeline

This guide should give you a more in depth view of how your app gets deployed after you pushed to either the staging or production branch. What is described in the following is fully automated and make the life of developers in the VIS much easier.

Lets start from the beginning. You pushed your new app the first time to the staging branch. You have committed a Dockerfile, a .gitlab-ci.yml file and cinit.yml file. This is mostly all our infrastructure needs from your side to be able to make your app accessable from the "real world". The first file used is the .gitlab-ci.yml file. GitLab has a built-in tool, where it executes a pipeline of scripts defined in the .gitlab-ci.yml. These scripts can be everything, from build, over tests, to code validations. We provide a template consisting of 3 stages: build, deploy and cleanup. All these steps are executed on our gitlab runner on build.vis.ethz.ch. We are going to step through each of them.

  • First we have the build stage: In there we build the docker image based on your Dockerfile. Moreover if your app needs certain services such as the people-api, message-api or mailalias-api, we generate the needed file, as you have done locally with service generate.
  • In the next step we deploy the app: Here we push the generated docker image to our registry, where we store our docker images (similar to Dockerhub). Our registry is reachable at registry.vis.ethz.ch. The last step in deploy is the actual deployment of your app. For this we use helm to generate the deployment of your app. The deployment is the config of how to run your app in our infrastructure. This includes for example how many instance of you app are running, on what domain you app is reachable or simply the name of your app. All this information is gathered from your .gitlab-ci.yml, where you have specified variables such as VIS_CI_REPLICAS, VIS_CI_DEPLOYMENT_SUBDOMAIN or VIS_CI_APP_NAME. There are many more variables you are able to set. An optional step in the deploy stage is to publish services. That means if your app provides a service for other apps such as the people-api you need to be registered, such that other apps know your app exists.

Maybe you wonder where all these instructions come from? If you have a closer look at your .gitlab-ci.yml, you might have noticed that at the end of this file there is something like

.auto_devops: &auto_devops |
  git clone --depth 1 git@gitlab.ethz.ch:vis/cit/ci-framework.git
  source ci-framework/ciscript.sh

This connects the pipeline provided by gitlab with the desired steps. If you are more interested you should have a look at the ciscript.sh in our ci-framework.

Now we have our app in the form of a docker images saved in our registry. But how do we get this app running now? Again this is helm. It first generates a kubernetes configuration from some templates which you also find in the ci-framework and then it notifies our Kubernetes that there is a new image to run. Kubernetes is a open-soure application to automatically manage, scale and provide docker containers. Now kubernetes pulls the newly created docker images, gets rid of the old one and starts up your app. After some time your app is available on the domain you have specified in your .gitlab-ci.yml.

Now where does your program actually run? It's

  • inside the docker container you just built

  • which runs inside a Kubernetes worker VM in the VIS's internal network

  • which runs on one of the 5 main compute nodes compute0.vis.ethz.ch to compute4.vis.ethz.ch.

And how does my request travel through the network?

If you resolve the website from DNS you will receive 2 IPs which belong to our routers kube-router-1.vis.ethz.ch and kube-router-2.vis.ethz.ch. They are two VMs routing packets between the Internet and our internal network. Your HTTP request is decrypted and analysed there. The router then decides to forward it to a so called ingress (this is a kubernetes term). This ingress is a container running nginx on the Kubernetes worker VMs. The ingress looks up, which service (again a kubernetes term) is running this application. A service is nothing more than an IP address without a machine owning it, a so-called virtual IP. The ingress sends the request to that IP address. A Linux mechanism called IPVS then looks up the mapping from Service IP to your actual container IP. Finally the kernel delivers the request to your container.

results matching ""

    No results matching ""