Serverless on Kubernetes
What if your containers could scale to zero when nobody's using them, and spring back to life in milliseconds?
Welcome to serverless on Kubernetes...
Cloud providers each built their own serverless:
First mover (2014). Massive ecosystem. Deeply tied to AWS services.
Microsoft's offering. Good .NET integration. Tied to Azure.
But what if you want serverless without vendor lock-in?
What if serverless ran on standard Kubernetes?
An open-source platform that brings serverless capabilities to Kubernetes.
| Feature | AWS Lambda | Azure Functions | Knative |
|---|---|---|---|
| Runtime | Proprietary | Proprietary | Any container |
| Vendor Lock-in | High | High | None |
| Runs on | AWS only | Azure only | Any K8s |
| Scale to Zero | Yes | Yes (Consumption) | Yes |
| Max Duration | 15 min | Varies | No limit |
| Local Dev | SAM/emulation | Core Tools | Real K8s |
1. What is Knative's current status within the CNCF?
2. What is the main advantage of Knative over AWS Lambda?
3. Which company originally created Knative?
Knative is made up of two main components:
Deploy and auto-scale your containers. Handles request routing, revisions, and scale-to-zero.
HTTP workloads
Event-driven architecture. Produce, route, and consume events using CloudEvents.
Async workloads
Developer
|
[kubectl / kn CLI]
|
+---------+---------+
| |
v v
Knative Serving Knative Eventing
| |
v v
Activator Broker/Trigger
Queue-Proxy Sources/Sinks
Autoscaler Channels
| |
+------- K8s -------+
| Networking Layer |
| (Kourier / Istio) |
+---------------------+
Knative needs a networking layer for traffic routing:
For AKS, Kourier is the simplest starting point. Upgrade to Istio when you need mTLS or advanced traffic policies.
Before installing Knative on AKS, you need:
kubectl configured to access the clusterkn CLI (optional but recommended)# Verify cluster access kubectl cluster-info kubectl get nodes # Install kn CLI brew install knative/client/kn # macOS
# Install Knative Serving CRDs
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.14.0/serving-crds.yaml
# Install Knative Serving core components
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.14.0/serving-core.yaml
# Install Kourier networking layer
kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.14.0/kourier.yaml
# Configure Knative to use Kourier
kubectl patch configmap/config-network \
--namespace knative-serving \
--type merge \
--patch '{"data":{"ingress-class":"kourier.ingress.networking.knative.dev"}}'
# Install Knative Eventing CRDs kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/eventing-crds.yaml # Install Knative Eventing core kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/eventing-core.yaml # Install In-Memory Channel (for dev/testing) kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/in-memory-channel.yaml # Install MT-Channel-Based Broker kubectl apply -f https://github.com/knative/eventing/releases/download/knative-v1.14.0/mt-channel-broker.yaml
# Check Serving components kubectl get pods -n knative-serving NAME READY STATUS activator-abcdef1234-xxxxx 1/1 Running autoscaler-abcdef1234-xxxxx 1/1 Running controller-abcdef1234-xxxxx 1/1 Running webhook-abcdef1234-xxxxx 1/1 Running # Check Eventing components kubectl get pods -n knative-eventing NAME READY STATUS eventing-controller-abcdef1234-xxxxx 1/1 Running eventing-webhook-abcdef1234-xxxxx 1/1 Running # Check Kourier kubectl get pods -n kourier-system
1. What are the two main components of Knative?
2. Which networking layer is recommended as the simplest option for Knative on AKS?
3. What minimum Kubernetes version is recommended for Knative?
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello-world
namespace: default
spec:
template:
spec:
containers:
- image: gcr.io/knative-samples/helloworld-go
ports:
- containerPort: 8080
env:
- name: TARGET
value: "World"
# Deploy the service
kubectl apply -f hello-world.yaml
# Or use the kn CLI
kn service create hello-world \
--image gcr.io/knative-samples/helloworld-go \
--env TARGET=World
# Check the service
kn service list
NAME URL READY
hello-world http://hello-world.default.example.com True
# Access the service
curl -H "Host: hello-world.default.example.com" \
http://$(kubectl get svc kourier -n kourier-system \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# Watch pods in real-time kubectl get pods -w NAME READY STATUS hello-world-00001-deployment-abc123-xyz 2/2 Running # ... 60 seconds of no traffic later ... hello-world-00001-deployment-abc123-xyz 2/2 Terminating hello-world-00001-deployment-abc123-xyz 0/2 Terminating # Zero pods! Zero cost! # Send another request... curl http://hello-world.default.example.com # Pod spins up automatically! hello-world-00001-deployment-abc123-new 0/2 Pending hello-world-00001-deployment-abc123-new 2/2 Running
Request arrives at Kourier
|
[Is there a running pod?]
/ \
Yes No
| |
Route to Route to Activator
Pod (holds request)
| |
Response Activator tells
Autoscaler to
scale up from 0
|
Pod starts (cold start)
|
Request forwarded to pod
|
Response
A developer-friendly CLI for Knative operations:
# Create a service kn service create hello --image myregistry/hello:v1 # Update a service kn service update hello --env TARGET=Knative # List services kn service list # Describe a service kn service describe hello # Delete a service kn service delete hello # List revisions kn revision list # Show traffic routes kn route list
hello-world-00001, hello-world-00002, etc.# Update the service -- creates a new revision automatically kn service update hello-world --env TARGET=Knative # Check revisions kn revision list NAME SERVICE TRAFFIC READY hello-world-00002 hello-world 100% True hello-world-00001 hello-world True # Each update = new revision kn service update hello-world --env TARGET=Universe kn revision list NAME SERVICE TRAFFIC READY hello-world-00003 hello-world 100% True hello-world-00002 hello-world True hello-world-00001 hello-world True
1. What happens when a Knative Service receives no traffic for ~60 seconds (with default settings)?
2. What component handles requests when a Knative Service is scaled to zero?
3. What is a Knative Revision?
Knative lets you split traffic between revisions:
# Send 80% to latest, 20% to previous revision kn service update hello-world \ --traffic hello-world-00003=80 \ --traffic hello-world-00002=20 # Tag a revision for direct access kn service update hello-world \ --tag hello-world-00002=staging # Access tagged revision directly: # http://staging-hello-world.default.example.com
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: hello-world
spec:
template:
spec:
containers:
- image: myregistry/hello:v3
traffic:
- latestRevision: true
percent: 80
- revisionName: hello-world-00002
percent: 20
- revisionName: hello-world-00001
percent: 0
tag: legacy
Tagged revisions get their own URLs even with 0% traffic -- great for testing!
Developer updates Service
|
Controller creates new Revision
|
Route updated with traffic rules
|
Pods created for new Revision
|
Health check passes
|
Traffic shifts to new Revision
|
Old Revision pods scale to zero
|
(Old Revision still exists for rollback)
| Capability | K8s Deployment | Knative Service |
|---|---|---|
| Scale to zero | No (min 1 replica) | Yes |
| Traffic splitting | Needs Istio/mesh | Built-in |
| Revisions | Manual (ReplicaSets) | Automatic |
| Auto-scaling | HPA (CPU-based) | Request-based (KPA) |
| Networking | Service + Ingress | Built-in routing |
| Resources needed | 3+ YAML files | 1 YAML file |
In the next module, we'll take a deep dive into Knative Serving:
Module 2: Knative Serving Deep Dive
Your containers now have superpowers.