Skip to content
Kong Docs are moving soon! Our docs are migrating to a new home. You'll be automatically redirected to the new site in the future. In the meantime, view this page on the new site!
Kong Logo | Kong Docs Logo
  • Docs
    • Explore the API Specs
      View all API Specs View all API Specs View all API Specs arrow image
    • Documentation
      API Specs
      Kong Gateway
      Lightweight, fast, and flexible cloud-native API gateway
      Kong Konnect
      Single platform for SaaS end-to-end connectivity
      Kong AI Gateway
      Multi-LLM AI Gateway for GenAI infrastructure
      Kong Mesh
      Enterprise service mesh based on Kuma and Envoy
      decK
      Helps manage Kong’s configuration in a declarative fashion
      Kong Ingress Controller
      Works inside a Kubernetes cluster and configures Kong to proxy traffic
      Kong Gateway Operator
      Manage your Kong deployments on Kubernetes using YAML Manifests
      Insomnia
      Collaborative API development platform
  • Plugin Hub
    • Explore the Plugin Hub
      View all plugins View all plugins View all plugins arrow image
    • Functionality View all View all arrow image
      View all plugins
      AI's icon
      AI
      Govern, secure, and control AI traffic with multi-LLM AI Gateway plugins
      Authentication's icon
      Authentication
      Protect your services with an authentication layer
      Security's icon
      Security
      Protect your services with additional security layer
      Traffic Control's icon
      Traffic Control
      Manage, throttle and restrict inbound and outbound API traffic
      Serverless's icon
      Serverless
      Invoke serverless functions in combination with other plugins
      Analytics & Monitoring's icon
      Analytics & Monitoring
      Visualize, inspect and monitor APIs and microservices traffic
      Transformations's icon
      Transformations
      Transform request and responses on the fly on Kong
      Logging's icon
      Logging
      Log request and response data using the best transport for your infrastructure
  • Support
  • Community
  • Kong Academy
Get a Demo Start Free Trial
Kong Ingress Controller
3.4.x (latest) LTS
  • Home icon
  • Kong Ingress Controller
  • Guides
  • Requests
  • Customizing load-balancing behavior with KongUpstreamPolicy
github-edit-pageEdit this page
report-issueReport an issue
  • Kong Gateway
  • Kong Konnect
  • Kong Mesh
  • Kong AI Gateway
  • Plugin Hub
  • decK
  • Kong Ingress Controller
  • Kong Gateway Operator
  • Insomnia
  • Kuma

  • Docs contribution guidelines
  • unreleased
  • 3.4.x (latest) (LTS)
  • 3.3.x
  • 3.2.x
  • 3.1.x
  • 3.0.x
  • 2.12.x (LTS)
  • 2.11.x
  • 2.10.x
  • 2.9.x
  • 2.8.x
  • 2.7.x
  • 2.6.x
  • 2.5.x (LTS)
  • Introduction
    • Overview
    • Kubernetes Gateway API
    • Version Support Policy
    • Changelog
  • How KIC Works
    • Architecture
    • Gateway API
    • Ingress
    • Custom Resources
    • Using Annotations
    • Admission Webhook
  • Get Started
    • Install KIC
    • Services and Routes
    • Rate Limiting
    • Proxy Caching
    • Key Authentication
  • KIC in Production
    • Deployment Topologies
      • Overview
      • Gateway Discovery
      • Database Backed
      • Traditional (sidecar)
    • Installation Methods
      • Helm
      • Kong Gateway Operator
    • Cloud Deployment
      • Azure
      • Amazon
      • Google
    • Enterprise License
    • Observability
      • Prometheus Metrics
      • Configuring Prometheus and Grafana
      • Kubernetes Events
    • Upgrading
      • Kong Gateway
      • Ingress Controller
  • Guides
    • Service Configuration
      • HTTP Service
      • TCP Service
      • UDP Service
      • gRPC Service
      • TLS
      • External Service
      • HTTPS Redirects
      • Multiple Backend Services
      • Configuring Gateway API resources across namespaces
      • Configuring Custom Kong Entities
    • Request Manipulation
      • Rewriting Hosts and Paths
      • Rewrite Annotation
      • Customizing load-balancing behavior
    • High Availability
      • KIC High Availability
      • Service Health Checks
      • Last Known Good Config
      • Fallback Configuration
    • Security
      • Kong Vaults
      • Using Workspaces
      • Preserving Client IP
      • Kubernetes Secrets in Plugins
      • Verifying Upstream TLS
    • Migrate
      • KongIngress to KongUpstreamPolicy
      • Migrating from Ingress to Gateway
      • Credential Type Labels
    • Customize Deployments
      • Images
    • Custom Ingress Class
      • Internal / External Traffic
  • Plugins
    • Custom Plugins
    • Authentication
    • ACL
    • Rate Limiting
    • mTLS
    • OIDC
  • Reference
    • Troubleshooting
    • Version Compatibility
    • Annotations
    • Configuration Options
    • Feature Gates
    • FAQ
      • Plugin Compatibility
      • Kong Router
      • Custom nginx.conf
    • Custom Resource Definitions
    • Resources Requiring Setting Ingress Class
    • Gateway API migration
    • Required Permissions for Installation
    • Categories of Failures
    • Combining Services From Different HTTPRoutes
enterprise-switcher-icon Switch to OSS
On this pageOn this page
  • Prerequisites
    • Install the Gateway APIs
    • Install Kong
    • Test connectivity to Kong
  • Deploy an echo service
    • Deploy additional echo replicas
  • Add routing configuration
  • Use KongUpstreamPolicy with a Service resource

Customizing load-balancing behavior with KongUpstreamPolicy

In this guide, we will learn how to use KongUpstreamPolicy resource to control proxy load-balancing behavior.

Prerequisites: Install Kong Ingress Controller with Gateway API support in your Kubernetes cluster and connect to Kong.

Prerequisites

Install the Gateway APIs

  1. Install the Gateway API CRDs before installing Kong Ingress Controller.

     kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
    
  2. Create a Gateway and GatewayClass instance to use.

    echo "
    ---
    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 -f -
    

    The results should look like this:

    gatewayclass.gateway.networking.k8s.io/kong created
    gateway.gateway.networking.k8s.io/kong created
    

Install Kong

You can install Kong in your Kubernetes cluster using Helm.

  1. Add the Kong Helm charts:

     helm repo add kong https://charts.konghq.com
     helm repo update
    
  2. Install Kong Ingress Controller and Kong Gateway with Helm:

     helm install kong kong/ingress -n kong --create-namespace 
    

Test connectivity to Kong

Kubernetes exposes the proxy through a Kubernetes service. Run the following commands to store the load balancer IP address in a variable named PROXY_IP:

  1. Populate $PROXY_IP for future commands:

     export PROXY_IP=$(kubectl get svc --namespace kong kong-gateway-proxy -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
     echo $PROXY_IP
    
  2. Ensure that you can call the proxy IP:

     curl -i $PROXY_IP
    

    The results should look like this:

     HTTP/1.1 404 Not Found
     Content-Type: application/json; charset=utf-8
     Connection: keep-alive
     Content-Length: 48
     X-Kong-Response-Latency: 0
     Server: kong/3.0.0
      
     {"message":"no Route matched with those values"}
    

Deploy an echo service

To proxy requests, you need an upstream application to send a request to. Deploying this echo server provides a simple application that returns information about the Pod it’s running in:

kubectl apply -f https://docs.konghq.com/assets/kubernetes-ingress-controller/examples/echo-service.yaml

The results should look like this:

service/echo created
deployment.apps/echo created

Deploy additional echo replicas

To demonstrate Kong’s load balancing functionality we need multiple echo Pods. Scale out the echo deployment.

kubectl scale --replicas 2 deployment echo

Add routing configuration

Create routing configuration to proxy /echo requests to the echo server:

Gateway API
Ingress
echo "
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: echo
  annotations:
    konghq.com/strip-path: 'true'
spec:
  parentRefs:
  - name: kong
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /echo
    backendRefs:
    - name: echo
      kind: Service
      port: 1027
" | kubectl apply -f -
echo "
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo
  annotations:
    konghq.com/strip-path: 'true'
spec:
  ingressClassName: kong
  rules:
  - http:
      paths:
      - path: /echo
        pathType: ImplementationSpecific
        backend:
          service:
            name: echo
            port:
              number: 1027
" | kubectl apply -f -

The results should look like this:

Gateway API
Ingress
httproute.gateway.networking.k8s.io/echo created
ingress.networking.k8s.io/echo created

Test the routing rule:

curl -i $PROXY_IP/echo

The results should look like this:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 140
Connection: keep-alive
Date: Fri, 21 Apr 2023 12:24:55 GMT
X-Kong-Upstream-Latency: 0
X-Kong-Proxy-Latency: 1
Via: kong/3.2.2

Welcome, you are connected to node docker-desktop.
Running on Pod echo-7f87468b8c-tzzv6.
In namespace default.
With IP address 10.1.0.237.
...

If everything is deployed correctly, you should see the above response. This verifies that Kong Gateway can correctly route traffic to an application running inside Kubernetes.

Use KongUpstreamPolicy with a Service resource

By default, Kong will round-robin requests between upstream replicas. If you run curl -s $PROXY_IP/echo | grep "Pod" repeatedly, you should see the reported Pod name alternate between two values.

You can configure the Kong upstream associated with the Service to use a different load balancing strategy, such as consistently sending requests to the same upstream based on a header value (please see the KongUpstreamPolicy reference for the full list of supported algorithms and their configuration options).

To modify these behaviours, let’s first create a KongUpstreamPolicy resource defining the new behaviour:

Command
Response
echo '
apiVersion: configuration.konghq.com/v1beta1
kind: KongUpstreamPolicy
metadata:
  name: sample-customization
spec:
  algorithm: consistent-hashing
  hashOn:
    header: x-lb
  hashOnFallback:
    input: ip
  ' | kubectl apply -f -
kongupstreampolicy.configuration.konghq.com/test created

Now, let’s associate this KongUpstreamPolicy resource with our Service resource using the konghq.com/upstream-policy annotation.

Command
Response
kubectl patch service echo -p '{"metadata":{"annotations":{"konghq.com/upstream-policy":"sample-customization"}}}'
service/echo patched

With consistent hashing and client IP fallback, sending repeated requests without any x-lb header now sends them to the same Pod:

Command
Response
for n in {1..5}; do curl -s $PROXY_IP/echo | grep "Pod"; done
Running on Pod echo-965f7cf84-frpjc.
Running on Pod echo-965f7cf84-frpjc.
Running on Pod echo-965f7cf84-frpjc.
Running on Pod echo-965f7cf84-frpjc.
Running on Pod echo-965f7cf84-frpjc.

If you add the header, Kong hashes its value and distributes it to the same replica when using the same value:

Command
Response
for n in {1..3}; do
  curl -s $PROXY_IP/echo -H "x-lb: foo" | grep "Pod";
  curl -s $PROXY_IP/echo -H "x-lb: bar" | grep "Pod";
  curl -s $PROXY_IP/echo -H "x-lb: baz" | grep "Pod";
done
Running on Pod echo-965f7cf84-wlvw9.
Running on Pod echo-965f7cf84-frpjc.
Running on Pod echo-965f7cf84-wlvw9.
Running on Pod echo-965f7cf84-wlvw9.
Running on Pod echo-965f7cf84-frpjc.
Running on Pod echo-965f7cf84-wlvw9.
Running on Pod echo-965f7cf84-wlvw9.
Running on Pod echo-965f7cf84-frpjc.
Running on Pod echo-965f7cf84-wlvw9.

Increasing the replicas redistributes some subsequent requests onto the new replica:

Command
Response
kubectl scale --replicas 3 deployment echo
deployment.apps/echo patched
Command
Response
for n in {1..3}; do
  curl -s $PROXY_IP/echo -H "x-lb: foo" | grep "Pod";
  curl -s $PROXY_IP/echo -H "x-lb: bar" | grep "Pod";
  curl -s $PROXY_IP/echo -H "x-lb: baz" | grep "Pod";
done
Running on Pod echo-965f7cf84-5h56p.
Running on Pod echo-965f7cf84-5h56p.
Running on Pod echo-965f7cf84-wlvw9.
Running on Pod echo-965f7cf84-5h56p.
Running on Pod echo-965f7cf84-5h56p.
Running on Pod echo-965f7cf84-wlvw9.
Running on Pod echo-965f7cf84-5h56p.
Running on Pod echo-965f7cf84-5h56p.
Running on Pod echo-965f7cf84-wlvw9.

Kong’s load balancer doesn’t directly distribute requests to each of the Service’s Endpoints. It first distributes them evenly across a number of equal-size buckets. These buckets are then distributed across the available Endpoints according to their weight. For Ingresses, however, there is only one Service, and the controller assigns each Endpoint (represented by a Kong upstream target) equal weight. In this case, requests are evenly hashed across all Endpoints.

Gateway API HTTPRoute rules support distributing traffic across multiple Services. The rule can assign weights to the Services to change the proportion of requests an individual Service receives. In Kong’s implementation, all Endpoints of a Service have the same weight. Kong calculates a per-Endpoint upstream target weight such that the aggregate target weight of the Endpoints is equal to the proportion indicated by the HTTPRoute weight.

For example, say you have two Services with the following configuration:

  • One Service has four Endpoints
  • The other Service has two Endpoints
  • Each Service has weight 50 in the HTTPRoute

The targets created for the two-Endpoint Service have double the weight of the targets created for the four-Endpoint Service (two weight 16 targets and four weight 8 targets). Scaling the four-Endpoint Service to eight would halve the weight of its targets (two weight 16 targets and eight weight 4 targets).

KongUpstreamPolicy can also configure upstream health checking behavior as well. See the KongUpstreamPolicy reference for the health check fields.

Thank you for your feedback.
Was this page useful?
Too much on your plate? close cta icon
More features, less infrastructure with Kong Konnect. 1M requests per month for free.
Try it for Free
  • Kong
    Powering the API world

    Increase developer productivity, security, and performance at scale with the unified platform for API management, service mesh, and ingress controller.

    • Products
      • Kong Konnect
      • Kong Gateway Enterprise
      • Kong Gateway
      • Kong Mesh
      • Kong Ingress Controller
      • Kong Insomnia
      • Product Updates
      • Get Started
    • Documentation
      • Kong Konnect Docs
      • Kong Gateway Docs
      • Kong Mesh Docs
      • Kong Insomnia Docs
      • Kong Konnect Plugin Hub
    • Open Source
      • Kong Gateway
      • Kuma
      • Insomnia
      • Kong Community
    • Company
      • About Kong
      • Customers
      • Careers
      • Press
      • Events
      • Contact
  • Terms• Privacy• Trust and Compliance
© Kong Inc. 2025