EXPEDIA GROUP TECHNOLOGY — SOFTWARE

Flagger - Get Started with Istio and Kubernetes

Flagger enables automated deployments — in this part I’ll run through setting up the environment for Flagger

Fabian Piau
Expedia Group Technology

--

This series of articles is dedicated to Flagger, a tool that integrates with Kubernetes, the popular container orchestration platform. Flagger enables automated deployments and will be one step closer to a continuous deployment process.

This article is the first of the series and also the only one where we won’t use Flagger yet… this article will walk through how you to run a Kubernetes cluster on your local environment and deploy an application which will be accessible via an Istio gateway.

This is a hands-on guide and can be followed step by step on MacOS. It will require some adjustments if you are using a Windows or Linux PC. It is important to note that this article will not go into details and only grasp the concepts & technologies so if you are not familiar with Docker, Kubernetes, Helm or Istio, I strongly advise you to check some documentation yourself before continuing reading.

Picture of a container ship sailing on sea
Photo by Rinson Chory on Unsplash
Line separator

Docker

Install Docker by installing the Docker Desktop for Mac application, you can refer to the official installation guide. For Windows users, the equivalent application “Docker for Windows” exists.

In the next part, we will also use Docker for Mac to set up our local Kubernetes cluster. Note that this tutorial has been tested with Docker for Mac 2.4.0.0 that includes a Kubernetes Cluster in version 1.18.8, this is the latest at the moment of writing.

If you use a different version, technology is moving fast so I cannot guarantee that the commands used in this series will work without any adjustment.

Mirror HTTP Server

First a few words about the application Mirror HTTP Server we will use in this series of articles.

MHS is a very simple JavaScript application based on Node.js using the framework Express which allows you to customize the HTTP response received by setting specific HTTP headers in the request. The Docker image is publicly available on the Docker Hub. You can consult the Github repo of the project to find out more, please note that I am not the author.

This little app is exactly what we need to test the capabilities of Flagger to simulate 200 OK responses and 500 Internal Server Error responses.

Let’s pull the Docker image:

docker pull eexit/mirror-http-server

And run a new container that uses it:

docker run -itp 8080:80 eexit/mirror-http-server

Then let’s make sure it is functioning properly, in another terminal:

curl -I 'http://localhost:8080'

You should receive an HTTP 200 OK response:

HTTP/1.1 200 OK
X-Powered-By: Express
date: Fri, 02 Oct 2020 17:17:17 GMT
Connection: keep-alive

While:

curl -I -H X-Mirror-Code:500 'http://localhost:8080'

will return an HTTP 500 response:

HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
date: Fri, 02 Oct 2020 17:17:45 GMT
Connection: keep-alive

For simplicity, we use the curl command, but you can use your favourite tool, e.g. Postman.

Kubernetes

Now that you’ve installed Docker for Mac, having a Kubernetes cluster running locally will be a simple formality. You just need to check a box!

Tick the Enable Kubernetes box
Enable Kubernetes with Docker for Mac

If the light is green, then your Kubernetes cluster has successfully started. Please note, this requires a significant amount of resources, so don’t panic if the fan is running at full speed and it takes a bit of time to start…

Kube dashboard

We will install our first application in our Kubernetes cluster.

Kubernetes via Docker does not come with the dashboard by default, you have to install it yourself. This dashboard is very practical and provides a graphical interface of what is going on in your cluster and will save you from having to enter kubectl commands.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml

The dashboard is protected, but you can use the default user to access it. You can generate a default token via this command:

kubectl -n kube-system describe secret default | grep token: | awk '{print $2}'

Copy it.

You will need to re-use this command and /or the token copied if your session has expired, this happens when you don’t interact with the dashboard for a little while.

Finally, create a proxy to access the dashboard from the browser (this command will need to run indefinitely):

kubectl proxy

If you access http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login and use the token that you copied to authenticate, you should see this screen.

Kube Dashboard showing Services etc
Kube Dashboard

Helm

We use Homebrew for the installation of Helm. Homebrew is a handy package manager available for Mac.

We will use Helm to install Istio and the MHS application in our cluster. Helm is a bit like Homebrew, but for Kubernetes. We are using version 3. Helm will save you from having to enter many kubectl apply commands.

Let’s install Helm 3 with:

brew install helm@3

To verify that Helm has been installed:

helm version

You should have a similar output (note that Helm 3.3.4 is the latest version at the time of writing):

version.BuildInfo{Version:"v3.3.4", GitCommit:"a61ce5633af99708171414353ed49547cf05013d", GitTreeState:"dirty", GoVersion:"go1.15.2"}

Istio & Prometheus

Now, we are going to install the Istio Service Mesh. For full explanations and the benefits of using a Service Mesh, I invite you to read the official documentation.

First of all, you must increase the memory limits of your Kubernetes via Docker, otherwise you will run into deployment issues. Your laptop’s fans will recover, don’t worry…

Here is my configuration:

Shows resources, 4 CPU, 8MB RAM, etc
Kubernetes Configuration in Docker for Mac for Istio

I followed the Docker Desktop recommendations for Istio.

Let’s go and install Istio 1.7.3 (the latest version at the time of writing). First, download the source:

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.7.3 sh -

cd istio-1.7.3

Add the istioctl client to your path:

export PATH=$PWD/bin:$PATH

Install Istio with the provided client, we use the demo profile:

istioctl install --set profile=demo

After a few minutes, you should get a message confirming that Istio has been installed. And voilà!

To install the latest version of Istio, you can simply replace the first line with curl -L https://istio.io/downloadIstio | sh -.

Add Prometheus as it’s required for Flagger:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/prometheus.yaml

From the Kube dashboard, verify that a new namespace has been created istio-system and that it contains the Istio tools including Prometheus.

Istio system selected from the dropdown at the top, shows prometheus pods in the namespace
Istio and Prometheus are deployed in your cluster

Why is Prometheus important? Because it is an essential component for Flagger which will provide the metrics to show if the new version of your application is healthy or not, thus it will know when to promote or rollback a version. I will come back to this in detail in the next article.

Deploying Mirror HTTP Server

Before deploying MHS, let’s create a new namespace application, we don't want to use the default one at the root of the cluster (this is good practice). The name is too generic, but sufficient for this tutorial, in general you will use the name of the team or the name of a group of features.

kubectl create ns application

Do not forget to activate Istio on this new namespace:

kubectl label namespace application istio-injection=enabled

To deploy MHS, I created a Helm chart.

This chart was created with the helm create mhs-chart command, then I updated to use the latest image of MHS. I also added a gateway.yaml file to configure the Istio gateway so it can be accessible outside of the cluster.

Clone the chart repo:

git clone https://github.com/ExpediaGroup/mhs-chart.git

And install MHS:

cd mhs-chart
helm install mhs --namespace application ./mhs

After a few moments, if you look at the dashboard, you should see 1 replica of MHS in the namespace application.

Application in the namespace dropdown shows MHS the pod is deployed in your cluster
MHS is deployed in your cluster

You now have 1 MHS pod running in your Kubernetes cluster. The pod is exposed to the outside world via an Istio gateway.

To test, use the similar commands that we used against the docker container earlier:

curl -I -H Host:mhs.example.com 'http://localhost'

You should receive an HTTP 200 OK response that was handled by Envoy, the proxy used by Istio:

HTTP/1.1 200 OK
x-powered-by: Express
date: Fri, 02 Oct 2020 17:37:19 GMT
x-envoy-upstream-service-time: 17
server: istio-envoy
transfer-encoding: chunked

And:

curl -I -H Host:mhs.example.com -H X-Mirror-Code:500 'http://localhost'

should return an HTTP 500 response:

HTTP/1.1 500 Internal Server Error
x-powered-by: Express
date: Fri, 02 Oct 2020 17:38:34 GMT
x-envoy-upstream-service-time: 2
server: istio-envoy
transfer-encoding: chunked

Congratulations, you’ve come to the end of this first tutorial!

For information, you can also access MHS with your favourite browser if you run a proxy command first to expose the pod:

export POD_NAME=$(kubectl get pods --namespace application -l "app.kubernetes.io/name=mhs,app.kubernetes.io/instance=mhs" -o jsonpath="{.items[0].metadata.name}")

kubectl port-forward --namespace application $POD_NAME 8080:80

Then, navigate to http://localhost:8080/.

You should see a… blank page. This is normal, MHS does not return a body in the response and there is no HTML output!

Cleaning up resources

You can delete the MHS application and its namespace.

helm delete mhs --namespace application

kubectl delete namespaces application

We don’t remove Istio / Prometheus because we will need it in the next article, but if you want to free up some resources, you can use these commands:

kubectl delete -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/prometheus.yamlistioctl manifest generate --set profile=demo | kubectl delete -f -kubectl delete namespaces istio-system
Line separator

What’s next?

The next article will focus on the installation of Flagger and use different versions of MHS to try canary deployments. Stay tuned! In the meantime, you can stop the Kubernetes cluster by unchecking the box and restarting Docker Desktop. Your computer deserves a break.

Learn more about technology at Expedia Group

--

--