Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

143 lines (119 sloc) 4.74 KB

Traffic Splitting

So far, whenever we have a configuration change (code or env variables), we apply that change which in turn creates a new revision and the route is updated to direct 100% of the traffic to the new revision. This is because we've been using spec.runLatest mode in our service definition.

What if you want to control how much traffic the new revision gets? You can do that by using spec.release mode in the service definition.

Split traffic between old and new

Let's create a new revision v4 that gets only 20% of the traffic while the old revision v1 gets 80%.

Create a service-v4.yaml file that has TARGET value of C# Sample v4 and it uses release mode. Note that the revision names are not correct but we'll fix that later:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: helloworld-csharp
  namespace: default
spec:
  release:
    # Ordered list of 1 or 2 revisions. 
    # First revision is traffic target "current"
    # Second revision is traffic target "candidate"
    revisions: ["helloworld-csharp-00001", "helloworld-csharp-00004"]
    rolloutPercent: 20 # Percent [0-99] of traffic to route to "candidate" revision
    configuration:
      revisionTemplate:
        spec:
          container:
            # Replace meteatamel with your actual DockerHub
            image: docker.io/meteatamel/helloworld-csharp:v1
            env:
              - name: TARGET
                value: "C# Sample v4"

The release mode lists two fake revisions (current and candidate) and rolloutPercent defines how much traffic the candidate (in this case v4) will receive

Apply the change:

kubectl apply -f service-v4.yaml

You should first see a new revision is created for v4 (generation 4):

kubectl get revision 

NAME                      SERVICE NAME                      GENERATION
helloworld-csharp-4ht6f   helloworld-csharp-4ht6f-service   2
helloworld-csharp-8sv8s   helloworld-csharp-8sv8s-service   3
helloworld-csharp-t66v9   helloworld-csharp-t66v9-service   1
helloworld-csharp-zd5qk   helloworld-csharp-zd5qk-service   4

Now, replace the fake revision ids with the real ones for generation 1 and 4. The yaml file should look like this:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: helloworld-csharp
  namespace: default
spec:
  release:
    # Ordered list of 1 or 2 revisions. 
    # First revision is traffic target "current"
    # Second revision is traffic target "candidate"
    revisions: ["helloworld-csharp-t66v9", "helloworld-csharp-zd5qk"]
    rolloutPercent: 20 # Percent [0-99] of traffic to route to "candidate" revision
    configuration:
      revisionTemplate:
        spec:
          container:
            # Replace meteatamel with your actual DockerHub
            image: docker.io/meteatamel/helloworld-csharp:v1
            env:
              - name: TARGET
                value: "C# Sample v4"

Apply the change:

kubectl apply -f service-v4.yaml

You should see roughly 20% of the requests going to the new revision:

for i in {1..10}; do curl "http://helloworld-csharp.default.$ISTIO_INGRESS.nip.io" ; sleep 1; done

Hello C# Sample v1
Hello C# Sample v1
Hello C# Sample v1
Hello C# Sample v4

Split traffic between existing revisions

What if you want to split traffic with existing revisions? You can do that by referring to the existing revisions in the revision field.

Create a service-v5.yaml file that refers to v1 and v3 revisions that are split by 50%. Make sure you use the actual revision ids in your deployment:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: helloworld-csharp
  namespace: default
spec:
  release:
    # Ordered list of 1 or 2 revisions. 
    # First revision is traffic target "current"
    # Second revision is traffic target "candidate"
    revisions: ["helloworld-csharp-t66v9", "helloworld-csharp-8sv8s"]
    rolloutPercent: 50 # Percent [0-99] of traffic to route to "candidate" revision
    configuration:
      revisionTemplate:
        spec:
          container:
            # Replace meteatamel with your actual DockerHub
            image: docker.io/meteatamel/helloworld-csharp:v1
            env:
              - name: TARGET
                value: "C# Sample v4"

Apply the change:

kubectl apply -f service-v5.yaml

You should see roughly 50% of the requests split between revisions:

for i in {1..10}; do curl "http://helloworld-csharp.default.$ISTIO_INGRESS.nip.io" ; sleep 1; done
Hello C# Sample v1
Bye C# Sample v3
Hello C# Sample v1
Bye C# Sample v3

What's Next?

Configure autoscaling

You can’t perform that action at this time.