Weight traffic to specific backends
Create an HTTPRoute
resource, and specify a weight
property under spec.rules[*].backendRefs[*].weight
to route traffic to specific backends.
Prerequisites
Kong Konnect
If you don’t have a Konnect account, you can get started quickly with our onboarding wizard.
- The following Konnect items are required to complete this tutorial:
- Personal access token (PAT): Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.
-
Set the personal access token as an environment variable:
export KONNECT_TOKEN='YOUR KONNECT TOKEN'
Enable the Gateway API
-
Install the Gateway API CRDs before installing Kong Ingress Controller.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml
-
Create a
Gateway
andGatewayClass
instance to use.
echo "
apiVersion: v1
kind: Namespace
metadata:
name: kong
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong
annotations:
konghq.com/gatewayclass-unmanaged: 'true'
spec:
controllerName: konghq.com/kic-gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong
spec:
gatewayClassName: kong
listeners:
- name: proxy
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
" | kubectl apply -n kong -f -
Create a KIC Control Plane
Use the Konnect API to create a new CLUSTER_TYPE_K8S_INGRESS_CONTROLLER
Control Plane:
CONTROL_PLANE_DETAILS=$(curl -X POST "https://us.api.konghq.com/v2/control-planes" \
-H "Authorization: Bearer $KONNECT_TOKEN" \
--json '{
"name": "My KIC CP",
"cluster_type": "CLUSTER_TYPE_K8S_INGRESS_CONTROLLER"
}')
We’ll need the id
and telemetry_endpoint
for the values.yaml
file later. Save them as environment variables:
CONTROL_PLANE_ID=$(echo $CONTROL_PLANE_DETAILS | jq -r .id)
CONTROL_PLANE_TELEMETRY=$(echo $CONTROL_PLANE_DETAILS | jq -r '.config.telemetry_endpoint | sub("https://";"")')
Create mTLS certificates
Kong Ingress Controller talks to Konnect over a connected secured with TLS certificates.
Generate a new certificate using openssl
:
openssl req -new -x509 -nodes -newkey rsa:2048 -subj "/CN=kongdp/C=US" -keyout ./tls.key -out ./tls.crt
The certificate needs to be a single line string to send it to the Konnect API with curl. Use awk
to format the certificate:
export CERT=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' tls.crt);
Next, upload the certificate to Konnect:
curl -X POST "https://us.api.konghq.com/v2/control-planes/$CONTROL_PLANE_ID/dp-client-certificates" \
-H "Authorization: Bearer $KONNECT_TOKEN" \
--json '{
"cert": "'$CERT'"
}'
Finally, store the certificate in a Kubernetes secret so that Kong Ingress Controller can read it:
kubectl create namespace kong -o yaml --dry-run=client | kubectl apply -f -
kubectl create secret tls konnect-client-tls -n kong --cert=./tls.crt --key=./tls.key
Kong Ingress Controller running
-
Add the Kong Helm charts:
helm repo add kong https://charts.konghq.com helm repo update
-
Install Kong Ingress Controller using Helm:
helm install kong kong/ingress -n kong --create-namespace
-
Set
$PROXY_IP
as an environment variable for future commands:export PROXY_IP=$(kubectl get svc --namespace kong kong-gateway-proxy -o jsonpath='{range .status.loadBalancer.ingress[0]}{@.ip}{@.hostname}{end}') echo $PROXY_IP
Deploy demo Services
This how-to deploys multiple Services to your Kubernetes cluster to simulate a production environment.
Deploy the Services and create routing resources:
kubectl apply -f https://developer.konghq.com/manifests/kic/echo-services.yaml -n kong
Create an HTTPRoute
To route HTTP traffic, create an HTTPRoute
resource pointing at your Kubernetes Service
:
echo 'apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: echo
namespace: kong
annotations:
konghq.com/strip-path: "true"
spec:
parentRefs:
- name: kong
rules:
- matches:
- path:
type: PathPrefix
value: /echo
backendRefs:
- name: echo
kind: Service
port: 80
- name: echo2
kind: Service
port: 80
' | kubectl apply -f -
Test your deployment
Send multiple requests through this Route and tabulate the results to check an even distribution of requests across the Services:
curl -s "$PROXY_IP/echo/hostname?iteration="{1..200} -w "\n" | sort | uniq -c
The results should look like this:
100 echo2-7cb798f47-gv6hs
100 echo-658c5ff5ff-tv275
Add Service weights
The weight
field overrides the default distribution of requests across Services. Each Service instead receives weight / sum(all Service weights)
percent of the requests.
-
Add weights to the Services in the HTTPRoute’s backend list:
kubectl patch -n kong --type json httproute echo -p='[ { "op":"add", "path":"/spec/rules/0/backendRefs/0/weight", "value":200 }, { "op":"add", "path":"/spec/rules/0/backendRefs/1/weight", "value":100 } ]'
-
Send the same requests again. This time, roughly 1/3 of the requests go to
echo2
and 2/3 go toecho
:curl -s "$PROXY_IP/echo/hostname?iteration="{1..200} -w "\n" | sort | uniq -c
The results should look like this:
133 echo-658c5ff5ff-tv275 67 echo2-7cb798f47-gv6hs
Cleanup
Uninstall KIC from your cluster
helm uninstall kong -n kong