Basics of Traffic Splitting¶
The last super power of Knative Serving we'll go over is traffic splitting.
Splitting traffic is useful for a number of very common modern infrastructure needs, such as blue/green deployments and canary deployments. Bringing these industry standards to bear on Kubernetes is as simple as a single CLI command on Knative or YAML tweak, let's see how!
What are revisions?¶
Knative Serving splits traffic between different Revisions
of a Knative Service. You can think of a Revision
as a stateless, autoscaling snapshot-in-time of application code and configuration. A new Revision
will get created each and every time you make changes to your Knative Service.
You may have noticed that when your Knative Service was created, Knative returned both a URL and a 'latest revision' for your Service. But what happens if we make a change to our service?
Creating a new Revision¶
Instead of "world," let's have our Knative Service "hello" greet "Knative." You can accomplish this by using the kn
CLI or by editing the YAML file you made earlier.
kn service update hello --env TARGET=Knative
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"
kubectl apply -f hello.yaml
As before, Knative spits out some helpful information to the CLI:
Service hello created to latest revision <revision-name> is available at URL:
<service-url>
Notice, since we are updating an existing Knative Service, the URL doesn't change, but your Revision
should have incremented by one (something like "hello-xxxxx-2").
Let's ping our Knative Service again to see the change:
curl <service-url>
The output should be:
Hello Knative!
Splitting Traffic between Revisions¶
Remember when I said that a Revision
was a "stateless, autoscaling snapshot-in-time of application code and configuration?" You may at this point be wondering, "where did 'Hello world!' go?"
We can easily see a list of our existing revisions with the kn
CLI:
kn get revisions
Though the following example doesn't cover it, you can peak under the hood to Kubernetes to see the revisions as Kubernetes sees them.
kubectl get revisions
The output should be:
NAME SERVICE TRAFFIC TAGS GENERATION AGE CONDITIONS READY REASON
hello-xxxxx-2 hello 100% 2 10m 3 OK / 4 True
hello-xxxxx-1 hello 1 17h 3 OK / 4 True
The column most relevant for our purposes is "TRAFFIC". It looks like 100% of traffic is going to our latest Revision
(hello-xxxxx-2) "Hello Knative!" and 0% of traffic is going to the Revision
we configured first (hello-xxxxx-1), "Hello world!"
By default, when Knative creates a brand new Service it directs 100% of traffic to @latest
, and updates the pointer @latest
with the most recent Revision
when we make a change to our Service. We can change this default behavior by using specifying how much traffic we want each of our Revisions
to receive.
kn service update hello \
--traffic hello-xxxxx-1=50 \
--traffic hello-xxxxx-2=50
kn service update hello \
--traffic hello-xxxxx-1=50 \
--traffic @latest=50
@latest
will always point to our "latest" Revision
which, at the moment, is hello-xxxxx-2
.
apiVersion: serving.knative.dev/v1
kind: Route
metadata:
name: route-hello
spec:
traffic:
- revisionName: hello-xxxxx-1
- percent: 50
- revisionName: hello-xxxxx-2
percent: 50
kubectl apply -f hello.yaml
Now when we curl our Knative Service URL...
[...] curl <service-url>
Hello Knative!
[...] curl <service-url>
Hello world!
Congratulations, you've successfully split traffic between 2 different
Revisions
. Up next, Knative Eventing!