Basics of Traffic Splitting

The last super power 🚀 of Knative Serving we’ll go over in this tutorial is traffic splitting.

What are some common traffic splitting use-cases?

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!

Creating a new Revision

A new Revision gets created each and every time you make changes to the configuration of your Knative Service. When splitting traffic, Knative splits traffic between different Revisions of your Knative Service.

What exactly is a Revision?

You can think of a Revision snapshot-in-time of application code and configuration.

Create a new Revision

Instead of TARGET=World update the environment variable TARGET on your Knative Service hello to greet “Knative” instead.

knYAML

Deploy the updated version of your Knative Service by running the command:

  1. kn service update hello \
  2. --env TARGET=Knative

As before, kn prints out some helpful information to the CLI.

Expected output

  1. Service 'hello' created to latest revision 'hello-00002' is available at URL:
  2. http://hello.default.${LOADBALANCER_IP}.sslip.io
  1. Edit your existing hello.yaml file to contain the following:

    1. ---
    2. apiVersion: serving.knative.dev/v1
    3. kind: Service
    4. metadata:
    5. name: hello
    6. spec:
    7. template:
    8. spec:
    9. containers:
    10. - image: gcr.io/knative-samples/helloworld-go
    11. ports:
    12. - containerPort: 8080
    13. env:
    14. - name: TARGET
    15. value: "Knative"
  2. Deploy the updated version of your Knative Service by running the command:

    1. kubectl apply -f hello.yaml

    Expected output

    1. service.serving.knative.dev/hello configured

Note that since we are updating an existing Knative Service hello, the URL doesn’t change, but our new Revision should have the new name hello-00002.

Access the new Revision

To see the change, access the Knative Service again on your browser or use curl in your terminal:

  1. echo "Accessing URL $(kn service describe hello -o url)"
  2. curl "$(kn service describe hello -o url)"

Expected output

  1. Hello Knative!

Splitting Traffic

You may at this point be wondering, “where did ‘Hello World!’ go?” Remember, Revisions are an immutable snapshot-in-time of application code and configuration, so your old hello-00001 Revision is still available to you.

List your Revisions

We can easily see a list of our existing Revisions with the kn or kubectl CLI.

knkubectl

View a list of revisions by running the command:

  1. kn revisions list

Expected output

  1. NAME SERVICE TRAFFIC TAGS GENERATION AGE CONDITIONS READY REASON
  2. hello-00002 hello 100% 2 30s 3 OK / 4 True
  3. hello-00001 hello 1 5m 3 OK / 4 True

View a list of Revisions by running the command:

  1. kubectl get revisions

Expected output

  1. NAME CONFIG NAME K8S SERVICE NAME GENERATION READY REASON ACTUAL REPLICAS DESIRED REPLICAS
  2. hello-00001 hello 1 True 0 0
  3. hello-00002 hello 2 True 0 0

When running the kn command, the column most relevant for our purposes is TRAFFIC. We can see that 100% of traffic is going to our latest Revision, hello-00002, which is on the row with the highest GENERATION. 0% of traffic is going to the Revision we configured earlier, hello-00001.

When you create a new Revision of a Knative Service, Knative defaults to directing 100% of traffic to this latest Revision. We can change this default behavior by specifying how much traffic we want each of our Revisions to receive.

Split traffic between Revisions

Lets split traffic between our two Revisions:

knYAML

Run the command:

  1. kn service update hello \
  2. --traffic hello-00001=50 \
  3. --traffic @latest=50
  1. Add the traffic section to the bottom of your existing hello.yaml file:

    1. apiVersion: serving.knative.dev/v1
    2. kind: Service
    3. metadata:
    4. name: hello
    5. spec:
    6. template:
    7. spec:
    8. containers:
    9. - image: gcr.io/knative-samples/helloworld-go
    10. ports:
    11. - containerPort: 8080
    12. env:
    13. - name: TARGET
    14. value: "Knative"
    15. traffic:
    16. - latestRevision: true
    17. percent: 50
    18. - latestRevision: false
    19. percent: 50
    20. revisionName: hello-00001
  2. Apply the YAML by running the command:

    1. kubectl apply -f hello.yaml

Info

@latest will always point to our “latest” Revision which, at the moment, is hello-00002.

Verify the traffic split

To verify that the traffic split has configured correctly, list the revisions again by running the command:

  1. kn revisions list

Expected output

  1. NAME SERVICE TRAFFIC TAGS GENERATION AGE CONDITIONS READY REASON
  2. hello-00002 hello 50% 2 10m 3 OK / 4 True
  3. hello-00001 hello 50% 1 36m 3 OK / 4 True

Access your Knative Service multiple times in your browser to see the different output being served by each Revision.

Similarly, you can access the Service URL from the terminal multiple times to see the traffic being split between the Revisions.

  1. echo "Accessing URL $(kn service describe hello -o url)"
  2. curl "$(kn service describe hello -o url)"

Expected output

  1. Hello Knative!
  2. Hello World!
  3. Hello Knative!
  4. Hello World!