Installing Knative with Istio on minikube for Windows

AirwaveTech
6 min readJan 9, 2020

Updated — Testing out Knative Serving v0.16.0

Knative (pronounced kay-nay-tiv) is a serverless solution you can run on Kubernetes, except in our case it’s minikube. We are going to do some basic set up and testing so you can get your feet wet and figure out what the Knative hype is about.

Before we dive in, a very quick and rudimentary breakdown of the Knative components:

Serving — We will be using Istio and Kubernetes to deploy and serve serverless applications and functions.

Eventing — A system to loosely couple services. Design principles include leveraging consumers, producers, and brokers. Sort of like Kafka.

Monitoring — This release allows you to deploy a monitoring solution using Elasticsearch-Logstash-Kibana (ELK stack), Jaeger, Prometheus, Grafana and/or Zipkin.

Because of limited resources on my PC, I had to omit the Monitoring part of the installation. I already have Prometheus and Grafana running from my Istio installation and I don’t want to run ELK right now, so I’m good to go. I’ll cover ELK or EFK in a future post.

For now, let’s move forward with our installation.

Installing Knative

Let’s give this a try. Don’t worry, you can always cleanly remove anything that’s been added here. I have Uninstall instructions at the end of this post.

Install Knative in your Istio-enabled minikube

Since we already have Istio installed, we decided to choose the installation method catered to this type of environment. We will be installing Knative files sourced from their official Github repos.

Check out the paths to understand which components you are installing.

kubectl apply --filename https://github.com/knative/serving/releases/download/v0.16.0/serving-crds.yamlkubectl apply --filename https://github.com/knative/serving/releases/download/v0.16.0/serving-core.yamlkubectl apply --filename https://github.com/knative/net-istio/releases/download/v0.16.0/release.yamlkubectl apply --filename https://github.com/knative/eventing/releases/download/v0.16.0/eventing-crds.yamlkubectl apply --filename https://github.com/knative/eventing/releases/download/v0.16.0/eventing-core.yamlkubectl apply --filename https://github.com/knative/eventing/releases/download/v0.16.0/in-memory-channel.yaml
A portion of the output from installing Knative-Eventing

Check on the installation

See if the Knative pods are running. It will take a few minutes depending on how many resources you have dedicated.

kubectl get pods --namespace knative-serving
kubectl get pods --namespace knative-eventing

Deploy a sample Serving serverless app

The following assumes you have a namespace called airwave-deploy . Once your Knative pods are running, it will be time to install a serverless app. This will utilize the Serving component of Knative. We will cover the Eventing component in a future post.

We will be applying a file named knative-service.yaml to deploy our hello-world web app, or in this case, serverless app. Knative will take care of the rest. That means that interoperability between Knative and Istio is included “out of the box”.

kubectl create namespace airwave-deploy
kubectl label namespace airwave-deploy istio-injection=enabled
kubectl apply --filename https://raw.githubusercontent.com/airwavetechio/hello-world/master/knative-service.yml
installing the airwavetech hello-world serverless example

Testing it out

Now that our serverless app is deployed, how do we access it? The following will show you how.

Get the IP and Port information

Imagine istio-ingressgateway as the one and only load balancer of our one-node cluster. Because minikube is a one-node cluster with a private IP assigned to it, you can presume that the load balancer of our single node cluster would be the same IP as the machine it was running on. It just so happens it is, and it listens on a certain TCP port. We need to find out what those are.

This will get your minikube IP and the port that the istio-ingressgateway is listening on.

minikube ip && kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==\"http2\")].nodePort}'

Get the Host header information

With the default settings, Knative will generate an accessible URL for your service, hence the example.com domain name. The naming convention can be customized to your liking, along with other settings, but that’s beyond the scope of what we are trying to do.

kubectl get ksvc airwavetech-helloworld -n airwave-deploy --output=custom-columns=NAME:.metadata.name,URL:.status.url
Capture the URL

We will use curl with the host header to test the route. The first request may take a little bit longer than you would expect. Your IP and URL will be different than mine.

curl -H "Host: <your URL without http://>" http://<minikube IP>:<istio-ingressgatway PORT> 
or
curl -H "Host: airwavetech-helloworld.airwave-deploy.example.com" http://192.168.79.129:30827 -v -i
curl the website using the proper host header

If you see

Hello World!

congratulations!

You just deployed your first serverless application on minkube!

Follow up

What just happened?

How did applying knative-service.yml get a service deployment out and routable?

Since we installed Knative using Istio on minikube, Knative will try to use the istio-ingressgateway to find an entry into your cluster. Once it does, Knative will carve out the proper path.

a screengrab from Kiali showing how things are connected

Here’s what our file looks like at the time of writing this:

This file looks like a mix up between your service definition and deployment.

Because it resembles a deployment file, you can imagine it’s using the same APIs as a deployment would. A key point here is that there are a lot of automatic changes to traffic routing done on your behalf. With strictly Istio, you would need a gateway and a virtual service applied in order to carve out the route.

Auto-Scale

As you check on your pods and look around, you might notice terminating pods.

kubectl get pods --namespace airwave-deploy
screengrab of various commands

You can see in the picture that pods are terminating by themselves. That’s because the Knative default configuration for auto-scaling is set to scale down to 0 after 30 seconds of inactivity. I encourage you to look deeper into the Knative configuration and edit your environment the best way it suits your needs.

screengrab of on-demand auto-scaling

This is why the first request, in a while, takes a little bit to respond successfully. Pods need to scale up! Give it a try by waiting idly for 30+ seconds, checking the pod status, and then sending your serverless app some traffic.

Uninstalling Knative

If you want to roll back everything we have just done, just run the following commands:

kubectl delete --filename   https://raw.githubusercontent.com/airwavetechio/hello-world/master/knative-service.ymlkubectl delete namespace airwave-deploykubectl delete --filename https://github.com/knative/eventing/releases/download/v0.16.0/in-memory-channel.yamlkubectl delete --filename https://github.com/knative/eventing/releases/download/v0.16.0/eventing-core.yamlkubectl delete --filename https://github.com/knative/eventing/releases/download/v0.16.0/eventing-crds.yamlkubectl delete --filename https://github.com/knative/net-istio/releases/download/v0.16.0/release.yamlkubectl delete --filename https://github.com/knative/serving/releases/download/v0.16.0/serving-core.yamlkubectl delete --filename https://github.com/knative/serving/releases/download/v0.16.0/serving-crds.yaml

Thanks for reading, and hopefully, this helps you understand Knative just a little bit better.

--

--

AirwaveTech

Helping you build the hardest parts of your Stack