-
Notifications
You must be signed in to change notification settings - Fork 99
feat(operator): document Service annotations added in 2.2.0 #5544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
sandromodarelli
merged 6 commits into
main
from
operator/annotations-reference-and-how-to
Jun 12, 2026
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
c0117a7
feat(operator): add Service annotations reference
sandromodarelli b142d88
feat(operator): add Service annotation how-to guides
sandromodarelli 9d6cd7d
chore(operator): add Service annotation pages to product index
sandromodarelli 6ec07dd
chore(operator): add strip-path annotation to httpbin service route
sandromodarelli b871d9c
chore(operator): add preserve-host annotation to httpbin service route
sandromodarelli 336d33c
Apply suggestions from code review
sandromodarelli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
104 changes: 104 additions & 0 deletions
104
app/_how-tos/operator/operator-dataplane-service-host-header.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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} | ||
|
|
||
|
sandromodarelli marked this conversation as resolved.
|
||
| {:.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`. | ||
109 changes: 109 additions & 0 deletions
109
app/_how-tos/operator/operator-dataplane-service-timeouts-retries.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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`. |
133 changes: 133 additions & 0 deletions
133
app/_how-tos/operator/operator-dataplane-service-upstream-policy.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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} | ||
|
|
||
|
sandromodarelli marked this conversation as resolved.
|
||
| 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`. | ||
|
lmilan marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 - | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.