A Practical Guide to Knative: Serverless on Kubernetes
Learn how to deploy and manage serverless workloads on Kubernetes using Knative — covering installation, auto-scaling, eventing, and a full NGINX deployment walkthrough.
Knative is a Kubernetes-based platform for building, deploying, and managing modern serverless workloads. This guide provides a structured overview, setup instructions, and real-world examples for understanding and implementing Knative effectively.
1. What is Knative?
Knative is a Kubernetes extension composed of custom controllers and custom resource definitions (CRDs) that enables serverless capabilities on top of Kubernetes. It abstracts infrastructure complexities so developers can focus on code.
Key Features
- Auto-scaling (to zero)
- Event-driven architecture
- Easy deployment of stateless applications
- Pluggable components
- Developer-friendly tooling
2. Core Components of Knative
Knative is made up of two main components:
2.1 Knative Serving
Handles the deployment and running of serverless workloads:
- Service — top-level resource managing the full lifecycle
- Route — maps network endpoints to revisions
- Configuration — maintains desired state
- Revision — immutable snapshot of code + config
2.2 Knative Eventing
Supports event-driven architecture and the management of event flow between services using:
- Broker — event ingress point
- Trigger — filters events to subscribers
- Subscription — connects channels to services
- Channel — persistent event buffer
3. Benefits of Knative
- Faster container-based development
- Focus on coding instead of infrastructure
- Easy entry into serverless computing
- Integration with tools like Django, Rails, Spring
4. Prerequisites
- Kubernetes cluster (v1.17+)
kubectlCLI installed and configured- Sufficient cluster resources
Note: This guide focuses on the Knative Serving component.
5. Installing Knative Serving
5.1 Serving Component
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.19.0/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.19.0/serving-core.yaml
5.2 Istio for Networking
kubectl apply -l knative.dev/crd-install=true -f https://github.com/knative/net-istio/releases/download/knative-v1.19.0/istio.yaml
kubectl apply -f https://github.com/knative/net-istio/releases/download/knative-v1.19.0/istio.yaml
kubectl apply -f https://github.com/knative/net-istio/releases/download/knative-v1.19.0/net-istio.yaml
5.3 Verify Installation
kubectl get pods -n knative-serving
6. DNS and Domain Configuration
Apply the default domain:
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.19.0/serving-default-domain.yaml
Patch for a custom domain:
kubectl patch configmap/config-domain \
--namespace knative-serving \
--type merge \
--patch '{"data":{"custom.com":""}}'
7. Deploying a Knative Service
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
spec:
containers:
- image: gcr.io/knative-samples/helloworld-go
env:
- name: TARGET
value: "IT WORKS!!"
8. Using Knative CLI (kn)
Installation
wget https://github.com/knative/client/releases/download/knative-v1.19.0/kn-linux-amd64
chmod +x kn-linux-amd64 && mv kn-linux-amd64 /usr/local/bin/kn
kn version
9. Using kn-func (Function CLI)
Installation
wget https://github.com/knative/func/releases/download/knative-v1.19.0/func_linux_amd64
chmod +x func_linux_amd64 && mv func_linux_amd64 /usr/local/bin/kn-func
Usage
kn func create -l python py1
kn func build
kn func run
kn func invoke
kn func deploy --namespace default -i docker.io/youruser/knfunc:tag
10. Accessing Services without DNS
# Patch ConfigMap
kubectl patch configmap/config-domain \
--namespace knative-serving \
--type merge \
--patch '{"data":{"custom.com":""}}'
# Access the service
curl -H "Host: nginx.default.custom.com" http://<external-ip>:<port>
11. Virtual Service with Istio
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: entry-route
namespace: default
spec:
gateways:
- knative-ingress-gateway.knative-serving.svc.cluster.local
hosts:
- test.domain.com
http:
- match:
- uri:
prefix: "/"
rewrite:
authority: testapi.default.svc.cluster.local
route:
- destination:
host: knative-local-gateway.istio-system.svc.cluster.local
port:
number: 80
12. Auto-Scaling & Serverless Behavior
Knative scales down to zero when the service is idle and scales up automatically on traffic. To enforce a concurrency limit:
kn service update <service-name> --concurrency-limit=1
13. Full NGINX Deployment on Knative
Here is a complete step-by-step NGINX deployment on Knative with all necessary Kubernetes manifests.
Step 1 — PersistentVolume (nginx-pv.yaml)
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data/nginx"
Step 2 — PersistentVolumeClaim (nginx-pvc.yaml)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Step 3 — ConfigMap (nginx-configmap.yaml)
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
Step 4 — Knative Service (nginx-knative-service.yaml)
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/metric: concurrency
autoscaling.knative.dev/target: "100"
spec:
containers:
- image: nginx:latest
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: config
mountPath: /etc/nginx/conf.d
volumes:
- name: html
persistentVolumeClaim:
claimName: nginx-pvc
- name: config
configMap:
name: nginx-config
Step 5 — Istio VirtualService (nginx-virtualservice.yaml)
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-vs
namespace: default
spec:
gateways:
- knative-ingress-gateway.knative-serving.svc.cluster.local
hosts:
- nginx.custom.com
http:
- match:
- uri:
prefix: "/"
rewrite:
authority: nginx.default.svc.cluster.local
route:
- destination:
host: knative-local-gateway.istio-system.svc.cluster.local
port:
number: 80
Access the NGINX Service
# Get Istio ingress IP
kubectl get svc istio-ingressgateway -n istio-system
# Curl with Host header
curl -H "Host: nginx.custom.com" http://<ISTIO_INGRESS_IP>:<PORT>