To run an application with Knative on a Kubernetes cluster and expose it to the public internet, you need: | |
an application packaged as container image | |
a Knative Service manifest file | |
Service definition | |
To expose an application on Knative, you need to define a Service object. (This is different than the Kubernetes Service type which helps you set up load balancing for Pods.) | |
Save the following into a file named helloworld.yaml: | |
helloworld.yaml | |
apiVersion: serving.knative.dev/v1 | |
kind: Service | |
metadata: | |
name: hello | |
spec: | |
template: | |
spec: | |
containers: | |
- image: gcr.io/knative-samples/helloworld-go | |
ports: | |
- containerPort: 8080 | |
env: | |
- name: TARGET | |
value: "World" | |
This Knative Service example uses the container image gcr.io/knative-samples/helloworld-go, which is a Go web application listening on port 8080 (currently required port number by Knative). | |
Deploy it: | |
$ kubectl apply -f helloworld.yaml | |
Verify it's deployed by querying "ksvc" (Knative Service) objects: | |
$ kubectl get ksvc | |
NAME CREATED AT | |
helloworld 32s | |
Make a request | |
External requests to Knative applications in a cluster go through a single public load balancer called knative-ingressgateway which has a public IP address. | |
Find the public IP address of the gateway (make a note of the EXTERNAL-IP field in the output), by running: | |
$ kubectl get service --namespace=istio-system istio-ingressgateway | |
Find the hostname of the application: | |
$ kubectl get ksvc | |
$ kubectl get ksvc helloworld --output jsonpath='{.status.domain}' | |
The hostname of the application should be helloworld.default.example.com. | |
Now, use curl to make the first request to this function (replace the IP_ADDRESS below with the gateway's external IP address you found earlier): | |
$ curl -H "Host: helloworld.default.example.com" http://IP_ADDRESS | |
$ curl -H "Host: hello.default.example.com" http://a9ae901051ac946dcb73928376469d03-1543302244.us-west-2.elb.amazonaws.com | |
Hello world! | |
After you made a request to the helloworld Service, you will see that a Pod is created on the Kubernetes cluster to serve the request. Query the list of Pods deployed: | |
$ kubectl get pods | |
NAME READY STATUS AGE | |
helloworld-00001-deployment-58b8b4d79b 3/3 Running 1m | |
Observe autoscaling | |
Watch the pods and see how they scale to zero after traffic stops going to the URL: | |
kubectl get pod -l serving.knative.dev/service=hello -w | |
Note | |
It may take up to 2 minutes for your pods to scale down. Pinging your service again resets this timer. | |
Expected output | |
NAME READY STATUS | |
hello-world 2/2 Running | |
hello-world 2/2 Terminating | |
hello-world 1/2 Terminating | |
hello-world 0/2 Terminating | |
Scale up your Knative Service¶ | |
Rerun the Knative Service in your browser. You can see a new pod running again: | |
Expected output | |
NAME READY STATUS | |
hello-world 0/2 Pending | |
hello-world 0/2 ContainerCreating | |
hello-world 1/2 Running | |
hello-world 2/2 Running | |
List your Knative Service | |
View a list of Knative Services by running the command: | |
$ kubectl get ksvc | |
Introduction to Knative Serving API | |
When you deploy the helloworld Service to Knative, it creates three kinds of objects: Configuration, Route, and Revision: | |
kubectl get configuration,revision,route | |
NAME CREATED AT | |
configuration.serving.knative.dev/helloworld 28m | |
NAME CREATED AT | |
revision.serving.knative.dev/helloworld-00001 28m | |
NAME CREATED AT | |
route.serving.knative.dev/helloworld 28m | |
Creating a new Revision | |
Instead of TARGET=World, update the environment variable TARGET on your Knative Service to greet "Knative" instead. | |
Edit your existing hello.yaml file to contain the following: | |
apiVersion: serving.knative.dev/v1 | |
kind: Service | |
metadata: | |
name: hello | |
spec: | |
template: | |
spec: | |
containers: | |
- image: gcr.io/knative-samples/helloworld-go | |
ports: | |
- containerPort: 8080 | |
env: | |
- name: TARGET | |
value: "Knative" | |
Deploy the updated version of your Knative Service by running the command: | |
$ kubectl apply -f hello.yaml | |
Because you are updating an existing Knative Service, the URL won't change, but the new Revision has the new name hello-00002. | |
Accessing the new Revision & View Existing Revisions | |
To see the change, access the Knative Service again on your browser or use curl in your terminal: | |
$ echo "Accessing URL $(kn service describe hello -o url)" | |
$ curl "$(kn service describe hello -o url)" | |
$ kubectl get revisions | |
$ kn revisions list | |
When running the kn command, the relevant column is TRAFFIC. You can see that 100% of traffic is going to the latest Revision, hello-00002, which is on the row with the highest GENERATION. 0% of traffic is going to the Revision hello-00001. | |
When you create a new Revision of a Knative Service, Knative defaults to directing 100% of traffic to this latest Revision. You can change this default behavior by specifying how much traffic you want each Revision to receive. | |
Splitting traffic between Revisions | |
Split the traffic between the two Revisions: | |
Add the traffic section to the bottom of your existing hello.yaml file | |
apiVersion: serving.knative.dev/v1 | |
kind: Service | |
metadata: | |
name: hello | |
spec: | |
template: | |
spec: | |
containers: | |
- image: gcr.io/knative-samples/helloworld-go | |
ports: | |
- containerPort: 8080 | |
env: | |
- name: TARGET | |
value: "Knative" | |
traffic: | |
- latestRevision: true | |
percent: 50 | |
- latestRevision: false | |
percent: 50 | |
revisionName: hello-00001 | |
Verify the traffic split | |
$ kn revisions list | |
$ kubectl get revisions |
Here’s what each of these Serving APIs do:
Service | Describes an application on Knative. |
Revision | Read-only snapshot of an application’s image and other settings (created by Configuration ). |
Configuration | Created by Service (from its spec.configuration field). It creates a new Revision when the revisionTemplate field changes. |
Route | Configures how the traffic coming to the Service should be split between Revision s. |
This diagram explains the relationship between them:

I’m a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I am working at Cotocus. I blog tech insights at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at I reviewed , and SEO strategies at Wizbrand.
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at PINTEREST
Rajesh Kumar at QUORA
Rajesh Kumar at WIZBRAND