Cloud Native 15 min read

Master Traffic Splitting and Version Control in Knative Serving

This guide walks through building a Go REST‑API, containerizing it, deploying multiple Knative Service revisions, configuring traffic percentages for gray releases, validating revisions before traffic shift, and rolling back, while comparing Knative’s traffic‑driven model to traditional pod‑based deployments.

Alibaba Cloud Native
Alibaba Cloud Native
Alibaba Cloud Native
Master Traffic Splitting and Version Control in Knative Serving

This article explains how to use Knative Serving to perform traffic‑splitting (gray release) and version management with a simple Go rest‑api example that distinguishes revisions via the RESOURCE environment variable.

Go application source

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "os"
    "flag"
)

var resource string

func main() {
    flag.Parse()
    resource = os.Getenv("RESOURCE")
    if resource == "" {
        resource = "NOT SPECIFIED"
    }
    root := "/" + resource
    path := root + "/{stockId}"
    http.HandleFunc("/", Index)
    http.HandleFunc(root, StockIndex)
    http.HandleFunc(path, StockPrice)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatalf("ListenAndServe error:%s ", err.Error())
    }
}

func Index(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Welcome to the %s app! 
", resource)
}

func StockIndex(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s ticker not found!, require /%s/{ticker}
", resource, resource)
}

func StockPrice(w http.ResponseWriter, r *http.Request) {
    stockId := r.URL.Query().Get("stockId")
    u := url.URL{Scheme: "https", Host: "api.iextrading.com", Path: "/1.0/stock/" + stockId + "/price"}
    log.Print(u)
    resp, err := http.Get(u.String())
    if err != nil {
        fmt.Fprintf(w, "%s not found for ticker : %s 
", resource, stockId)
        return
    }
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Fprintf(w, "%s price for ticker %s is %s
", resource, stockId, string(body))
}

Docker image

Create a Dockerfile that builds the binary in a Golang 1.12 builder stage and copies it into an Alpine‑sh runtime image, then push the image to your registry.

FROM registry.cn-hangzhou.aliyuncs.com/knative-sample/golang:1.12 as builder
WORKDIR /go/src/github.com/knative-sample/rest-api-go
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -v -o rest-api-go

FROM registry.cn-hangzhou.aliyuncs.com/knative-sample/alpine-sh:3.9
COPY --from=builder /go/src/github.com/knative-sample/rest-api-go/rest-api-go /rest-api-go
CMD ["/rest-api-go"]

Deploy revision v1

Save the following Service definition as revision-v1.yaml and apply it:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: stock-service-example
  namespace: default
spec:
  template:
    metadata:
      name: stock-service-example-v1
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/rest-api-go:v1
        env:
        - name: RESOURCE
          value: v1
        readinessProbe:
          httpGet:
            path: /
          initialDelaySeconds: 0
          periodSeconds: 3

Running kubectl apply -f revision-v1.yaml creates the Revision stock-service-example-v1 and routes 100 % of traffic to it.

Verify Knative resources

kubectl get ksvc stock-service-example -o yaml
kubectl get configuration -l "serving.knative.dev/service=stock-service-example" -o yaml
kubectl get revision -l "serving.knative.dev/service=stock-service-example" -o yaml
kubectl get route -l "serving.knative.dev/service=stock-service-example" -o yaml

Test the service

Create run-test.sh to discover the Istio Ingress IP and the Service domain, then curl with the proper Host header:

#!/bin/bash
SVC_NAME="stock-service-example"
export INGRESSGATEWAY=istio-ingressgateway
export GATEWAY_IP=$(kubectl get svc $INGRESSGATEWAY --namespace istio-system -o jsonpath="{.status.loadBalancer.ingress[*]['ip']}")
export DOMAIN_NAME=$(kubectl get route $SVC_NAME -o jsonpath="{.status.url}" | awk -F/ '{print $3}')
curl -H "Host: ${DOMAIN_NAME}" http://${GATEWAY_IP}

Output shows Welcome to the v1 app!, confirming the deployment.

Deploy revision v2 with 50 % traffic

Save the following as revision-v2.yaml and apply:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: stock-service-example
  namespace: default
spec:
  template:
    metadata:
      name: stock-service-example-v2
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/rest-api-go:v1
        env:
        - name: RESOURCE
          value: v2
        readinessProbe:
          httpGet:
            path: /
          initialDelaySeconds: 0
          periodSeconds: 3
  traffic:
  - tag: v1
    revisionName: stock-service-example-v1
    percent: 50
  - tag: v2
    revisionName: stock-service-example-v2
    percent: 50
  - tag: latest
    latestRevision: true
    percent: 0

After kubectl apply -f revision-v2.yaml, running the test script repeatedly yields alternating v1 and v2 responses, confirming the 50 % split.

Pre‑validation with a third revision

Create revision-v3.yaml (no traffic assigned) to verify the new version before exposing it:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: stock-service-example
  namespace: default
spec:
  template:
    metadata:
      name: stock-service-example-v3
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/rest-api-go:v1
        env:
        - name: RESOURCE
          value: v3
        readinessProbe:
          httpGet:
            path: /
          initialDelaySeconds: 0
          periodSeconds: 3

Apply it with kubectl apply -f revision-v3.yaml. The Revision appears in kubectl get revision but receives no traffic.

Shift traffic to v3

Update the Service to allocate traffic among v1, v2 and v3 (40 % / 30 % / 30 %) in revision-v3-2.yaml:

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  name: stock-service-example
  namespace: default
spec:
  template:
    metadata:
      name: stock-service-example-v3
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/rest-api-go:v1
        env:
        - name: RESOURCE
          value: v3
        readinessProbe:
          httpGet:
            path: /
          initialDelaySeconds: 0
          periodSeconds: 3
  traffic:
  - tag: v1
    revisionName: stock-service-example-v1
    percent: 40
  - tag: v2
    revisionName: stock-service-example-v2
    percent: 30
  - tag: v3
    revisionName: stock-service-example-v3
    percent: 30
  - tag: latest
    latestRevision: true
    percent: 0

After applying, the test script shows a distribution roughly 4:3:3 among the three versions.

Rollback

Revisions are immutable; to roll back, simply adjust the traffic block to point 100 % (or any desired percentage) to a previous revision.

Comparison with traditional pod‑based gray releases

In classic Kubernetes deployments, gray releases are achieved by manually scaling Pods of each version, which does not guarantee that traffic proportion matches pod proportion. Knative Serving automatically creates Pods based on incoming traffic, allowing precise traffic‑percentage control without pre‑defining replica counts.

Conclusion

Knative Serving’s traffic‑centric model enables fine‑grained gray releases, safe pre‑validation of new revisions, and effortless rollbacks, distinguishing it from traditional pod‑count‑driven approaches.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DockerKubernetesGoBlue‑Green deploymenttraffic splittingKnativeServing
Alibaba Cloud Native
Written by

Alibaba Cloud Native

We publish cloud-native tech news, curate in-depth content, host regular events and live streams, and share Alibaba product and user case studies. Join us to explore and share the cloud-native insights you need.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.