diff --git a/app/_how-tos/operator/operator-dataplane-service-host-header.md b/app/_how-tos/operator/operator-dataplane-service-host-header.md new file mode 100644 index 0000000000..56c034ac72 --- /dev/null +++ b/app/_how-tos/operator/operator-dataplane-service-host-header.md @@ -0,0 +1,104 @@ +--- +title: Set the Host header sent to a Service +description: "Learn how to override the Host header that {{ site.base_gateway }} sends to upstream services using the konghq.com/host-header annotation." +content_type: how_to + +permalink: /operator/dataplanes/how-to/set-host-header/ +breadcrumbs: + - /operator/ + - index: operator + group: Gateway Deployment + - index: operator + group: Gateway Deployment + section: "How-To" + +products: + - operator + +works_on: + - on-prem + - konnect + +min_version: + operator: '2.2' + +prereqs: + operator: + konnect: + auth: true + control_plane: true + inline: + - title: Create Gateway resources + include_content: /prereqs/operator/gateway + - title: Create a Service and a Route + include_content: /prereqs/operator/httpbin-service-route + +tldr: + q: How do I override the Host header sent to an upstream service with {{ site.operator_product_name }}? + a: | + Annotate the Kubernetes `Service` with `konghq.com/host-header: "your-hostname"`. {{ site.base_gateway }} will use this value as the `Host` header when forwarding requests upstream instead of the Pod IP address. + +related_resources: + - text: Service annotations reference + url: /operator/dataplanes/reference/service-annotations/ +--- + +By default, {{site.base_gateway}} sets the `Host` header to the IP address of the individual Pod it forwards the request to. Some upstream services perform host-based virtual hosting or access control and require a specific `Host` header value. You can override this behavior using the `konghq.com/host-header` annotation. + +## Check the default behavior + +1. Get the Gateway's external IP address: + + ```bash + export PROXY_IP=$(kubectl get gateway kong -n kong -o jsonpath='{.status.addresses[0].value}') + ``` + +1. Send a request to the `/headers` endpoint, which returns all request headers received by the upstream service: + + ```bash + curl -s $PROXY_IP/httpbin/headers + ``` + + The response shows the headers the upstream received. The `Host` header will contain the Pod IP address assigned by {{site.base_gateway}}: + + ```json + { + "headers": { + "Host": "10.0.0.5", + ... + } + } + ``` +{:.no-copy-code} + +## Annotate the Service + +Annotate the `httpbin` Service to set a custom `Host` header: + +```bash +kubectl annotate service httpbin -n kong \ + konghq.com/host-header="internal.example.com" +``` + +## Validate + +Send the same request again: + +```bash +curl -s $PROXY_IP/httpbin/headers +``` + +The `Host` header in the upstream request now reflects the configured value: + +```json +{ + "headers": { + "Host": "internal.example.com", + ... + } +} +``` +{:.no-copy-code} + +{:.info} +> **Note**: If the client-side `Host` header must be preserved instead, use the `konghq.com/preserve-host: "true"` annotation on the `HTTPRoute` or `Ingress` resource. When `preserve-host` is set to `true`, it takes precedence over `konghq.com/host-header`. diff --git a/app/_how-tos/operator/operator-dataplane-service-timeouts-retries.md b/app/_how-tos/operator/operator-dataplane-service-timeouts-retries.md new file mode 100644 index 0000000000..7b5fcaff87 --- /dev/null +++ b/app/_how-tos/operator/operator-dataplane-service-timeouts-retries.md @@ -0,0 +1,109 @@ +--- +title: Set timeouts and retries for a Service +description: "Learn how to configure connection, read, and write timeouts and retry behavior on a Kubernetes Service using {{ site.operator_product_name }} annotations." +content_type: how_to + +permalink: /operator/dataplanes/how-to/set-timeouts-and-retries/ +breadcrumbs: + - /operator/ + - index: operator + group: Gateway Deployment + - index: operator + group: Gateway Deployment + section: "How-To" + +products: + - operator + +works_on: + - on-prem + - konnect + +min_version: + operator: '2.2' + +prereqs: + operator: + konnect: + auth: true + control_plane: true + inline: + - title: Create Gateway resources + include_content: /prereqs/operator/gateway + - title: Create a Service and a Route + include_content: /prereqs/operator/httpbin-service-route + +tldr: + q: How do I configure timeouts and retries for a Service with {{ site.operator_product_name }}? + a: | + Annotate the Kubernetes `Service` with `konghq.com/connect-timeout`, `konghq.com/read-timeout`, `konghq.com/write-timeout`, and `konghq.com/retries`. {{ site.base_gateway }} applies these settings when forwarding requests to the upstream service. + +related_resources: + - text: Service annotations reference + url: /operator/dataplanes/reference/service-annotations/ +--- + +Timeout and retry settings control how long {{site.base_gateway}} waits for responses from your upstream services and how many times it retries failed requests. You configure these settings by annotating the Kubernetes `Service` that your `HTTPRoute` routes traffic to. + +## Annotate the Service + +Annotate the `httpbin` Service with timeout and retry values: + +```bash +kubectl annotate service httpbin -n kong \ + konghq.com/connect-timeout="3000" \ + konghq.com/read-timeout="5000" \ + konghq.com/write-timeout="5000" \ + konghq.com/retries="3" +``` + +The annotations have the following effects: + +{% table %} +columns: + - title: "Annotation" + key: "annotation" + - title: "Value" + key: "value" + - title: "Effect" + key: "effect" +rows: + - annotation: "`konghq.com/connect-timeout`" + value: "`3000`" + effect: "{{site.base_gateway}} waits up to 3 seconds to establish a TCP connection" + - annotation: "`konghq.com/read-timeout`" + value: "`5000`" + effect: "{{site.base_gateway}} waits up to 5 seconds for the upstream to send a response" + - annotation: "`konghq.com/write-timeout`" + value: "`5000`" + effect: "{{site.base_gateway}} waits up to 5 seconds when sending data upstream" + - annotation: "`konghq.com/retries`" + value: "`3`" + effect: "Failed requests are retried up to 3 times before returning an error" +{% endtable %} + +All timeout values are in milliseconds. + +## Validate + +1. Get the Gateway's external IP address: + + ```bash + export PROXY_IP=$(kubectl get gateway kong -n kong -o jsonpath='{.status.addresses[0].value}') + ``` + +1. Send a request that completes within the read timeout. The `/delay/1` endpoint waits 1 second before responding: + + ```bash + curl -s -o /dev/null -w "%{http_code}" $PROXY_IP/httpbin/delay/1 + ``` + + The response code should be `200`. + +1. Send a request that exceeds the read timeout. The `/delay/10` endpoint waits 10 seconds: + + ```bash + curl -s -o /dev/null -w "%{http_code}" $PROXY_IP/httpbin/delay/10 + ``` + + The response code should be `504`, indicating that the upstream did not respond within the configured `read-timeout`. diff --git a/app/_how-tos/operator/operator-dataplane-service-upstream-policy.md b/app/_how-tos/operator/operator-dataplane-service-upstream-policy.md new file mode 100644 index 0000000000..3f778af4c5 --- /dev/null +++ b/app/_how-tos/operator/operator-dataplane-service-upstream-policy.md @@ -0,0 +1,133 @@ +--- +title: Configure load balancing with KongUpstreamPolicy +description: "Learn how to customize load balancing behavior for a Kubernetes Service using the konghq.com/upstream-policy annotation and a KongUpstreamPolicy resource." +content_type: how_to + +permalink: /operator/dataplanes/how-to/configure-upstream-policy/ +breadcrumbs: + - /operator/ + - index: operator + group: Gateway Deployment + - index: operator + group: Gateway Deployment + section: "How-To" + +products: + - operator + +works_on: + - on-prem + - konnect + +min_version: + operator: '2.2' + +prereqs: + operator: + konnect: + auth: true + control_plane: true + inline: + - title: Create Gateway resources + include_content: /prereqs/operator/gateway + - title: Create a Service and a Route + include_content: /prereqs/operator/echo-service-route + +tldr: + q: How do I configure custom load balancing behavior for a Service with {{ site.operator_product_name }}? + a: | + Create a `KongUpstreamPolicy` resource with your desired load balancing settings, then attach it to the Kubernetes `Service` using the `konghq.com/upstream-policy` annotation. + +related_resources: + - text: Service annotations reference + url: /operator/dataplanes/reference/service-annotations/ + - text: KongUpstreamPolicy reference + url: /kubernetes-ingress-controller/reference/custom-resources/#kongupstreampolicy +--- + +By default, {{site.base_gateway}} distributes requests across the Pods of a Kubernetes Service using round-robin load balancing. For production workloads, you may need sticky sessions, consistent routing based on request attributes, or health check integration. + +The `konghq.com/upstream-policy` annotation lets you attach a `KongUpstreamPolicy` resource to a `Service`, giving you full control over {{site.base_gateway}}'s upstream load balancing behavior. + +This guide demonstrates consistent-hashing load balancing, which routes requests with the same header value to the same upstream Pod — a common pattern for session affinity. + +## Scale the Service + +Scale the `echo` Deployment to three replicas so there are multiple Pods to route between: + +```bash +kubectl scale deployment echo -n kong --replicas=3 +``` + +Wait for all Pods to be ready: + +```bash +kubectl rollout status deployment echo -n kong +``` + +## Create a KongUpstreamPolicy + +Create a `KongUpstreamPolicy` that configures consistent-hashing by a request header: + +```bash +echo ' +apiVersion: configuration.konghq.com/v1beta1 +kind: KongUpstreamPolicy +metadata: + name: session-affinity + namespace: kong +spec: + algorithm: consistent-hashing + hashOn: + header: x-session-id + hashOnFallback: + input: ip' | kubectl apply -f - +``` + +With this policy, requests that carry the same `x-session-id` header value are always forwarded to the same upstream Pod. When the header is absent, {{site.base_gateway}} falls back to hashing on the client IP. + +## Annotate the Service + +Attach the `KongUpstreamPolicy` to the `echo` Service: + +```bash +kubectl annotate service echo -n kong \ + konghq.com/upstream-policy="session-affinity" +``` + +## Validate + +1. Get the Gateway's external IP address: + + ```bash + export PROXY_IP=$(kubectl get gateway kong -n kong -o jsonpath='{.status.addresses[0].value}') + ``` + +1. Send several requests with the same `x-session-id` header value and observe that all responses come from the same Pod: + + ```bash + for i in {1..5}; do + curl -s -H "x-session-id: user-alice" $PROXY_IP/echo | grep "Running on Pod" + done + ``` + + All five responses should report the same Pod name: + + ``` + Running on Pod echo-6d8f4c9b7-xk2vt. + Running on Pod echo-6d8f4c9b7-xk2vt. + Running on Pod echo-6d8f4c9b7-xk2vt. + Running on Pod echo-6d8f4c9b7-xk2vt. + Running on Pod echo-6d8f4c9b7-xk2vt. + ``` +{:.no-copy-code} + +1. Send requests with a different header value to confirm they land on a different Pod: + + ```bash + for i in {1..5}; do + curl -s -H "x-session-id: user-bob" $PROXY_IP/echo | grep "Running on Pod" + done + ``` + + Requests for `user-bob` consistently hit a different Pod than requests for `user-alice`. diff --git a/app/_includes/prereqs/operator/httpbin-service-route.md b/app/_includes/prereqs/operator/httpbin-service-route.md new file mode 100644 index 0000000000..be93c18d00 --- /dev/null +++ b/app/_includes/prereqs/operator/httpbin-service-route.md @@ -0,0 +1,31 @@ +1. Run the following command to create a sample httpbin Service: + + ```bash + kubectl apply -f https://developer.konghq.com/manifests/kic/httpbin-service.yaml -n kong + ``` + +1. Create an `HTTPRoute` resource: + + ```sh + echo ' + apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httpbin-route + namespace: kong + annotations: + konghq.com/strip-path: "true" + konghq.com/preserve-host: "false" + spec: + parentRefs: + - name: kong + rules: + - matches: + - path: + type: PathPrefix + value: /httpbin + backendRefs: + - name: httpbin + kind: Service + port: 80' | kubectl apply -f - + ``` diff --git a/app/_indices/operator.yaml b/app/_indices/operator.yaml index 1e1d19837b..2187ae5b81 100644 --- a/app/_indices/operator.yaml +++ b/app/_indices/operator.yaml @@ -64,6 +64,9 @@ groups: - path: /operator/dataplanes/how-to/deploy-custom-plugins/ - path: /operator/dataplanes/how-to/handle-ingress/ - path: /operator/dataplanes/how-to/configure-plugins-for-httproute/ + - path: /operator/dataplanes/how-to/set-timeouts-and-retries/ + - path: /operator/dataplanes/how-to/set-host-header/ + - path: /operator/dataplanes/how-to/configure-upstream-policy/ - title: Observability items: - path: /operator/dataplanes/reference/metrics/operator/ @@ -74,6 +77,7 @@ groups: - path: /operator/dataplanes/reference/podtemplatespec/ - path: /operator/dataplanes/reference/autoscale-gateway/ - path: /operator/dataplanes/reference/autoscale-workloads/ + - path: /operator/dataplanes/reference/service-annotations/ - title: Upgrading items: - path: /operator/migrate/migrate-1.6.x-2.0.0/ diff --git a/app/operator/dataplanes/reference/service-annotations.md b/app/operator/dataplanes/reference/service-annotations.md new file mode 100644 index 0000000000..fc2f28b68e --- /dev/null +++ b/app/operator/dataplanes/reference/service-annotations.md @@ -0,0 +1,213 @@ +--- +title: "Service annotations" +description: "Configure upstream behavior such as timeouts, retries, host header, and TLS by annotating Kubernetes Services exposed through an HTTPRoute." +content_type: reference +layout: reference + +products: + - operator + +works_on: + - on-prem + - konnect + +min_version: + operator: '2.2' + +breadcrumbs: + - /operator/ + - index: operator + group: Gateway Deployment + - index: operator + group: Gateway Deployment + section: Advanced Usage + +related_resources: + - text: Set timeouts and retries for a Service + url: /operator/dataplanes/how-to/set-timeouts-and-retries/ + - text: Set the Host header sent to a Service + url: /operator/dataplanes/how-to/set-host-header/ + - text: Configure load balancing with KongUpstreamPolicy + url: /operator/dataplanes/how-to/configure-upstream-policy/ + - text: KIC annotation reference + url: /kubernetes-ingress-controller/reference/annotations/ +--- + +{{ site.operator_product_name }} supports a set of `konghq.com/*` annotations on Kubernetes `Service` resources. These annotations configure how {{site.base_gateway}} communicates with the upstream service — including protocols, timeouts, retries, host headers, and TLS settings. + +Annotations are placed on the `Service` object that is referenced as a `backendRef` in an `HTTPRoute`. For example: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service + namespace: kong + annotations: + konghq.com/connect-timeout: "3000" + konghq.com/read-timeout: "10000" + konghq.com/retries: "3" +spec: + ports: + - port: 80 +``` + +## Available annotations + +{% table %} +columns: + - title: Annotation + key: name + - title: Description + key: description +rows: + - name: "[`konghq.com/protocol`](#konghq-com-protocol)" + description: "Set the protocol {{site.base_gateway}} uses to communicate with the upstream service" + - name: "[`konghq.com/path`](#konghq-com-path)" + description: "Prepend an HTTP path to every request forwarded to the upstream service" + - name: "[`konghq.com/host-header`](#konghq-com-host-header)" + description: "Override the `Host` header sent to the upstream service" + - name: "[`konghq.com/client-cert`](#konghq-com-client-cert)" + description: "Client certificate and key pair {{site.base_gateway}} uses to authenticate itself to the upstream service (mTLS)" + - name: "[`konghq.com/upstream-policy`](#konghq-com-upstream-policy)" + description: "Override {{site.base_gateway}} Upstream configuration with a `KongUpstreamPolicy` resource" + - name: "[`konghq.com/connect-timeout`](#konghq-com-connect-timeout)" + description: "Timeout for completing a TCP connection to the upstream service, in milliseconds" + - name: "[`konghq.com/read-timeout`](#konghq-com-read-timeout)" + description: "Timeout for receiving an HTTP response after sending a request, in milliseconds" + - name: "[`konghq.com/write-timeout`](#konghq-com-write-timeout)" + description: "Timeout for transmitting data to the upstream service, in milliseconds" + - name: "[`konghq.com/retries`](#konghq-com-retries)" + description: "Maximum number of times to retry a failed request" + - name: "[`konghq.com/tls-verify`](#konghq-com-tls-verify)" + description: "Enable or disable verification of the upstream service's TLS certificate" + - name: "[`konghq.com/tls-verify-depth`](#konghq-com-tls-verify-depth)" + description: "Maximum certificate chain depth when verifying the upstream service's TLS certificate" +{% endtable %} + +## konghq.com/protocol + +Sets the protocol {{site.base_gateway}} uses to communicate with the upstream Kubernetes service. + +Accepted values: + +- `http` +- `https` +- `grpc` +- `grpcs` +- `tcp` +- `tls` + +Sample usage: + +```yaml +konghq.com/protocol: "https" +``` + +## konghq.com/path + +Prepends an HTTP path segment to every request forwarded to the upstream service. + +For example, if the annotation is set to `/api` and the incoming request path is `/orders/123`, the upstream service receives `/api/orders/123`. + +Sample usage: + +```yaml +konghq.com/path: "/api" +``` + +## konghq.com/host-header + +Sets the value of the `Host` header sent to the upstream service. By default, {{site.base_gateway}} sets `Host` to the IP address of the individual Pod target. + +This annotation overrides that default with a static hostname, which is useful when upstream services perform host-based virtual hosting. + +Sample usage: + +```yaml +konghq.com/host-header: "internal.example.com" +``` + +## konghq.com/client-cert + +Sets the TLS client certificate and key pair that {{site.base_gateway}} presents to the upstream service when the upstream requires mutual TLS (mTLS) authentication. + +The value must be the name of a Kubernetes `Secret` of type `kubernetes.io/tls` in the same namespace as the `Service`. + +Sample usage: + +```yaml +konghq.com/client-cert: "my-client-cert-secret" +``` + +## konghq.com/upstream-policy + +Attaches a `KongUpstreamPolicy` resource to the `Service`, allowing fine-grained control over load balancing behavior such as algorithm selection, consistent hashing, and health checks. + +The value is the name of a `KongUpstreamPolicy` object in the same namespace as the `Service`. See the [KongUpstreamPolicy reference](/kubernetes-ingress-controller/reference/custom-resources/#kongupstreampolicy) for the full list of configuration fields. + +Sample usage: + +```yaml +konghq.com/upstream-policy: "my-upstream-policy" +``` + +## konghq.com/connect-timeout + +Sets the timeout for completing a TCP connection to the upstream service, in milliseconds. If the connection cannot be established within this time, {{site.base_gateway}} returns an error to the client. + +Sample usage: + +```yaml +konghq.com/connect-timeout: "3000" +``` + +## konghq.com/read-timeout + +Sets the timeout for receiving the first byte of an HTTP response from the upstream service after sending the request, in milliseconds. + +Sample usage: + +```yaml +konghq.com/read-timeout: "10000" +``` + +## konghq.com/write-timeout + +Sets the timeout for sending data to the upstream service before closing the connection, in milliseconds. + +Sample usage: + +```yaml +konghq.com/write-timeout: "10000" +``` + +## konghq.com/retries + +Sets the maximum number of times {{site.base_gateway}} retries a failed request to the upstream service. A request is retried if the upstream returns a connection failure or timeout. + +Sample usage: + +```yaml +konghq.com/retries: "3" +``` + +## konghq.com/tls-verify + +Enables or disables verification of the upstream service's TLS certificate when `konghq.com/protocol` is set to `https` or `grpcs`. Accepted values are `"true"` or `"false"`. Verification is disabled by default. + +Sample usage: + +```yaml +konghq.com/tls-verify: "true" +``` + +## konghq.com/tls-verify-depth + +Sets the maximum certificate chain depth when verifying the upstream service's TLS certificate. If not set, the system default is used. + +Sample usage: + +```yaml +konghq.com/tls-verify-depth: "3" +```