Chapter 8. Traffic splitting 8.1. Traffic splitting overview In a Knative application, traffic can be managed by creating a traffic split. A traffic split is configured as part of a route, which is managed by a Knative service. Configuring a route allows requests to be sent to different revisions of a service. This routing is determined by the traffic spec of the Service object. A traffic spec declaration consists of one or more revisions, each responsible for handling a portion of the overall traffic. The percentages of traffic routed to each revision must add up to 100%, which is ensured by a Knative validation. The revisions specified in a traffic spec can either be a fixed, named revision, or can point to the "latest" revision, which tracks the head of the list of all revisions for the service. The "latest" revision is a type of floating reference that updates if a new revision is created. Each revision can have a tag attached that creates an additional access URL for that revision. The traffic spec can be modified by: Editing the YAML of a Service object directly. Using the Knative ( kn ) CLI --traffic flag. Using the OpenShift Container Platform web console. When you create a Knative service, it does not have any default traffic spec settings. 8.2. Traffic spec examples The following example shows a traffic spec where 100% of traffic is routed to the latest revision of the service. Under status , you can see the name of the latest revision that latestRevision resolves to: apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: ... traffic: - latestRevision: true percent: 100 status: ... traffic: - percent: 100 revisionName: example-service The following example shows a traffic spec where 100% of traffic is routed to the revision tagged as current , and the name of that revision is specified as example-service . The revision tagged as latest is kept available, even though no traffic is routed to it: apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: ... traffic: - tag: current revisionName: example-service percent: 100 - tag: latest latestRevision: true percent: 0 The following example shows how the list of revisions in the traffic spec can be extended so that traffic is split between multiple revisions. This example sends 50% of traffic to the revision tagged as current , and 50% of traffic to the revision tagged as candidate . The revision tagged as latest is kept available, even though no traffic is routed to it: apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: ... traffic: - tag: current revisionName: example-service-1 percent: 50 - tag: candidate revisionName: example-service-2 percent: 50 - tag: latest latestRevision: true percent: 0 8.3. Traffic splitting using the Knative CLI Using the Knative ( kn ) CLI to create traffic splits provides a more streamlined and intuitive user interface over modifying YAML files directly. You can use the kn service update command to split traffic between revisions of a service. 8.3.1. Creating a traffic split by using the Knative CLI Prerequisites The OpenShift Serverless Operator and Knative Serving are installed on your cluster. You have installed the Knative ( kn ) CLI. You have created a Knative service. Procedure Specify the revision of your service and what percentage of traffic you want to route to it by using the --traffic tag with a standard kn service update command: Example command USD kn service update <service_name> --traffic <revision>=<percentage> Where: <service_name> is the name of the Knative service that you are configuring traffic routing for. <revision> is the revision that you want to configure to receive a percentage of traffic. You can either specify the name of the revision, or a tag that you assigned to the revision by using the --tag flag. <percentage> is the percentage of traffic that you want to send to the specified revision. Optional: The --traffic flag can be specified multiple times in one command. For example, if you have a revision tagged as @latest and a revision named stable , you can specify the percentage of traffic that you want to split to each revision as follows: Example command USD kn service update showcase --traffic @latest=20,stable=80 If you have multiple revisions and do not specify the percentage of traffic that should be split to the last revision, the --traffic flag can calculate this automatically. For example, if you have a third revision named example , and you use the following command: Example command USD kn service update showcase --traffic @latest=10,stable=60 The remaining 30% of traffic is split to the example revision, even though it was not specified. 8.4. CLI flags for traffic splitting The Knative ( kn ) CLI supports traffic operations on the traffic block of a service as part of the kn service update command. 8.4.1. Knative CLI traffic splitting flags The following table displays a summary of traffic splitting flags, value formats, and the operation the flag performs. The Repetition column denotes whether repeating the particular value of flag is allowed in a kn service update command. Flag Value(s) Operation Repetition --traffic RevisionName=Percent Gives Percent traffic to RevisionName Yes --traffic Tag=Percent Gives Percent traffic to the revision having Tag Yes --traffic @latest=Percent Gives Percent traffic to the latest ready revision No --tag RevisionName=Tag Gives Tag to RevisionName Yes --tag @latest=Tag Gives Tag to the latest ready revision No --untag Tag Removes Tag from revision Yes 8.4.1.1. Multiple flags and order precedence All traffic-related flags can be specified using a single kn service update command. kn defines the precedence of these flags. The order of the flags specified when using the command is not taken into account. The precedence of the flags as they are evaluated by kn are: --untag : All the referenced revisions with this flag are removed from the traffic block. --tag : Revisions are tagged as specified in the traffic block. --traffic : The referenced revisions are assigned a portion of the traffic split. You can add tags to revisions and then split traffic according to the tags you have set. 8.4.1.2. Custom URLs for revisions Assigning a --tag flag to a service by using the kn service update command creates a custom URL for the revision that is created when you update the service. The custom URL follows the pattern https://<tag>-<service_name>-<namespace>.<domain> or http://<tag>-<service_name>-<namespace>.<domain> . The --tag and --untag flags use the following syntax: Require one value. Denote a unique tag in the traffic block of the service. Can be specified multiple times in one command. 8.4.1.2.1. Example: Assign a tag to a revision The following example assigns the tag latest to a revision named example-revision : USD kn service update <service_name> --tag @latest=example-tag 8.4.1.2.2. Example: Remove a tag from a revision You can remove a tag to remove the custom URL, by using the --untag flag. Note If a revision has its tags removed, and it is assigned 0% of the traffic, the revision is removed from the traffic block entirely. The following command removes all tags from the revision named example-revision : USD kn service update <service_name> --untag example-tag 8.5. Splitting traffic between revisions After you create a serverless application, the application is displayed in the Topology view of the Developer perspective in the OpenShift Container Platform web console. The application revision is represented by the node, and the Knative service is indicated by a quadrilateral around the node. Any new change in the code or the service configuration creates a new revision, which is a snapshot of the code at a given time. For a service, you can manage the traffic between the revisions of the service by splitting and routing it to the different revisions as required. 8.5.1. Managing traffic between revisions by using the OpenShift Container Platform web console Prerequisites The OpenShift Serverless Operator and Knative Serving are installed on your cluster. You have logged in to the OpenShift Container Platform web console. Procedure To split traffic between multiple revisions of an application in the Topology view: Click the Knative service to see its overview in the side panel. Click the Resources tab, to see a list of Revisions and Routes for the service. Figure 8.1. Serverless application Click the service, indicated by the S icon at the top of the side panel, to see an overview of the service details. Click the YAML tab and modify the service configuration in the YAML editor, and click Save . For example, change the timeoutseconds from 300 to 301 . This change in the configuration triggers a new revision. In the Topology view, the latest revision is displayed and the Resources tab for the service now displays the two revisions. In the Resources tab, click Set Traffic Distribution to see the traffic distribution dialog box: Add the split traffic percentage portion for the two revisions in the Splits field. Add tags to create custom URLs for the two revisions. Click Save to see two nodes representing the two revisions in the Topology view. Figure 8.2. Serverless application revisions 8.6. Rerouting traffic using blue-green strategy You can safely reroute traffic from a production version of an app to a new version, by using a blue-green deployment strategy . 8.6.1. Routing and managing traffic by using a blue-green deployment strategy Prerequisites The OpenShift Serverless Operator and Knative Serving are installed on the cluster. Install the OpenShift CLI ( oc ). Procedure Create and deploy an app as a Knative service. Find the name of the first revision that was created when you deployed the service, by viewing the output from the following command: USD oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}' Example command USD oc get ksvc showcase -o=jsonpath='{.status.latestCreatedRevisionName}' Example output USD showcase-00001 Add the following YAML to the service spec to send inbound traffic to the revision: ... spec: traffic: - revisionName: <first_revision_name> percent: 100 # All traffic goes to this revision ... Verify that you can view your app at the URL output you get from running the following command: USD oc get ksvc <service_name> Deploy a second revision of your app by modifying at least one field in the template spec of the service and redeploying it. For example, you can modify the image of the service, or an env environment variable. You can redeploy the service by applying the service YAML file, or by using the kn service update command if you have installed the Knative ( kn ) CLI. Find the name of the second, latest revision that was created when you redeployed the service, by running the command: USD oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}' At this point, both the first and second revisions of the service are deployed and running. Update your existing service to create a new, test endpoint for the second revision, while still sending all other traffic to the first revision: Example of updated service spec with test endpoint ... spec: traffic: - revisionName: <first_revision_name> percent: 100 # All traffic is still being routed to the first revision - revisionName: <second_revision_name> percent: 0 # No traffic is routed to the second revision tag: v2 # A named route ... After you redeploy this service by reapplying the YAML resource, the second revision of the app is now staged. No traffic is routed to the second revision at the main URL, and Knative creates a new service named v2 for testing the newly deployed revision. Get the URL of the new service for the second revision, by running the following command: USD oc get ksvc <service_name> --output jsonpath="{.status.traffic[*].url}" You can use this URL to validate that the new version of the app is behaving as expected before you route any traffic to it. Update your existing service again, so that 50% of traffic is sent to the first revision, and 50% is sent to the second revision: Example of updated service spec splitting traffic 50/50 between revisions ... spec: traffic: - revisionName: <first_revision_name> percent: 50 - revisionName: <second_revision_name> percent: 50 tag: v2 ... When you are ready to route all traffic to the new version of the app, update the service again to send 100% of traffic to the second revision: Example of updated service spec sending all traffic to the second revision ... spec: traffic: - revisionName: <first_revision_name> percent: 0 - revisionName: <second_revision_name> percent: 100 tag: v2 ... Tip You can remove the first revision instead of setting it to 0% of traffic if you do not plan to roll back the revision. Non-routeable revision objects are then garbage-collected. Visit the URL of the first revision to verify that no more traffic is being sent to the old version of the app.

Commands:
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: traffic: - latestRevision: true percent: 100 status: traffic: - percent: 100 revisionName: example-service
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: traffic: - tag: current revisionName: example-service percent: 100 - tag: latest latestRevision: true percent: 0
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: example-service namespace: default spec: traffic: - tag: current revisionName: example-service-1 percent: 50 - tag: candidate revisionName: example-service-2 percent: 50 - tag: latest latestRevision: true percent: 0
kn service update <service_name> --traffic <revision>=<percentage>
kn service update showcase --traffic @latest=20,stable=80
kn service update showcase --traffic @latest=10,stable=60
kn service update <service_name> --tag @latest=example-tag
kn service update <service_name> --untag example-tag
oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}'
oc get ksvc showcase -o=jsonpath='{.status.latestCreatedRevisionName}'
showcase-00001
spec: traffic: - revisionName: <first_revision_name> percent: 100 # All traffic goes to this revision
oc get ksvc <service_name>
oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}'
spec: traffic: - revisionName: <first_revision_name> percent: 100 # All traffic is still being routed to the first revision - revisionName: <second_revision_name> percent: 0 # No traffic is routed to the second revision tag: v2 # A named route
oc get ksvc <service_name> --output jsonpath="{.status.traffic[*].url}"
spec: traffic: - revisionName: <first_revision_name> percent: 50 - revisionName: <second_revision_name> percent: 50 tag: v2
spec: traffic: - revisionName: <first_revision_name> percent: 0 - revisionName: <second_revision_name> percent: 100 tag: v2