diff --git a/assets/agw-docs/snippets/agentgateway/helm.md b/assets/agw-docs/snippets/agentgateway/helm.md index 9b6a12312..07bb2b46c 100644 --- a/assets/agw-docs/snippets/agentgateway/helm.md +++ b/assets/agw-docs/snippets/agentgateway/helm.md @@ -38,7 +38,7 @@ 3. Install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart. - 1. **Optional**: Pull and inspect the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart values before installation. You might want to update the Helm chart values files to customize the installation. For example, you might change the namespace, update the resource limits and requests, or enable extensions such as for AI. For more information, see [Advanced settings]({{< link-hextra path="/advanced">}}). + 1. **Optional**: Pull and inspect the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart values before installation. You might want to update the Helm chart values files to customize the installation. For example, you might change the namespace, update the resource limits and requests, or enable extensions such as for AI. For more information, see [Advanced settings]({{< link-hextra path="/install/advanced/">}}). ```sh helm pull oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} diff --git a/assets/docs/examples/httpbin.yaml b/assets/docs/examples/httpbin.yaml deleted file mode 100644 index dbe8679ab..000000000 --- a/assets/docs/examples/httpbin.yaml +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright Istio Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -################################################################################################## -# httpbin service -################################################################################################## -apiVersion: v1 -kind: ServiceAccount -metadata: - name: httpbin ---- -apiVersion: v1 -kind: Service -metadata: - name: httpbin - labels: - app: httpbin - service: httpbin -spec: - ports: - - name: http - port: 8000 - targetPort: 8080 - - name: tcp - port: 9000 - selector: - app: httpbin ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: httpbin -spec: - replicas: 1 - selector: - matchLabels: - app: httpbin - version: v1 - template: - metadata: - labels: - app: httpbin - version: v1 - spec: - serviceAccountName: httpbin - containers: - - image: docker.io/mccutchen/go-httpbin:v2.6.0 - imagePullPolicy: IfNotPresent - name: httpbin - command: [ go-httpbin ] - args: - - "-port" - - "8080" - - "-max-duration" - - "600s" # override default 10s - ports: - - containerPort: 8080 - # Include curl container for e2e testing, allows sending traffic mediated by the proxy sidecar - - name: curl - image: curlimages/curl:7.83.1 - resources: - requests: - cpu: "100m" - limits: - cpu: "200m" - imagePullPolicy: IfNotPresent - command: - - "tail" - - "-f" - - "/dev/null" - - name: hey - image: gcr.io/solo-public/docs/hey:0.1.4 - imagePullPolicy: IfNotPresent \ No newline at end of file diff --git a/assets/docs/examples/petstore.yaml b/assets/docs/examples/petstore.yaml deleted file mode 100644 index 2f2adf338..000000000 --- a/assets/docs/examples/petstore.yaml +++ /dev/null @@ -1,47 +0,0 @@ - -########################## -# # -# Example # -# Service # -# # -# # -########################## -# petstore service -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: petstore - name: petstore - namespace: default -spec: - selector: - matchLabels: - app: petstore - replicas: 1 - template: - metadata: - labels: - app: petstore - spec: - containers: - - image: soloio/petstore-example:latest - name: petstore - ports: - - containerPort: 8080 - name: http ---- -apiVersion: v1 -kind: Service -metadata: - name: petstore - namespace: default - labels: - service: petstore -spec: - ports: - - name: http - port: 8080 - protocol: TCP - selector: - app: petstore \ No newline at end of file diff --git a/assets/docs/pages/about/architecture.md b/assets/docs/pages/about/architecture.md deleted file mode 100644 index 423906bff..000000000 --- a/assets/docs/pages/about/architecture.md +++ /dev/null @@ -1,83 +0,0 @@ -Learn more about the components that make up the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control and data plane. These components work together to provide traffic management, security, and resiliency for your apps. - -## Component architecture - -The following image shows the different components that make up the {{< reuse "/agw-docs/snippets/kgateway.md" >}} {{< gloss "Control Plane" >}}control plane{{< /gloss >}} and {{< gloss "Data Plane" >}}data plane{{< /gloss >}}. These components work together to translate gateway custom resources into gateway {{< gloss "Proxy" >}}proxy{{< /gloss >}} configuration. The gateway proxy configuration controls the behavior of the gateway proxies that serve your apps. - -{{< reuse-image src="img/agw-control-plane-components.svg" caption="Component architecture" >}} -{{< reuse-image-dark srcDark="img/agw-control-plane-components-dark.svg" caption="Component architecture" >}} - - - -1. The config and secret watcher components in the `{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}` pod watch the cluster for new Kubernetes Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} resources, such as Gateways, HTTPRoutes, or TrafficPolicies. -2. When the config or secret watcher detect new or updated resources, it sends the resource configuration to the {{< reuse "/agw-docs/snippets/kgateway.md" >}} {{< gloss "Translation" >}}translation{{< /gloss >}} engine. -3. The translation engine translates Kubernetes Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} resources into gateway proxy configuration. All gateway proxy configuration is consolidated into an xDS snapshot. -4. The reporter receives a status report for every resource that is processed by the translator. -5. The reporter writes the resource status back to the etcd data store. -6. The xDS snapshot is provided to the {{< reuse "/agw-docs/snippets/kgateway.md" >}} xDS server component in the `{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}` pod. -7. Gateway proxies in the cluster pull the latest gateway proxy configuration from the {{< reuse "/agw-docs/snippets/kgateway.md" >}} xDS server. -8. Clients send a request to the IP address or hostname that the gateway proxy is exposed on. -9. The gateway proxy uses the listener and route-specific configuration that was provided in the xDS snapshot to perform routing decisions and forward requests to destinations in the cluster. - -### Config watcher - -The config watcher component is part of the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and watches the cluster for new or updated Kubernetes Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} resources, such as Gateways, HTTPRoutes, and Backends. When the config watcher detects new or updated resources, it sends the Kubernetes configuration to the {{< reuse "/agw-docs/snippets/kgateway.md" >}} translation engine. - -### Secret watcher - -The secret watcher component is part of the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and watches a secret store for updates to secrets. For example, you might use a Kubernetes Secret to store the AWS access key and secret key credentials for a Backend to access an AWS Lambda. However, you can configure {{< reuse "/agw-docs/snippets/kgateway.md" >}} to also watch other secret stores. - - - -### Translation engine - -The {{< reuse "/agw-docs/snippets/kgateway.md" >}} translator receives snapshots of all the Kubernetes Gateway API, Kubernetes API, and {{< reuse "/agw-docs/snippets/kgateway.md" >}} resources that you create or update. The translator starts a new translation loop for each update to translate these resources into valid gateway proxy configuration. The gateway proxy configuration is stored in an xDS snapshot. - -The following image shows the different stages of a translation cycle for the gateway proxy. - - - -{{< reuse-image src="img/agw-translation-loop.svg" caption="Agentgateway translation cycle" >}} -{{< reuse-image-dark srcDark="img/agw-translation-loop-dark.svg" caption="Agentgateway translation cycle" >}} - -1. When the agentgateway feature is enabled for {{< reuse "/agw-docs/snippets/kgateway.md" >}}, the agentgateway syncer component is created as part of the control plane. - -2. The agentgateway syncer sets up the initial configuration, including the `agentgateway` GatewayClass name that Gateways can use to automatically create agentgateway proxies. The agentgateway syncer also builds the initial krt collections based on the Gateway API and kgateway resources in the cluster. - -3. The translation cycle starts by collecting all of the resources that are needed to create agentgateway proxy config. These various collections include: - * Core collections of the Kubernetes, Gateway API, and kgateway resources that are defined in the cluster, such as namespaces, services, gateways, routes, policies, backends, and plugins for AI, MCP, and A2A-specific backends. - * Agentgateway data plane resource building that consist of information translated from the core collection into the format that agentgateway expects, such as bind, port, listener, route, backend, target, and policy configuration for agentgateway. For more information, see the [agentgateway about topic](../../agentgateway/about/#resources). - * Address collections of the service and workloads that are included in service discovery and endpoint resolution. - * The translation order ensures that dependencies are resolved correctly: `binds → listeners → routes → policies`, with backends and addresses processed separately and added to the final configuration. - -4. The next step in the translation process is to build the xDS collection. This step merges all of the resource config of agentgateway data plane resources together with the address collections to create the config for each agentgateway proxy. It also builds status reports for the resources, tracks attached routes, and determines attached policies. - -5. Finally, the information from the resource and xDS collections are turned into an xDS snapshot of the agentgateway proxy config. The snapshot is sent to the xDS server. The agentgateway proxies in your cluster watch the xDS server for new config. When new config is detected, the config is pulled into the agentgateway proxy via gRPC. - -### Reporter - -The reporter component receives a validation report for every {{< reuse "/agw-docs/snippets/kgateway.md" >}} resource that was processed by the translator. Any invalid configuration is reported back to the user through the Kubernetes storage layer. Invalid resources are marked as `rejected` and an error message is captured in the resource configuration. - -### xDS server - -The xDS server sends the xDS snapshot to the gateway proxies in the data plane. - -{{< icon "agentgateway" >}} **Agentgateway proxy**: Updates the agentgateway proxy with agentgateway-specific configuration, including MCP and A2A protocol support, to match the desired state. - - - diff --git a/assets/docs/pages/about/backendconfigpolicy.md b/assets/docs/pages/about/backendconfigpolicy.md deleted file mode 100644 index b752bca52..000000000 --- a/assets/docs/pages/about/backendconfigpolicy.md +++ /dev/null @@ -1,80 +0,0 @@ -Use a BackendConfigPolicy resource to configure connection settings for a backend. - -## Policy attachment {#policy-attachment-backendconfigpolicy} - -You can apply BackendConfigPolicies to individual Kubernetes services, any backend that matches a specific label, or a global service in your ambient mesh. - -{{< callout type="info" >}} -By default, you must attach policies to resources that are in the same namespace. To create global policies that can attach to resources in any namespace, see the [Global policy attachment](../global-attachment/) guide. -{{< /callout >}} - -### Individual backend {#attach-to-backend} - -You can use the `spec.targetRefs` section in the BackendConfigPolicy resource to apply policies to a specific backend, such as a Kubernetes Service or a {{< reuse "agw-docs/snippets/backend.md" >}} resource. - -The following example BackendConfigPolicy resource specifies connection settings for the `httpbin` service. - -```yaml -kind: BackendConfigPolicy -apiVersion: gateway.kgateway.dev/v1alpha1 -metadata: - name: httpbin-policy - namespace: httpbin -spec: - targetRefs: - - name: httpbin - group: "" - kind: Service - connectTimeout: 5s - perConnectionBufferLimitBytes: 1024 -``` - -### Backends with specific label {#label-selector} - -Instead of applying the policy to a specific service or {{< reuse "agw-docs/snippets/backend.md" >}}, you can also use a label selector to apply the policy to all services or {{< reuse "agw-docs/snippets/backend.md" >}}s that match the label. - -The following example shows a BackendConfigPolicy resource that applies connection settings to all Kubernetes services that have the `app: httpbin` and `service: httpbin` labels. - -```yaml -kind: BackendConfigPolicy -apiVersion: gateway.kgateway.dev/v1alpha1 -metadata: - name: httpbin-policy - namespace: httpbin -spec: - targetSelectors: - - group: networking.istio.io - kind: Service - matchLabels: - app: httpbin - service: httpbin - connectTimeout: 5s - commonHttpProtocolOptions: - maxHeadersCount: 15 - maxRequestsPerConnection: 100 -``` - -### Global service {#istio-global} - -If you use {{< reuse "agw-docs/snippets/kgateway.md" >}} with an Istio ambient mesh and you exposed services across multiple clusters by using the `solo.io/service-scope=global` label, Istio automatically creates ServiceEntry resources in each of your clusters that use the same global hostname. You can then use the global hostname to send and load balance requests across multiple clusters. - -To apply connection settings to all service instances that are exposed by this global hostname, you can apply a BackendConfigPolicy to an Istio hostname as shown in the following example. - -```yaml -kind: BackendConfigPolicy -apiVersion: gateway.kgateway.dev/v1alpha1 -metadata: - name: httpbin-policy-alias - namespace: gwtest -spec: - targetSelectors: - - group: networking.istio.io - kind: Hostname - matchLabels: - app: httpbin - service: httpbin - connectTimeout: 5s - commonHttpProtocolOptions: - maxHeadersCount: 15 - maxRequestsPerConnection: 100 -``` diff --git a/assets/docs/pages/about/custom-resources.md b/assets/docs/pages/about/custom-resources.md deleted file mode 100644 index d45eb98d9..000000000 --- a/assets/docs/pages/about/custom-resources.md +++ /dev/null @@ -1,76 +0,0 @@ -Learn about the custom resources that make up {{< reuse "/agw-docs/snippets/kgateway.md" >}} and how they interact with each other. - -## Custom resource overview - -{{< reuse "agw-docs/snippets/cr-ov.md" >}} - - - -## Kubernetes Gateway API resources {#k8s} - -Review the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} resources that you use to set up gateway proxies and configure routing for your apps. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} introduction](https://gateway-api.sigs.k8s.io/#introduction). - -### Gateway and GatewayClass - -The [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway/) custom resource is a network abstraction that defines a point of access at which traffic can be forwarded to a backend in a {{< gloss "Cluster (Kubernetes)" >}}Kubernetes cluster{{< /gloss >}}. A Gateway defines the listeners that you want to open, including the ports, protocols, and hostnames that you want to listen on for incoming traffic. You can also specify how incoming, encrypted traffic is handled. For example, encrypted traffic can be terminated at the gateway or passed through to a backend in the cluster. - -To spin up a Gateway and manage its lifecycle, a gateway controller is used. The gateway controller is defined in the [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resource and manages the underlying infrastructure to ensure that traffic to endpoints is routed accordingly. When you install kgateway, a GatewayClass resource is automatically created that points to the kgateway controller. For more information, see [GatewayClass]({{< link-hextra path="/setup/default/#gatewayclass" >}}). - -### HTTPRoute and TCPRoute {#httproute} - -To configure routing, the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} provides several routing resources, such as an HTTPRoute and TCPRoute. These routes attach to a Gateway resource and define how incoming traffic is matched and forwarded to a backing destination. - -* [HTTPRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/): The most commonly used route resource, that configures traffic routing for HTTP and HTTPS traffic. -* [TCPRoute](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute): A resource to route TCP requests. - -While the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} provides the functionality for basic request matching, redirects, rewrites, and header manipulation, it is missing more complex traffic management, resiliency, and security features, such as transformations, access logging, or route delegation. - -You can extend the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} features by leveraging the [kgateway-native policy custom resources](#policies). Policies allow you to apply intelligent traffic management, resiliency, and security standards to an HTTPRoute or Gateway. - -### Kubernetes Services - -Kubernetes Services expose Kubernetes pods within and outside a Kubernetes cluster so that other network endpoints can communicate with them. In the context of the Kubernetes Gateway API, the Kubernetes Service represents an app within the cluster that you want to route traffic to from outside the cluster. The Service is referenced in the HTTPRoute resource, including the port that you want to send traffic to. - -If traffic matches the conditions that are defined in the HTTPRoute, the Gateway forwards traffic to the Kubernetes Service that is referenced in the HTTPRoute. - -### ReferenceGrant - -A [ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) allows a Kubernetes Gateway API resource, such as an HTTPRoute, to reference resources that exist in other namespaces. For example, if you create an HTTPRoute resource in `namespace1`, but the Kubernetes Service or Backend that you want to route to is in `namespace2`, you must create a ReferenceGrant to allow communication between these resources. - - - -## Kgateway resources {#kgateway} - -Review the kgateway resources that you use to bootstrap, configure, and customize your gateway proxy, and the policies that you can leverage to add additional traffic management, resiliency, and security capabilities to your gateway and routes. - -### GatewayExtensions - -A {{< gloss "Gateway Extension" >}}GatewayExtension{{< /gloss >}} is a {{< reuse "/agw-docs/snippets/kgateway.md" >}} Custom Resource that serves as a configuration bridge between {{< reuse "/agw-docs/snippets/kgateway.md" >}} and external services that extend a Gateway's functionality. These external services provide additional capabilities like authentication (`extAuth`), rate limiting (`rateLimit`), and request processing (`extProc`). TrafficPolicies can then refer to the GatewayExtension with the external service that the policy needs to be enforced. For more information, see the [API docs]({{< link-hextra path="/reference/api/#gatewayextension" >}}). - -### {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - -When you create a Gateway resource, a [default gateway proxy template](https://github.com/kgateway-dev/kgateway/blob/{{< reuse "agw-docs/versions/github-branch.md" >}}{{< reuse "agw-docs/versions/github-kgateway-deployment.md" >}}) is used to automatically spin up and bootstrap a gateway proxy deployment and service in your cluster. The template includes Envoy configuration that binds the gateway proxy deployment to the Gateway resource that you created. In addition, the settings in the {{< gloss "GatewayParameters" >}}{{< reuse "agw-docs/snippets/gatewayparameters.md" >}}{{< /gloss >}} resource are used to configure the gateway proxy. - -To learn more about the default gateway setup and how these resource interact with each other, see [Default gateway proxy setup]({{< link-hextra path="/setup/default/" >}}). - -### Policies - -While the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} allows you to do simple routing, such as to match, redirect, or rewrite requests, you might want additional capabilities in your API gateway, such as access logging or transformations. [Policies]({{< link-hextra path="/about/policies/" >}}) allow you to apply intelligent traffic management, resiliency, and security standards to HTTPRoutes or Gateways. - -Kgateway uses the following custom resources to attach policies to routes and gateway listeners: - -* [**DirectResponse**]({{< link-hextra path="/traffic-management/direct-response/" >}}): Directly respond to incoming requests with a custom HTTP response code and body. -* [**HTTPListenerPolicy**]({{< link-hextra path="/about/policies/httplistenerpolicy/" >}}): Apply policies to all HTTP and HTTPS listeners. -* [**TrafficPolicy**](https://kgateway.dev/docs/envoy/main/about/policies/trafficpolicy/): Attach policies to routes in an HTTPRoute resource. - -### {{< reuse "agw-docs/snippets/backend.md" >}}s - -For workloads within your cluster, you can can route incoming traffic to their Kubernetes Service. But what if you have external services such as static hostnames or AWS Lambda functions that you want to route traffic to? - -You can use a {{< reuse "agw-docs/snippets/backend.md" >}} resource to accomplish this task. Similar to using Kubernetes Services, you reference the {{< reuse "agw-docs/snippets/backend.md" >}} in your HTTPRoute resource. For more information, see [{{< reuse "agw-docs/snippets/backend.md" >}}s]({{< link-hextra path="/traffic-management/destination-types/backends/" >}}). diff --git a/assets/docs/pages/about/deployment-patterns.md b/assets/docs/pages/about/deployment-patterns.md deleted file mode 100644 index 5b36deb1d..000000000 --- a/assets/docs/pages/about/deployment-patterns.md +++ /dev/null @@ -1,79 +0,0 @@ -Learn how you can deploy gateway proxies to ensure proper traffic routing, security, and isolation for your apps. - -The flexibility of {{< reuse "/agw-docs/snippets/kgateway.md" >}} allows you to deploy it in a way that best serves your environment. Review the following recommended deployment patterns to choose how to set up gateway proxies. - -## API Gateway and ingress controller - -Use the gateway proxy as a fast and flexible Kubernetes-native ingress controller and next-generation API gateway to aggregate and provide uniform access to your APIs. - -### Simple ingress - -The following image shows a gateway proxy that serves as a single ingress API gateway to the workloads in a Kubernetes cluster. The gateway is centrally managed by the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and configured to match and forward traffic based on the traffic management, resiliency, and security rules that you define. - -{{% reuse-image src="img/pattern-simple-ingress.svg" width="400px" caption="Simple ingress" %}} -{{% reuse-image-dark srcDark="img/pattern-simple-ingress.svg" width="400px" caption="Simple ingress" %}} - - - -This setup is a great way to get started with {{< reuse "/agw-docs/snippets/kgateway.md" >}}, and is suitable for smaller environments where all workloads run in a single cluster and traffic is balanced between services. However, in larger environments or environments where you have both high traffic and low traffic services, consider adding [multiple gateway proxies to distribute traffic load more evenly](#sharded-gateway). - -### Sharded gateway {#sharded-gateway} - -In larger environments or environments where you have both high traffic and low traffic services, you can isolate services from each other and protect against noisy neighbors by using a sharded gateway. With a sharded gateway architecture, you typically have multiple gateway proxies that split up the traffic for different services in the cluster as depicted in the following image. - -{{% reuse-image src="img/pattern-sharded-gateway.svg" width="400px" caption="Sharded gateway" %}} -{{% reuse-image-dark srcDark="img/pattern-sharded-gateway.svg" width="400px" caption="Sharded gateway" %}} - - - -All gateway proxies are managed by the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane. However, one gateway proxy manages traffic for the workloads in the `foo` and `bar` namespaces. The second gateway proxy is a dedicated API gateway for the workloads in the `extra` namespace. Both gateway proxies are exposed directly on the edge. - -While this setup is great to split up and load balance traffic across apps, you might not want the gateway proxies to be exposed directly on the edge. Instead, you might want a central ingress gateway proxy that applies common traffic management, resiliency, and security rules, and that forwards traffic to other gateway proxies that are dedicated to certain apps, teams, or namespaces. To learn more about this deployment pattern, see [Sharded gateway with central ingress](#sharded-gatway-with-central-ingress). - - -### Sharded gateway with central ingress {#sharded-gatway-with-central-ingress} - -The following image shows a gateway proxy that serves as the main ingress endpoint for all traffic. The gateway proxy can be configured to apply common traffic management, resiliency, and security rules to all traffic that enters the cluster. For example, you can set header manipulation policies on that gateway before you forward traffic to a second layer of gateway proxies. This is useful if you need a central IP address and DNS name for the gateway that serves all your traffic. - -The second layer of gateway proxies can apply additional traffic management, resiliency, and security policies to incoming traffic for specific apps. You also shard the second layer of proxies to better account for high and low traffic services to avoid noisy neighbor problems. All gateway proxies are managed by the same {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane. - -{{% reuse-image src="img/pattern-central-ingress-gloo.svg" width="600px" %}} -{{% reuse-image-dark srcDark="img/pattern-central-ingress-gloo.svg" width="600px" %}} - - - -Depending on your existing setup, you might want to use a different type of proxy as your central ingress endpoint. For example, you might have an HAProxy or AWS NLB/ALB instance that all traffic must go through. Kgateway can be paired with these types of proxies as depicted in the following image. - -{{% reuse-image src="img/pattern-central-ingress-any.svg" width="600px" %}} -{{% reuse-image-dark srcDark="img/pattern-central-ingress-any.svg" width="600px" %}} - - - -## Service mesh gateway - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} integrates seamlessly with your Istio service mesh so that you can control and manage ingress, egress, and mesh-internal traffic. - -### Ambient mesh - -You can deploy {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an ingress, egress, or waypoint proxy gateway for the workloads in an Istio ambient mesh. An ambient mesh uses node-level ztunnels to route and secure Layer 4 traffic between pods with mutual TLS (mTLS). Waypoint proxies enforce Layer 7 traffic policies whenever needed. - -The following image shows a gateway proxy that is exposed on the edge and serves traffic for the ambient mesh. Services in the mesh communicate with each other via mutual TLS (mTLS). - -{{% reuse-image src="img/ambient-ingress.svg" width="600px" %}} -{{% reuse-image-dark srcDark="img/ambient-ingress.svg" width="600px" %}} - - - -For more information, see the guides for using {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an [ingress gateway](../../integrations/istio/ambient/ambient-ingress/) or [waypoint proxy](../../integrations/istio/ambient/waypoint/) for your ambient mesh. - -### Sidecar mesh - -You can deploy {{< reuse "/agw-docs/snippets/kgateway.md" >}} with an Istio sidecar to route traffic to services in an Istio sidecar mesh. The following image shows a gateway proxy that is exposed on the edge and serves traffic for the sidecar mesh. Services in the mesh communicate with each other via mutual TLS (mTLS) by using the istio-proxy sidecar that is injected into the app. The sidecar is represented with the Envoy logo in the image. - -{{< reuse-image src="img/sidecar-ingress.svg" width="800px" >}} -{{< reuse-image-dark srcDark="img/sidecar-ingress.svg" width="800px" >}} - - - -For more information, see the guide for using {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an [ingress gateway](../../integrations/istio/sidecar/ingress/) to your sidecar mesh. - diff --git a/assets/docs/pages/about/httplistenerpolicy.md b/assets/docs/pages/about/httplistenerpolicy.md deleted file mode 100644 index 0f402d11e..000000000 --- a/assets/docs/pages/about/httplistenerpolicy.md +++ /dev/null @@ -1,122 +0,0 @@ -You can use an HTTPListenerPolicy resource to attach policies to HTTP or HTTPS listeners on the gateway. - -{{< callout type="info" >}} -By default, you must attach policies to resources that are in the same namespace. To create global policies that can attach to resources in any namespace, see the [Global policy attachment](../global-attachment/) guide. -{{< /callout >}} - -## Policy attachment {#policy-attachment-listeneroption} - - - -You can apply a policy to all HTTP and HTTPS listeners that are defined on the gateway by using the `spec.targetRefs` section in the HTTPListenerPolicy resource. - -The following HTTPListenerPolicy resource configures access logs on a Gateway that is named `http`. The policy applies to all the HTTP and HTTPS listeners that are defined on the gateway. - -```yaml {hl_lines=[7,8,9,10]} -apiVersion: gateway.kgateway.dev/v1alpha1 -kind: HTTPListenerPolicy -metadata: - name: access-logs - namespace: kgateway-system -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - accessLog: - - fileSink: - path: /dev/stdout - jsonFormat: - start_time: "%START_TIME%" - method: "%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%" - path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" - protocol: "%PROTOCOL%" - response_code: "%RESPONSE_CODE%" - response_flags: "%RESPONSE_FLAGS%" - bytes_received: "%BYTES_RECEIVED%" - bytes_sent: "%BYTES_SENT%" - total_duration: "%DURATION%" - resp_backend_service_time: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%" - req_x_forwarded_for: "%REQ(X-FORWARDED-FOR)%" - user_agent: "%REQ(USER-AGENT)%" - request_id: "%REQ(X-REQUEST-ID)%" - authority: "%REQ(:AUTHORITY)%" - backendHost: "%UPSTREAM_HOST%" - backendCluster: "%UPSTREAM_CLUSTER%" -``` - - - -## Conflicting policies - -If you create multiple HTTPListenerPolicy resources that define the same type of top-level policy, and attach them to the same gateway by using the `targetRefs` option, only the HTTPListenerPolicy that was last applied is enforced. - - \ No newline at end of file diff --git a/assets/docs/pages/about/overview.md b/assets/docs/pages/about/overview.md deleted file mode 100644 index 15b15afa2..000000000 --- a/assets/docs/pages/about/overview.md +++ /dev/null @@ -1,103 +0,0 @@ -{{< reuse "agw-docs/snippets/kgateway-about.md" >}} - -In this topic, you learn about the basics of API gateways for microservices, the extensions that {{< reuse "/agw-docs/snippets/kgateway.md" >}} provides beyond typical API gateway functionality, and the default API gateway proxy setup. - -{{< callout icon="agentgateway" >}} -Looking for an AI gateway to connect agents, MCP tools, and LLMs? Check out the [agentgateway data plane docs](../../agentgateway/). {{< reuse "agw-docs/snippets/control-plane-note.md" >}} -{{< /callout >}} - -## API gateway {#api-gateway} - -The {{< reuse "/agw-docs/snippets/kgateway.md" >}} data plane is a feature-rich, fast, and flexible Kubernetes-native [ingress controller](#what-is-an-ingress) and next-generation [API gateway](#what-is-an-api-gateway) that is built on top of [Envoy proxy](https://www.envoyproxy.io/) and the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}](#what-is-the-kubernetes-gateway-api). - -### What is an ingress? - -An ingress, edge router, or application gateway, is a service that is accessible to the Internet, and routes traffic to services running inside a Kubernetes environment. Traditionally, this service was managed by a Kubernetes object also called an `Ingress`, and as such “ingress” in a Kubernetes context normally refers to an operator configuration where a control plane configures a hardware or software proxy server. The traffic can include API traffic, but can also include general traffic like web pages and images. - -Examples of Kubernetes ingresses include ingress-nginx and Contour. - -Kgateway includes full Kubernetes ingress functionality, providing its own control plane, using the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}](#what-is-the-kubernetes-gateway-api) as its configuration language and Envoy as its proxy server. - -### What are the components of an ingress? - -There are three major components that make up any ingress solution: - -* control plane -* data plane -* configuration language - -The [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}](#what-is-the-kubernetes-gateway-api) is a project designed to standardize the configuration language, replacing the legacy `Ingress` API with an extensible API. - -Ingress projects therefore differentiate on their data plane — there are solutions built on top of Envoy, HAProxy, NGINX, Traefik and more — and the performance, scalability and features of their control plane. - - - -### What is an API? - -An application programming interface (API) is a method to allow a machine to talk to a machine. Contrast APIs with user interfaces (UIs), which allow a human to talk to a machine. - -Today, an API most commonly refers to a web API, a method using HTTP (or a derivative like gRPC) to provide access to machine readable data in a format like JSON or XML. Web APIs are sometimes referred to as web services, which is where Amazon Web Services (AWS) gets its name. - -As an example, take a look at the API for NASA's popular [Astronomy Picture of the Day](https://apod.nasa.gov/apod/astropix.html) service. The most common way that humans access this service is through the UI that is the NASA website. However, if you want a machine to use this service, you can also use the API. - -To start, you [generate an API key](https://api.nasa.gov/) that gives access to the API. Then, you set up your program to perform an HTTP GET request to the API endpoint: `https://api.nasa.gov/planetary/apod?api_key=$YOUR_API_KEY`. - -As with most APIs, the Astronomy Picture of the Day API also includes parameters that you can use in the request to get back more specific responses, such as the date. Typically, parameters have default values if you don't include them, such as today's date. To find out the available parameters and more, you use the [API documentation](https://github.com/nasa/apod-api?tab=readme-ov-file#docs-). - -### What is an API gateway? - -An API gateway is a service that provides centralized gateway functionality for API traffic. The concept that took off as microservices architectures were growing in popularity in the 2005-2015 era, with early vendors such as 3scale, WSO2 and Apigee targeting backends that were run on Java. As Kubernetes became popular, the need arose to offer API gateway functionality that integrated with it. This led to the launch of Gloo, which is the original name of kgateway. - -In the NASA example, recall that you had to provide an API key to access the service. This is a way of identifying you to the API, which can then be used to enable decision-making. - -Some functions an API gateway might perform include: - -* **Routing and aggregation**: Similar to an ingress, make APIs from different backend services (including serverless functions) available at a single endpoint, behind a single API key. -* **Load balancing**: Send requests to backend services, based on their load. -* **Rate limiting:** Limit the number of users that can call certain APIs, based on parameters such as identity, load, or cost. -* **Security**: Provide authentication and authorization, and Web Application Firewall functionality. -* **Logging and monitoring**: Track and display usage in order to provide visibility into the system to help with use cases such as API management, debugging, and accurate billing data. - -### Are ingresses API gateways? - -Although a necessary component, ingress functionality by itself is not sufficient for a project to be considered an API gateway. - -Traditionally an ingress primarily handles routing and aggregation, with Kubernetes providing load balancing. If you hear the phrase “application gateway,” it’s probably acting as a gateway for the website UI. Although APIs are web traffic and are often published through an ingress, you don’t have the full range of features in a UI-focused application gateway as you would in an API gateway. - -### What is the Kubernetes Gateway API? - -The {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} is a common, extensible standard for traffic management in Kubernetes. It is quickly becoming the standard interface for defining routing and policy for cloud native networking, addressing many shortcomings of its predecessor, the Ingress API, and unifying best practices that have evolved through real-world usage. - -[Learn about the history of the Gateway API](/blog/introduction-to-kubernetes-gateway-api/), or [watch our in-depth video series](/resources/videos/). - -Kgateway is fully conformant with the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} and extends its functionality with custom extension APIs, such as TrafficPolicies, ListenerPolicies, and Backends. These custom resources help to centrally configure advanced traffic management, security, and resiliency rules for an HTTPRoute or Gateway listener. - -### Is the Gateway API an API gateway? - -No, but this demonstrates why [naming things](https://www.karlton.org/2017/12/naming-things-hard/) is hard! - -The Gateway API is an API which can be used to program an ingress or an API gateway. - -## Extensions - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} provides the following extensions on top of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} to configure advanced routing, security, and resiliency capabilities. - -{{< cards >}} - {{< card link="../../security/access-logging/" title="Access logging" tag="Security" >}} - {{< card link="../../integrations/aws-elb/" title="AWS ALB and NLB" tag="Traffic" >}} - {{< card link="../../traffic-management/destination-types/backends/lambda" title="AWS Lambda" tag="Traffic" >}} - {{< card link="../../traffic-management/route-delegation/" title="Delegation" tag="Traffic" >}} - {{< card link="../../traffic-management/direct-response/" title="Direct responses" tag="Traffic" >}} - {{< card link="../../traffic-management/ext/" title="Direct responses" tag="Traffic" >}} - {{< card link="../../setup/customize/" title="Gateway customization" tag="Setup" >}} - {{< card link="../../integrations/" title="Integrations" tag="Setup" >}} - {{< card link="../../resiliency/mirroring/" title="Mirroring" tag="Resiliency" >}} - {{< card link="../../traffic-management/transformations/" title="Transformations" tag="Traffic" >}} - {{< card link="../../traffic-management/weighted-routes/" title="Weighted routing" tag="Traffic" >}} -{{< /cards >}} - -## Default gateway proxy setup - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} automatically spins up, bootstraps, and manages gateway proxy deployments when you create a Kubernetes Gateway resource. To do that, a combination of kgateway and Kubernetes resources are used, such as GatewayClass, GatewayParameters, and a gateway proxy template that includes the Envoy configuration that each proxy is bootstrapped with. - -To learn more about the default setup and how these resources interact with each other, see the [Default gateway proxy setup]({{< link-hextra path="/setup/default/" >}}). diff --git a/assets/docs/pages/about/policies-index.md b/assets/docs/pages/about/policies-index.md deleted file mode 100644 index b571348d1..000000000 --- a/assets/docs/pages/about/policies-index.md +++ /dev/null @@ -1,41 +0,0 @@ -Learn more about the custom resources that you can use to apply policies in kgateway. - - -While the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} allows you to do simple routing, such as to match, redirect, or rewrite requests, you might want additional capabilities in your API gateway, such direct responses, local rate limiting, or request and response transformations. Policies allow you to apply intelligent traffic management, resiliency, and security standards to an HTTPRoute or Gateway. - -## Policy CRDs - -Kgateway uses the following custom resources to attach policies to routes and gateway listeners. - - -{{< cards >}} - {{< card link="../policies/backendconfigpolicy/" title="BackendConfigPolicy" subtitle="Configure connection settings to an upstream service." >}} - {{< card link="../../traffic-management/direct-response/" title="Direct response" subtitle="Directly respond to incoming requests with a custom HTTP response code and body." >}} - {{< card link="../policies/httplistenerpolicy/" title="HTTPListenerPolicy" subtitle="Apply policies to all HTTP and HTTPS listeners." >}} - {{< card link="../policies/trafficpolicy/" title="TrafficPolicy" subtitle="Attach policies to routes in an HTTPRoute or Gateway resource." >}} -{{< /cards >}} - - - -## Supported policies {#supported-policies} - -Review the policies that you can configure in kgateway and the level at which you can apply them. - -| Policy | Applied via | -| -- | -- | -| [Access logging](../../security/access-logging) | HTTPListenerPolicy | -| [Buffering](../../traffic-management/buffering)| {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} | -| [CSRF](../../security/csrf)| {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} | -| [Direct response](../../traffic-management/direct-response/) | DirectResponse | -| [Dynamic Forward Proxy (DFP)](../../traffic-management/dfp)| Backend and HTTPRoute | -| [External authorization](../../security/external-auth) | GatewayExtension and {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} | -| [External processing (ExtProc)](../../traffic-management/extproc/) | {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} | -| [Health checks for the Gateway](../../traffic-management/health-checks/gateway)| HTTPListenerPolicy | -| [Health checks for the Backends](../../traffic-management/health-checks/backend)| BackendConfigPolicy | -| [HTTP connection settings](../../resiliency/connection)| BackendConfigPolicy | -| [Outlier detection](../../resiliency/outlier-detection)| BackendConfigPolicy | -| [Rate limiting](../../security/ratelimit/) | {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} | -| [Session affinity - Simple load balancing](../../traffic-management/session-affinity/loadbalancing/) | BackendConfigPolicy | -| [Session affinity - Consistent hashing](../../traffic-management/session-affinity/consistent-hashing/) | BackendConfigPolicy | -| [TCP keepalive](../../resiliency/tcp-keepalive/) | BackendConfigPolicy | -| [Transformations](../../traffic-management/transformations) | {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} | \ No newline at end of file diff --git a/assets/docs/pages/about/policy-merging.md b/assets/docs/pages/about/policy-merging.md deleted file mode 100644 index d86cb85e5..000000000 --- a/assets/docs/pages/about/policy-merging.md +++ /dev/null @@ -1,86 +0,0 @@ -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} lets you define how policies are merged when they are applied to a parent and child resource. - -## About - -Parent-child hierarchies might be: - -* Resources that target or serve other resources, such as Gateway > ListenerSet > HTTPRoute > Route rule. -* Routes that are delegated, such as Parent HTTPRoute A > Child HTTPRoute B > Grandchild HTTPRoute C. - -Policy merging applies to the following policies: - -* Native Kubernetes Gateway API policies, such as rewrites, timeouts, or retries. -* {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. - -Resources that are higher in the parent-child hierarchy can use a special annotation to define how child resources inherit policies. This way, parent resources such as a Gateway or HTTPRoute can decide whether child resources can override the parent policies or not. - -## Merging annotation {#merging-annotation} - -The annotation on the parent resource is: `kgateway.dev/inherited-policy-priority`. - -You can use the following values for the annotation: - -- `ShallowMergePreferChild` (default): Child policies take precedence over parent policies and the policies are shallow merged. -- `ShallowMergePreferParent`: Parent policies take precedence over child policies and the policies are shallow merged. - -**Shallow merging** means that the policies are merged at the top level. Only the top-level fields of the policies are considered for merging. If a field is present in both parent and child policies, the value from the higher priority policy is used. Priority is typically determined by specificity and creation time. The more specific (such as HTTPRoute rule over all the routes in the HTTPRoute) and older (created-first) policy takes precedence. Consider the following shallow merge scenario: - -* Parent policy adds a `x-season=summer` header. -* Child policy adds `x-season=winter` and `x-holiday=christmas` headers. -* Merging annotation is the default value, `ShallowMergePreferChild`. - -Resulting merged policy: The parent's `x-season` header is not included in the merged policy because the strategy is `ShallowMergePreferChild`. - -| Header | Value | Source | -| -- | -- | -- | -| `x-season` | `winter` | Child | -| `x-holiday` | `christmas` | Child | - - - -## Merging examples {#merging-examples} - -For more information, check out the following guides: - -* {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}'s [Policy priority and merging rules](../trafficpolicy/#policy-priority-and-merging-rules) -* [Policy inheritance and overrides](../../../traffic-management/route-delegation/inheritance/) for both Kubernetes Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} policies. \ No newline at end of file diff --git a/assets/docs/pages/about/proxies.md b/assets/docs/pages/about/proxies.md deleted file mode 100644 index 04c2a15d5..000000000 --- a/assets/docs/pages/about/proxies.md +++ /dev/null @@ -1,36 +0,0 @@ -Learn more about the gateway proxies that the {{< reuse "/agw-docs/snippets/kgateway.md" >}} {{< gloss "Control Plane" >}}control plane{{< /gloss >}} supports. - -## About gateway proxies {#about} - -Gateway proxies are the {{< gloss "Data Plane" >}}data plane{{< /gloss >}} in your {{< reuse "/agw-docs/snippets/kgateway.md" >}} setup. The data plane handles traffic between clients and servers, or backend applications. - -The type of gateway proxy that you want to use depends on your use case, which is often related to the backend applications and the "direction" of the traffic. - -Backend applications are commonly accessed by clients through application programming interfaces (APIs). Hence, an "API gateway" is a common use case for a gateway proxy. For more information, see the [API gateway overview topic](../overview/#api-gateway). If the client is outside your cluster, you need an ingress gateway to handle this "north-south" traffic. If the client is within the cluster or service mesh, you need an "east-west" gateway. To control traffic that leaves your environment, you need an egress gateway. - -Increasingly, gateway proxies are designed to meet the challenges that are specific to artificial intelligence (AI) networking. In these scenarios, your backend applications might be cloud provider large language models (LLMs), your own LLMs and inferences, model context protocol (MCP) servers, agent-to-agent (A2A) servers, and similar AI use cases. - -The best gateway proxies offer you ways to configure advanced routing, load balancing, security enforcement, protocol translation, and more. They also generate metrics and logs that you can use to monitor and troubleshoot your traffic. - -## Architecture - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} is a control plane that manages the lifecycle of gateway proxies that adhere to the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io) spec. - -When you install {{< reuse "/agw-docs/snippets/kgateway.md" >}}, you automatically get GatewayClasses out of the box. When you create a Gateway resource based on one of these GatewayClasses, {{< reuse "/agw-docs/snippets/kgateway.md" >}} automatically spins up a gateway proxy for you. The gateway proxy controls the data plane that routes traffic to the backend services. {{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} then configures the data plane based on the Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} custom resources that you configure, such as HTTPRoutes and TrafficPolicies. This way, you can standardize the configuration of your gateway proxies with the same set of open source resources. - -For more information, see the other docs in this [About](../) section. - -## Supported gateway proxies {#supported} - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} supports the following gateway proxies. You can use both gateway proxies in the same Kubernetes cluster, depending on your use case. - -{{< reuse "agw-docs/snippets/control-plane-note.md" >}} - -| Gateway proxy | Primary use cases | Description | -| --- | --- | --- | -| {{< icon "kgateway" >}} kgateway | API, ingress, egress, service mesh | The kgateway project includes its own proxy that is based on Envoy, an L3/L4/L7 network proxy. Beyond Envoy, kgateway provides a set of extensions for advanced configuration, security, and traffic management features. You can also integrate kgateway with the Istio service mesh in sidecar and ambient modes. For more information, see the [kgateway FAQs](../../faqs/) and [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/intro/what_is_envoy). | -| {{< icon "agentgateway" >}} agentgateway | AI, A2A, MCP, LLM, Inference Extension | Agentgateway is an enterprise-grade gateway data plane that provides AI connectivity for agents and tools in any environment. | - -## Reserved ports - -{{< reuse "agw-docs/snippets/reserved-ports.md" >}} \ No newline at end of file diff --git a/assets/docs/pages/about/trafficpolicy.md b/assets/docs/pages/about/trafficpolicy.md deleted file mode 100644 index 3cec25aeb..000000000 --- a/assets/docs/pages/about/trafficpolicy.md +++ /dev/null @@ -1,322 +0,0 @@ -Use a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to attach policies to one, multiple, or all routes in an HTTPRoute resource, or all the routes that a Gateway serves. - -## Policy attachment {#policy-attachment-TrafficPolicy} - -You can apply {{< reuse "agw-docs/snippets/trafficpolicies.md" >}} to all routes in an HTTPRoute resource or only to specific routes. - -{{< callout type="info" >}} -By default, you must attach policies to resources that are in the same namespace. To create global policies that can attach to resources in any namespace, see the [Global policy attachment](../global-attachment/) guide. -{{< /callout >}} - -### All HTTPRoute routes {#attach-to-all-routes} - -You can use the `spec.targetRefs` section in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to apply policies to all the routes that are specified in a particular HTTPRoute resource. - -The following example {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource specifies transformation rules that are applied to all routes in the `httpbin` HTTPRoute resource. - -```yaml {hl_lines=[7,8,9,10]} -apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: transformation - namespace: httpbin -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - set: - - name: x-kgateway-response - value: '{{ request_header("x-kgateway-request") }}' -``` - -You can also apply the same {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to multiple HTTPRoutes by referencing them in the `targetRefs` section, as shown in the following example. - -```yaml {hl_lines=[7,8,9,10,11,12,13,14,15,16]} -apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: transformation - namespace: httpbin -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: petstore - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: echo - transformation: - response: - set: - - name: x-kgateway-response - value: '{{ request_header("x-kgateway-request") }}' -``` - - -### Individual route {#attach-to-route} - -Instead of applying the policy to all routes that are defined in an HTTPRoute resource, you can apply them to specific routes by using the `ExtensionRef` filter in the HTTPRoute resource. - -{{< callout type="warning" >}} -Attaching a policy via the `ExtensionRef` filter is legacy behavior and might be deprecated in a future release. Instead, use the [HTTPRoute rule attachment option](#attach-to-rule) to apply a policy to an individual route, which requires the Kubernetes Gateway API experimental channel version 1.3.0 or later. Also, the `ExtensionRef` filter is not supported for agentgateway proxies. -{{< /callout >}} - -The following example shows a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource that defines a transformation rule. Note that the `spec.targetRef` field is not set. Because of that, the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} does not apply until it is referenced in an HTTPRoute by using the `ExtensionRef` filter. - -```yaml -apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: transformation - namespace: httpbin -spec: - transformation: - response: - set: - - name: x-kgateway-response - value: '{{ request_header("x-kgateway-request") }}' -``` - -To apply the policy to a particular route, you use the `ExtensionRef` filter on the desired HTTPRoute route. In the following example, the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} is applied to the `/anything/path1` route. However, it is not applied to the `/anything/path2` path. - -```yaml {hl_lines=[17,18,19,20,21,22]} -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: httpbin-policy - namespace: httpbin -spec: - parentRefs: - - name: http - namespace: kgateway-system - hostnames: - - TrafficPolicy.example - rules: - - matches: - - path: - type: PathPrefix - value: /anything/path1 - filters: - - type: ExtensionRef - extensionRef: - group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - name: transformation - backendRefs: - - name: httpbin - port: 8000 - - matches: - - path: - type: PathPrefix - value: /anything/path2 - backendRefs: - - name: httpbin - port: 8000 -``` - -### HTTPRoute rule {#attach-to-rule} - -{{< callout type="info" >}} -To use this feature, you must install the Kubernetes Gateway API experimental channel version 1.3.0 or later. -{{< /callout >}} - -Instead of using the `extensionRef` filter to apply a policy to a specific route, you can attach a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to an HTTPRoute rule by using the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}'s `targetRefs.sectionName` option. - -You can also use this attachment option alongside the `extensionRef` filter. However, policies that are attached via the `extensionRef` filter take precedence over policies that are attached via the `targetRefs.sectionName` option. - -The following HTTPRoute defines two HTTPRoute rules that both route traffic to the httpbin app. -```yaml -kubectl apply -f- <}} to a specific HTTPRoute rule (`rule1`), use the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}'s `targetRefs.sectionName` option as shown in the following example. - -```yaml -kubectl apply -f- <}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: local-ratelimit - namespace: kgateway-system -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - sectionName: rule1 - rateLimit: - local: - tokenBucket: - maxTokens: 1 - tokensPerFill: 1 - fillInterval: 100s -EOF -``` - -### Gateway {#attach-to-gateway} - -Some policies, such as a local rate limiting policy, can be applied to all the routes that the Gateway serves. This way, you can apply gateway-level rules and do not have to keep track of new HTTPRoutes that are attached to the Gateway in your environment. - -To attach a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to a Gateway, you simply use the `targetRefs` section in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to reference the Gateway you want the policy to apply to as shown in the following example. - -```yaml -apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: local-ratelimit - namespace: kgateway-system -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - rateLimit: - local: - tokenBucket: - maxTokens: 1 - tokensPerFill: 1 - fillInterval: 100s -``` - -### Gateway listener {#attach-to-listener} - -Instead of applying a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to all the routes that the Gateway serves, you can select specific Gateway listeners by using the `targetRefs.sectionName` option. - -The following Gateway resource defines two listeners, an HTTP (`http`) and HTTPS (`https`) listener. - -```yaml -kind: Gateway -apiVersion: gateway.networking.k8s.io/v1 -metadata: - name: http - namespace: kgateway-system -spec: - gatewayClassName: kgateway - listeners: - - name: http - protocol: HTTP - port: 8080 - allowedRoutes: - namespaces: - from: All - - name: https - port: 443 - protocol: HTTPS - tls: - mode: Terminate - certificateRefs: - - name: https - kind: Secret - allowedRoutes: - namespaces: - from: All -``` - -To apply the policy to only the `https` listener, you specify the listener name in the `spec.targetRefs.sectionName` field in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource as shown in the following example. - -```yaml -apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: local-ratelimit - namespace: kgateway-system -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - sectionName: https - rateLimit: - local: - tokenBucket: - maxTokens: 1 - tokensPerFill: 1 - fillInterval: 100s -``` - -## Policy priority and merging rules - -If you apply multiple {{< reuse "agw-docs/snippets/trafficpolicies.md" >}} by using different attachment options, policies are merged based on specificy and priority. - -By default, the following rules apply. You can update the behavior by using the `kgateway.dev/inherited-policy-priority` annotation. For more information, see [Policy merging]({{< link-hextra path="/about/policies/merging/" >}}). - -* If you apply multiple {{< reuse "agw-docs/snippets/trafficpolicies.md" >}} that define the same top-level policy, the policies are not merged and only the oldest policy is enforced. Policies with a later timestamp are ignored. -* {{< reuse "agw-docs/snippets/trafficpolicies.md" >}} that define different top-level policies are merged and are enforced in combination. -* In addition to the timestamp, the attachment option of a policy determines the policy priority. In general, more specific policy targets have higher priority and take precedence over less specific policies. For example, a policy targeting an individual route has higher priority than a policy targeting all the routes in an HTTPRoute resource. However, keep in mind that these rules might be different in a route delegation setup. For more information, see [Policy inheritance and overrides in delegation setups](#delegation). -* Lower priority policies can augment higher priority policies by defining other top-level policies. For example, if you already attached a local rate limiting policy to a Gateway listener by using the `targetRefs.sectionName` option, you can add another {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that defines a transformation policy and apply that policy to the entire Gateway. -* Native Kubernetes Gateway API policies have higher priority than any kgateway-native policies that must be attached via the `targetRefs` or `extensionRef` option. - -### Priority order - -Review the following Gateway and HTTPRoute policy priorities, sorted from highest to lowest. - -**Gateway**: - -| Priority | Attachment option | Description | -| -- | -- | -- | -| 1 | [Gateway listener policy](#attach-to-listener) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that references a Gateway listener by using the `targetRefs.sectionName` field has the highest priority. Note that if you have multiple Gateway listener policies that define the same top-level policy, only the one with the oldest timestamp is applied. | -| 2 | [Gateway policy](#attach-to-gateway) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that references a Gateway in the `targetRefs` section has the lowest priority. This policy can still augment any higher priority policies by defining different top-level policies. Note that if you have multiple Gateway policies that all define the same top-level policy, only the one with the oldest timestamp is applied. | - -**HTTPRoute**: - -| Priority | Attachment option | Description | -| -- | -- | -- | -| 1 | [Individual HTTPRoute policy](#attach-to-route) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that is attached to an individual route by using the `extensionRef` filter in the HTTPRoute has the highest priority. Note that if you have multiple HTTPRoute policies that are attached via the `extensionRef` option and all define the same top-level policy, only the one with the oldest timestamp is applied. | -| 2 | [HTTPRoute rule policy](#attach-to-rule) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that is attached to an HTTPRoute rule by using the `targetRefs.sectionName` option has a lower priority. This policy can still augment any `extensionRef` policies by defining different top-level policies. Note that if you have multiple HTTPRoute rule policies and all define the same top-level policy, only the one with the oldest timestamp is applied. | -| 3 | [All HTTPRoute routes policy](#attach-to-all-routes) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that is attached to all routes in an HTTPRoute resource by using the `targetRefs` option has the lowest priority. You can still augment any higher priority policies by defining different top-level policies. If you have multiple HTTPRoute rule policies and they all specify the same top-level policy, only the one with the oldest timestamp is applied. | - -{{< callout type="info" >}} -If you apply a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with the same top-level policy to a Gateway and an HTTPRoute, the policy on the HTTPRoute takes precedence and the one on the Gateway is ignored. For example, you might have two local rate limiting policies. One is applied to a Gateway and one is applied to the HTTPRoute. Because the same top-level policy is defined, the policy on the HTTPRoute is considered higher priority and therefore enforced. -{{< /callout >}} - -### Policy inheritance and overrides in delegation setups {#delegation} - -The way policies are inherited along the route delegation chain depends on the type of policy that you want to apply. - -#### Native Gateway API policies - -{{< reuse "agw-docs/snippets/policy-inheritance-native.md" >}} - -For an example, see the policy inheritance guide for [Native Gateway API policies]({{< link-hextra path="/traffic-management/route-delegation/inheritance/native-policies/" >}}). - -#### Kgateway policies - -{{< reuse "agw-docs/snippets/policy-inheritance.md" >}} - -For an example, see the policy inheritance guide for [kgateway policies]({{< link-hextra path="/traffic-management/route-delegation/inheritance/kgateway-policies/" >}}). - diff --git a/assets/docs/pages/agentgateway/about.md b/assets/docs/pages/agentgateway/about.md deleted file mode 100644 index df6e1f742..000000000 --- a/assets/docs/pages/agentgateway/about.md +++ /dev/null @@ -1,45 +0,0 @@ -{{< reuse "agw-docs/snippets/agentgateway/about.md" >}} - -Agentgateway supports many agent connectivity use cases, including the following: - -* Agent-to-agent (A2A) -* Model Context Protocol (MCP) -* REST APIs as agent-native tools -* AI routing to cloud and local large language models (LLMs) -* Support for the Gateway API Inference Extension project - -## Architecture - -For more information about how kgateway integrates with agentgateway, see the [Architecture](../../about/architecture/) topic. - -For more information about agentgateway resources, see the [Agentgateway upstream docs](https://agentgateway.dev/docs/about/). - -## Agentgateway resource configuration {#resources} - -Review the following table to understand how to configure agentgateway resources in {{< reuse "/agw-docs/snippets/kgateway.md" >}}. - -| Agentgateway resource | Description | Configured in {{< reuse "/agw-docs/snippets/kgateway.md" >}} by | -| -- | -- | -- | -| Bind | The set of port bindings that associate gateway listeners with specific network ports. The bind has a unique key in the format `port/namespace/name`, such as `8080/default/my-gateway` with the value being the port number, such as `8080`. | Created automatically based on the Gateway and each unique port across Gateway listeners or ListenerSets. | -| Port | The port to listen on. Each port has a set of listeners that in turn have their own routes with policies and backends. | Ports in a Gateway or ListenerSet. | -| Listener | Listener configuration for how agentgateway accepts and processes incoming requests. Listeners can each have their own set of routes with policies and backends. | Listeners in a Gateway or ListenerSet. | -| Route | Routing rules for how agentgateway routes incoming requests to the appropriate backend. | Routing resources such as HTTPRoute, GRPCRoute, TCPRoute, and TLSRoute. | -| Backend | The backing destination where traffic is routed. Unlike other resources, backends are global resources (not per-gateway) that are applied to all Gateways that use agentgateway. Each backend has a unique name in the format: `namespace/name`. Backend types include AI for model-specific LLM provider configuration, static host or IP addresses, and virtual MCP servers, including A2A use cases. | Services and Backends. | -| Target | The details of the backend, such as the tools in an MCP backend. | Services and Backends. | -| Policies | Policies for how agentgateway processes incoming requests. | Policies in HTTPRoutes and Backends. | - - - \ No newline at end of file diff --git a/assets/docs/pages/agentgateway/agent/a2a.md b/assets/docs/pages/agentgateway/agent/a2a.md deleted file mode 100644 index a3bb65ef7..000000000 --- a/assets/docs/pages/agentgateway/agent/a2a.md +++ /dev/null @@ -1,236 +0,0 @@ -With {{< reuse "agw-docs/snippets/agentgateway.md" >}}, you can route to agent-to-agent (A2A) servers and expose their tools securely. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - - - -## Step 1: Deploy an A2A server {#a2a-server} - -Deploy an A2A server that you want {{< reuse "agw-docs/snippets/agentgateway.md" >}} to proxy traffic to. Notice that the Service uses the `appProtocol: kgateway.dev/a2a` setting. This way, {{< reuse "agw-docs/snippets/kgateway.md" >}} configures the {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy to use the A2A protocol. - -```yaml -kubectl apply -f- <}} - rules: - - backendRefs: - - name: a2a-agent - port: 9090 -EOF -``` - -## Step 3: Verify the connection {#verify} - -1. Get the agentgateway address. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80 - ``` - {{% /tab %}} - {{< /tabs >}} - -2. As a user, send a request to the A2A server. As an assistant, the agent echoes back the message that you sent. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -X POST http://$INGRESS_GW_ADDRESS/ \ - -H "Content-Type: application/json" \ - -v \ - -d '{ - "jsonrpc": "2.0", - "id": "1", - "method": "tasks/send", - "params": { - "id": "1", - "message": { - "role": "user", - "parts": [ - { - "type": "text", - "text": "hello gateway!" - } - ] - } - } - }' | jq - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - curl -X POST http://localhost:8080/ \ - -H "Content-Type: application/json" \ - -v \ - -d '{ - "jsonrpc": "2.0", - "id": "1", - "method": "tasks/send", - "params": { - "id": "1", - "message": { - "role": "user", - "parts": [ - { - "type": "text", - "text": "hello gateway!" - } - ] - } - } - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```json - { - "jsonrpc": "2.0", - "id": "1", - "result": { - "id": "1", - "message": { - "role": "assistant", - "parts": [ - { - "type": "text", - "text": "hello gateway!" - } - ] - } - } - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete Deployment a2a-agent -kubectl delete Service a2a-agent -kubectl delete HTTPRoute a2a -``` \ No newline at end of file diff --git a/assets/docs/pages/agentgateway/agent/about.md b/assets/docs/pages/agentgateway/agent/about.md deleted file mode 100644 index f83e68d82..000000000 --- a/assets/docs/pages/agentgateway/agent/about.md +++ /dev/null @@ -1,66 +0,0 @@ -Learn about what agents are and how they work. - -## About A2A - -Agent-to-agent, or [A2A](https://github.com/a2aproject/A2A), is an open protocol that enables communication and interoperability between opaque agentic applications. Developed by Google, A2A defines a common language that enables agents to show their capabilities and help them negotiate how they interact with the user, such as via text, forms, or bidirectional audio or video, irrespective of the framework or vendor they are built on. - -With A2A, agents can: - -* Discover each other's capabilities. -* Negotiate interaction modalities (text, forms, media). -* Securely collaborate on long running tasks. -* Operate without exposing their internal state, memory, or tools. - -## What are agents? - -An artificial intelligence (AI) agent is an application that can interact with users in natural language. Agents use LLM to generate responses to user queries and decide whether to call external tools to execute actions on behalf of the user. - -LLMs are limited by static training data. This limitation can make seemingly simple questions difficult to answer. For example, consider the following question: - -> What's the weather today? - -The LLM has to know several pieces of real-time information that it was not trained on: - -* The user's location -* The current date -* The weather forecast for that date and location - -With agents and tools, you can extend the capabilities of the LLM with your own external APIs, apps, and data. First, you create _tools_ that extend the capabilities of the LLM with a function, such as `get_weather`. These functions can include _parameters_, or inputs, that are needed to execute the function. For example, the `get_weather` function needs the date and location to get the current weather forecast. The _name_ and _description_ of the tool function and parameters help the LLM decide when to call the tool. - -Next, when forwarding user requests to the LLM, you can include the set of tools that the LLM can leverage to answer the user. Based on the user's question, the LLM can respond directly or suggest a tool to call to help answer the question. To get the required parameters for the tool call, the LLM might ask the end user or call other functions like `get_location` or `get_date`, which in turn might pull that information based on system settings on the end user's device. - -### Agent sequence diagram {#diagram} - -Consider the following sequence diagram that shows how agents and tools work. - -```mermaid -sequenceDiagram - autonumber - User->>+Agent: "What's the weather in Columbus?" - Agent->>+LLM: Forward user request along with tool list - LLM-->>-Agent: Suggest tool call (get_weather) - Agent-->>+App: Send tool suggestion - App->>-App: Execute tool (get_weather) - App->>+Agent: Send tool result - Agent->>+LLM: Forward tool result - LLM-->>+Agent: Generate final response - Agent-->>-User: "The weather in Columbus is 15°C and cloudy." -``` - -1. The User asks about the weather today. The request includes a list of tools that the LLM can use to answer the question. - -2. The agent sends the request with the tool list to the LLM. - -3. Based on the conversation, the LLM suggests to call the get_weather tool and includes the required parameters to use that tool. The LLM might get these parameters by using the chat history, asking the end user to provide them, or by suggesting other tools to call before calling the get_weather function. - -4. The agent invokes the get_weather tool by sending a request to the App. The request includes the required parameters to execute the tool. - -5. The App executes the get_weather tool with the required parameters to get the current weather in the location, such as Columbus, OH. - -6. The App returns the tool result to the agent. - -7. The agent returns the tool result to the LLM. - -8. The LLM uses the real-time tool result from the App in a natural language response and returns this response to the agent. - -9. The agent then forwards the natural language response to the User. diff --git a/assets/docs/pages/agentgateway/configuration.md b/assets/docs/pages/agentgateway/configuration.md deleted file mode 100644 index b7f33013e..000000000 --- a/assets/docs/pages/agentgateway/configuration.md +++ /dev/null @@ -1,208 +0,0 @@ -Customize your agentgateway proxy with {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}. - -## About customizing your proxy {#upstream-configuration} - -In upstream agentgateway, you can manage [configuration](https://agentgateway.dev/docs/configuration/overview/) via a YAML or JSON file. The configuration features of agentgateway are captured in the [schema of the agentgateway codebase](https://github.com/agentgateway/agentgateway/tree/main/schema). - -Unlike in the upstream agentgateway project, you do not configure these features in a raw configuration file in the agentgateway proxy. Instead, you configure them in a Kubernetes Gateway API-native way as explained in the guides throughout this doc set. - -However, you still might want to pass in custom configuration to your agentgateway proxy. This can be useful in the following use cases: - -- Migrating from upstream to {{< reuse "/agw-docs/snippets/agw-kgw.md" >}}. -- Using a feature that is not yet exposed via the Kubernetes Gateway or {{< reuse "/agw-docs/snippets/agw-kgw.md" >}} APIs. - - - -You can choose between the following options to provide custom configuration to your agentgateway proxy. - -* **Embed in {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} CRD directly (recommended)**: You can add your custom configuration to the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} custom resource directly. This way, your configuration is validated when you apply the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource in your cluster. Keep in mind that not all upstream configuration options, such as `binds`, are currently supported in the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. For supported options, see the [API reference]({{< link-hextra path="/reference/api/#agentgatewayparametersspec" >}}). -* **`rawConfig`**: For configuration that cannot be embedded into the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource directly, or if you prefer to pass in raw upstream configuration, you can use the `rawConfig` option in the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource instead. Note that configuration is not automatically validated. If configuration is malformatted or includes unsupported fields, the agentgateway proxy does not start. You can run `kubectl logs deploy/agentgateway-proxy -n agentgateway-system` to view the logs of the proxy and find more information about why the configuration could not be applied. - - - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}). - -## Step 1: Create agentgateway configuration {#agentgateway-configuration} - - - - -Choose between the following options to provide your agentgateway configuration: - -* [Embed in {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}](#embed) -* [`rawConfig`](#rawconfig) - -### Embed in {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} {#embed} - -You can add your custom configuration to the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} custom resource directly. This way, your configuration is validated when you apply the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource in your cluster. - -1. Create an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource with your custom configuration. The following example changes the logging format from `text` to `json`. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - metadata: - name: agentgateway-config - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - logging: - format: json - EOF - ``` - -2. Create a Gateway resource that sets up an agentgateway proxy that uses your {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}. - - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - infrastructure: - parametersRef: - name: agentgateway-config - group: {{< reuse "agw-docs/snippets/gatewayparam-group.md" >}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - listeners: - - name: http - port: 3030 - protocol: HTTP - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. Check the pod logs to verify that the agentgateway logs are displayed in JSON format. - ```sh - kubectl logs deployment/agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ``` - {"level":"info","time":"2025-12-16T15:58:18.245219Z","scope":"agent_core::readiness","message":"Task 'agentgateway' complete (2.378042ms), still awaiting 1 tasks"} - {"level":"info","time":"2025-12-16T15:58:18.245221Z","scope":"agentgateway::management::hyper_helpers","message":"listener established","address":"127.0.0.1:15000","component":"admin"} - {"level":"info","time":"2025-12-16T15:58:18.245231Z","scope":"agentgateway::management::hyper_helpers","message":"listener established","address":"[::]:15020","component":"stats"} - {"level":"info","time":"2025-12-16T15:58:18.248025Z","scope":"agent_xds::client","message":"Stream established","xds":{"id":1}} - {"level":"info","time":"2025-12-16T15:58:18.248081Z","scope":"agent_xds::client","message":"received response","type_url":"type.googleapis.com/agentgateway.dev.workload.Address","size":44,"removes":0,"xds":{"id":1}} - ``` - -### `rawConfig` - -Use the `rawConfig` option to pass in raw upstream configuration to your agentgateway proxy. Note that the configuration is not automatically validated. If configuration is malformatted or includes unsupported fields, the agentgateway proxy does not start. You can run `kubectl logs deploy/agentgateway-proxy -n agentgateway-system` to view the logs of the proxy and find more information about why the configuration could not be applied. - -1. Create an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource with your custom configuration. The following example sets up a simple direct response listener on port 3000 that returns a `200 OK` response with the body `"hello!"` for requests to the `/direct` path. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - metadata: - name: agentgateway-config - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - rawConfig: - binds: - - port: 3000 - listeners: - - protocol: HTTP - routes: - - name: direct-response - matches: - - path: - pathPrefix: /direct - policies: - directResponse: - body: "hello!" - status: 200 - EOF - ``` - -2. Create a Gateway resource that sets up an agentgateway proxy that uses your {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}. Set the port to a dummy value like `3030` to avoid conflicts with the binds defined in your {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. - - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - infrastructure: - parametersRef: - name: agentgateway-config - group: {{< reuse "agw-docs/snippets/gatewayparam-group.md" >}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - listeners: - - name: http - port: 3030 - protocol: HTTP - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. Check the pod logs to verify that agentgateway loaded the configuration from the ConfigMap, such as by searching for the port binding. - - ```bash - kubectl logs deployment/agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}} | grep 3000 - ``` - - Example output: - - ``` - 2025-10-28T13:47:01.116095Z info proxy::gateway started bind bind="bind/3000" - ``` - -4. Send a test request. - - * **Cloud Provider LoadBalancer**: - 1. Get the external address of the gateway proxy and save it in an environment variable. - - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} agentgateway-config -o=jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - - 2. Send a request along the `/direct` path to the agentgateway proxy through port 3000. - ```sh - curl -i http://$INGRESS_GW_ADDRESS:3000/direct - ``` - * **Port-forward for local testing** - 1. Port-forward the `agentgateway-config` pod on port 3000. - ```sh - kubectl port-forward deployment/agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}} 3000:3000 - ``` - - 2. Send a request to verify that you get back the expected response from your direct response configuration. - ```sh - curl -i localhost:3000/direct - ``` - - Example output: - - ```txt - HTTP/1.1 200 OK - content-length: 6 - date: Tue, 28 Oct 2025 14:13:48 GMT - - hello! - ``` - -{{< /version>}} - - -## Clean up - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```bash -kubectl delete Gateway agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` diff --git a/assets/docs/pages/agentgateway/gateway-api.md b/assets/docs/pages/agentgateway/gateway-api.md deleted file mode 100644 index b057dbb8a..000000000 --- a/assets/docs/pages/agentgateway/gateway-api.md +++ /dev/null @@ -1,70 +0,0 @@ -Agentgateway is based on the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/). -Gateway API is an official Kubernetes project that focuses on managing L4 and L7 traffic routing in Kubernetes environments. -Along with core functionality, Gateway API provides a rich set of extension points for advanced use cases. -Agentgateway uses these extension points to provide functionality beyond what is provided by the core Kubernetes API. - -## Conformance - -Unlike other implementations of Gateway API, agentgateway is the only data plane designed from the ground up for -Kubernetes. -As a result, agentgateway offers some of the most comprehensive support for the Gateway API. - -You can review the conformance test results by version in the [Gateway API docs](https://gateway-api.sigs.k8s.io/implementations/#conformance-levels). For example, as of the time of this writing, agentgateway is the only implementation of Gateway API that passes all conformance tests for Gateway API v1.3. - -In addition to supporting all Core and Extended Gateway API features, Gateway API has a number of "experimental" -features that are in development. -Agentgateway supports many of these experimental features, as shown in the following table. - -| Feature | GEP | Status | -|---------------------------------------------------------------------------|-----------------------------------------------------------|-----------------------------------------| -| Client Certificate Validation for TLS terminating at the Gateway Listener | [GEP-91](https://gateway-api.sigs.k8s.io/geps/gep-91) | ✅ Supported | -| HTTP Auth | [GEP-1494](https://gateway-api.sigs.k8s.io/geps/gep-1494) | ✅ Supported | -| Session Persistence | [GEP-1619](https://gateway-api.sigs.k8s.io/geps/gep-1619) | ❌ Unsupported | -| ListenerSets | [GEP-1713](https://gateway-api.sigs.k8s.io/geps/gep-1713) | ✅ Supported | -| HTTPRoute Retries | [GEP-1731](https://gateway-api.sigs.k8s.io/geps/gep-1731) | ✅ Supported | -| Gateway API Interaction with Multi-Cluster Services | [GEP-1748](https://gateway-api.sigs.k8s.io/geps/gep-1748) | ❌ Unsupported | -| CORS Filter | [GEP-1767](https://gateway-api.sigs.k8s.io/geps/gep-1767) | ✅ Supported | -| TLS based passthrough Route / TLSRoute | [GEP-2643](https://gateway-api.sigs.k8s.io/geps/gep-2643) | ✅ Supported | -| Complete Backend mutual TLS Configuration | [GEP-3155](https://gateway-api.sigs.k8s.io/geps/gep-3155) | ❌ Unsupported (supported via extension) | -| Retry Budgets | [GEP-3388](https://gateway-api.sigs.k8s.io/geps/gep-3388) | ❌ Unsupported | -| Gateway TLS Updates for HTTP/2 Connection Coalescing | [GEP-3567](https://gateway-api.sigs.k8s.io/geps/gep-3567) | ✅ Supported | - -## Extensions - -To add functionality that is missing in the core Gateway API, agentgateway provides a number of extensions. -Some of these add completely novel functionality, such as support for the MCP protocol, while others provide more rich -functionality for existing features. - -This section describes the extensions that overlap with the core Gateway API. -For a full list of extensions, refer to the rest of the documentation. - -When a feature is implemented in both the core Gateway API and an extension, you have the choice to use either API. -- If you value building on the portable standard and do not require the additional functionality, then use the core Gateway API. -- If you require the additional functionality, or want the ability to expand to use additional functionality in the future without requiring a migration, then use the agentgateway extension. - -| Feature | Gateway API | Agentgateway extension | Differences | -|-----------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| -| Originating TLS to backends | [BackendTLSPolicy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/) | `AgentgatewayPolicy` `.backend.tls` | Agentgateway supports mutual TLS (mTLS), automatic SNI and SAN validation, ALPN customization, and the ability to (optionally) disable TLS verification. | -| Header manipulation | [HTTPRoute header modifier](https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional) | `AgentgatewayPolicy` `.traffic.transformation` | Agentgateway supports setting headers based on CEL expressions, rather than just static values. | -| External Authorization | [HTTPRoute ExternalAuth filter](https://gateway-api.sigs.k8s.io/geps/gep-1494/) | `AgentgatewayPolicy` `.traffic.extAuth` | Agentgateway supports more advanced configuration, such as automatic redirects (to sign-in pages), and more control over request and response processing. | -| HTTP Filters | [Filters inline in HTTPRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional) | `AgentgatewayPolicy` `.traffic` | Agentgateway allows all policies to be either configured as inline HTTPRoute filters, or as standalone policies attached to objects like Gateway and HTTPRoute, allowing more flexibility and re-use. | - -## Comparison with other implementations {#implementations} - -The Kubernetes Gateway API has more than 40 [implementations](https://gateway-api.sigs.k8s.io/implementations/) at the time of this writing. -If you are in the process of evaluating a Gateway API implementation, consider the following factors: - - - -**Conformance level**: Is the implementation up to date? The Gateway API docs [set three levels of conformance](https://gateway-api.sigs.k8s.io/implementations/#conformance-levels), depending on the level of commitment to the Gateway API by version. -- Prefer conformant implementations that pass tests for the past two releases of the Gateway API, such as kgateway with agentgateway. -- Review the release version-specific conformance reports. If an implementation is not listed, then it might be stale. Many implementations have not been updated for years, making them incompatible with the latest API. -- Confirm that the implementation is generally available. Some implementations might be in beta or alpha, and not yet ready for production use. - -**Feature coverage**: Is the implementation correctly implementing the Gateway API specification for features that you use? -- Evaluate each implementation's conformance report for the version that you want to use. Unlike other conformance programs, Gateway API conformance **does not require passing all (or any) tests**, and instead lets implementations skip features. -- Confirm that basic functionality like HTTP Method matching, request timeouts, and so forth are supported by the implementation. Remember that because implementations can skip features, even a "passing" conformance report does not indicate basic functionality. - -**Real-world performance**: Does the implementation behave well in real world scenarios? -- Consider that the conformance reports evaluate the correctness of an implementation in a simple environment. They do not test whether the implementation can scale up to thousands of routes, handle rapidly changing configuration, or gracefully handle changes without downtime. -- Review the unofficial [Gateway API Benchmarks](https://github.com/howardjohn/gateway-api-bench) as a starting point for evaluating the behavior of a Gateway API implementation. Agentgateway is featured in [Part 2](https://github.com/howardjohn/gateway-api-bench/blob/main/README-v2.md)! diff --git a/assets/docs/pages/agentgateway/guardrails.md b/assets/docs/pages/agentgateway/guardrails.md deleted file mode 100644 index 8e149d8e3..000000000 --- a/assets/docs/pages/agentgateway/guardrails.md +++ /dev/null @@ -1,419 +0,0 @@ -Use the Guardrail Webhook API to set up your own custom guardrail controls for {{< reuse "agw-docs/snippets/agentgateway.md" >}}. - -## About guardrails {#about} - -Guardrails are control mechanisms that help ensure safe, consistent, and compliant interactions with large language models (LLMs) by validating both input and output content. - -### Benefits of guardrails {#about-benefits} - -Because LLMs generate text based on probability calculations and training data that is outside your control and business context, their responses can vary widely. LLMs might hallucinate, generate harmful or unhelpful content, leak sensitive data, or otherwise return unexpected responses that are not aligned with your organization's standards. - -Guardrails mitigate such risks by letting you take action on: - -* Input, or the content before sending requests to the LLM. -* Output, or the content before delivering responses to the user. - -For example, a guardrail might: - -* Scan input and mask sensitive data patterns before they reach the LLM, such as employee IDs or other personally identifiable information (PII). -* Verify that LLM responses follow a required JSON structure before returning them to users. - -By applying guardrails to both input and output, you can: - -* Reject or mask harmful or unhelpful content. -* Enforce desired formats, content boundaries, and safety rules. -* Comply with regulatory requirements, industry standards, internal policies, style guides, and more. - -### Support for guardrails {#about-guardrail-support} - -{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} includes built-in [prompt guards](../../prompt-guards/) to reject, mask, or pass prompt data through a moderation endpoint. - -However, you might want to bring your own guardrails for situations such as: - -* Small language models (SMLs) that do not have a moderation endpoint but that you want to use to sanitize input or output. -* Advanced guards and moderation rules that are not part of {{< reuse "agw-docs/snippets/agentgateway.md" >}} or the LLM provider's moderation endpoint. -* Full control over safety and compliance logic. -* Centralized enforcement across multiple models and providers. -* The ability to update your policies without redeploying the gateway proxy or models. -* Extra logging and auditing capabilities that are built into your own guardrail implementation. - -To support such advanced scenarios, {{< reuse "agw-docs/snippets/agentgateway.md" >}} includes a Guardrail Webhook API that you can use to bring your own guardrails. This way, your webhook server can integrate with {{< reuse "agw-docs/snippets/agentgateway.md" >}} to process requests synchronously before they reach the LLM and responses before they return to the user. This architecture allows for flexible integration with your existing security and compliance tools. - -### Example diagram {#example-diagram} - -The following diagram shows a simple sequence of how the Guardrail Webhook API lets your webhook server integrate with {{< reuse "agw-docs/snippets/agentgateway.md" >}} to process LLM requests and responses. - -```mermaid -sequenceDiagram - participant Client - participant Gateway as Agentgateway - participant Webhook as Guardrail Webhook - participant LLM - - Client->>Gateway: Send prompt - Gateway->>Webhook: Pre-request guardrail check - Webhook-->>Gateway: Allow/Modify/Reject - - alt Request Allowed - Gateway->>LLM: Forward prompt - LLM-->>Gateway: Generate response - Gateway->>Webhook: Post-response guardrail check - Webhook-->>Gateway: Allow/Modify/Reject - Gateway-->>Client: Return response - else Request Rejected - Webhook-->>Gateway: Return rejection - Gateway-->>Client: Forward rejection - end -``` - -1. The client sends a request to the LLM. -2. {{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} receives the request and passes it to the webhook server for a pre-request guardrail check. -3. If the request is allowed, {{< reuse "agw-docs/snippets/agentgateway.md" >}} forwards the request to the LLM. The LLM generates a response that the webhook server can modify before {{< reuse "agw-docs/snippets/agentgateway.md" >}} returns the response to the client. -4. If the request is rejected by the Guardrail Webhook, {{< reuse "agw-docs/snippets/agentgateway.md" >}} forwards the rejection to the client. - -### Considerations for using guardrails {#about-considerations} - -When implementing a guardrail webhook server, consider the following performance, implementation, and operational factors. - -* **Performance impact**: Each guardrail check adds latency to the request-response cycle. Plan accordingly, such as deploying the webhook server close to the gateway proxy to minimize latency and implementing resiliency best practices such as timeouts and horizontal scaling. -* **Implementation challenges**: Your webhook server must handle requests synchronously and respond quickly to avoid user experience degradation. The requests might be streaming or non-streaming. -* **Operational responsibilities**: You are responsible for developing, integrating, and operating your own guardrail webhook server. - -### Optimize guardrail webhook performance {#optimize-performance} - -To optimize guardrail webhook performance, you can update the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} for {{< reuse "agw-docs/snippets/agentgateway.md" >}} with the following settings. - -* `GUARDRAIL_WEBHOOK_MAX_CONNECTIONS`: The maximum number of concurrent connections that the gateway can open to the webhook server. A value of `0` means no limit. The default value is `100`. Higher values allow for greater concurrency, which is good for high-throughput systems, such as when many user requests trigger requests to the webhook server. Lower values help reduce resource usage and the risk of overwhelming the webhook server. -* `GUARDRAIL_WEBHOOK_KEEPALIVE_SECONDS`: The number of seconds to keep an idle connection alive. The default value is `300`. Higher values help avoid delays to setup and teardown connections when requests are intermittent. Lower values help free up unused connections faster, which can help if the webhook server does not handle idle connections well. - -Example configuration file: - - - - -```yaml -kubectl apply -f- <}} -kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} -metadata: - name: agw-override - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - env: - - name: GUARDRAIL_WEBHOOK_MAX_CONNECTIONS - value: "50" - - name: GUARDRAIL_WEBHOOK_KEEPALIVE_SECONDS - value: "60" -EOF -``` - - - -### More information - -* [Example scenario](#example-scenario) of a simple Python webhook server that integrates with the Guardrail Webhook API. -* [Guardrail Webhook API reference docs](../openapi-spec/). - -## Example scenario - -To learn how to implement your own guardrail webhook server, you can use the following sample Python webhook server. For the source code, see the [GitHub repository](https://github.com/solo-io/gloo-gateway-use-cases/tree/main/ai-guardrail-webhook-server). - -The webhook server is configured to take the following actions: - -* If the content has the word `block`, the request is rejected with a 403 Forbidden response. -* If the response has the word `mask`, the gateway transforms the word `mask` to asterisks (`****`) in the body with a 200 response. - -{{< callout type="warning" >}} -{{% reuse "agw-docs/snippets/demo-disclaimer.md" %}} -{{< /callout >}} - -### Before you begin - -{{< reuse "agw-docs/snippets/agw-prereq-llm.md" >}} - -### Step 1: Deploy the webhook server to your cluster - -1. Deploy the webhook server. The example includes a Deployment based on the `gcr.io/solo-public/docs/ai-guardrail-webhook:latest` image and Service of type LoadBalancer that listens for incoming requests on port 8000. If the image does not work for your environment, you can build your own from the sample code in the [GitHub repository](https://github.com/solo-io/gloo-gateway-use-cases/tree/main/ai-guardrail-webhook-server). - - ```yaml - kubectl apply -f - <}} - labels: - app: ai-guardrail - spec: - replicas: 2 - selector: - matchLabels: - app: ai-guardrail-webhook - template: - metadata: - labels: - app: ai-guardrail-webhook - spec: - containers: - - name: webhook - image: gcr.io/solo-public/docs/ai-guardrail-webhook:latest - ports: - - containerPort: 8000 - resources: - requests: - memory: "128Mi" - cpu: "100m" - limits: - memory: "256Mi" - cpu: "200m" - --- - apiVersion: v1 - kind: Service - metadata: - name: ai-guardrail-webhook - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - labels: - app: ai-guardrail - spec: - selector: - app: ai-guardrail-webhook - ports: - - port: 8000 - targetPort: 8000 - type: LoadBalancer - EOF - ``` - -2. Verify that the webhook server is running. - - ```sh - kubectl get deploy,svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=ai-guardrail - ``` - - Example output: - - ``` - NAME READY UP-TO-DATE AVAILABLE AGE - deployment.apps/ai-guardrail-webhook 2/2 2 2 88s - - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - service/ai-guardrail-webhook LoadBalancer 172.xx.xxx.xx .us-east-2.elb.amazonaws.com 8000:30752/TCP 88s - ``` - -3. Save the address of the webhook server in an environment variable. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal= "2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - - ```sh - export WEBHOOK_SERVER_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} ai-guardrail-webhook -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $WEBHOOK_SERVER_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - If the webhook service is deployed in the same cluster as the gateway proxy, you can also use the Kubernetes DNS name of the service, such as `ai-guardrail-webhook.{{< reuse "agw-docs/snippets/namespace.md" >}}.svc.cluster.local`. - ```sh - export WEBHOOK_SERVER_ADDRESS=ai-guardrail-webhook.{{< reuse "agw-docs/snippets/namespace.md" >}}.svc.cluster.local - echo $WEBHOOK_SERVER_ADDRESS - ``` - {{% /tab %}} - {{< /tabs >}} - - -### Step 2: Configure the gateway proxy to use the webhook server {#ai-gateway} - -Configure a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to use the webhook server for prompt guarding. - - - - -```yaml -kubectl apply -f - <}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: openai-prompt-guard - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: openai - backend: - ai: - promptGuard: - request: - - webhook: - backendRef: - kind: Service - name: ai-guardrail-webhook - port: 8000 - response: - - webhook: - backendRef: - kind: Service - name: ai-guardrail-webhook - port: 8000 -EOF -``` - -{{% reuse "agw-docs/snippets/review-table.md" %}} For more prompt guard options such as custom responses, see the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} API docs for AI. - -| Setting | Description | -|---------|-------------| -| `targetRefs` | The HTTPRoute that you want to apply the guardrail to. This example uses the `openai` HTTPRoute that you created before you began. | -| `backend.ai.promptGuard` | The AI prompt guarding configuration that you want to set up. In this example, you configure the webhook server for both request and response guardrails. | -| `webhook.backendRef` | The reference to the webhook server service. The example webhook server is configured to use port 8000. | - - - - -### Step 3: Test the webhook server {#test-webhook-server} - -1. Send a request through {{< reuse "agw-docs/snippets/agentgateway.md" >}} to the OpenAI provider. In the body, include the word `block` to trigger the 403 Forbidden response. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal= "2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi "$INGRESS_GW_ADDRESS:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "You are a skilled developer who is good at explaining basic programming concepts to beginners." - }, - { - "role": "user", - "content": "Write a method to block inappropriate content." - } - ] - }' - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "You are a skilled developer who is good at explaining basic programming concepts to beginners." - }, - { - "role": "user", - "content": "Write a method to block inappropriate content." - } - ] - }' - ``` - {{% /tab %}} - {{< /tabs >}} - - Example response: - - ``` - HTTP/1.1 403 Forbidden - ... - request blocked - ``` - -2. Send another request. This time, include the word `mask` in the body to trigger the 200 response with the content masked. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal= "2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi "$INGRESS_GW_ADDRESS:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "You are a skilled developer who is good at explaining basic programming concepts to beginners." - }, - { - "role": "user", - "content": "Explain masking to me briefly, and show me an example of masking the names of the people in this directory: Alice, Sr. Developer. Bob, Jr. Developer. Charlie, Manager." - } - ] - }' - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "You are a skilled developer who is good at explaining basic programming concepts to beginners." - }, - { - "role": "user", - "content": "Explain masking to me briefly, and show me an example of masking the names of the people in this directory: Alice, Sr. Developer. Bob, Jr. Developer. Charlie, Manager." - } - ] - }' - ``` - {{% /tab %}} - {{< /tabs >}} - - Example response: Note that the response turns the word `mask` into asterisks (`****`). - - ``` - HTTP/1.1 200 OK - ``` - - ```json - { - "id": "chatcmpl-BMFO97jLVP4YOjf6CZEOL5sHSqhbn", - "object": "chat.completion", - "created": 1744642069, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Sure! In programming, we use the term \"****\" to refer to a process of hiding sensitive information such as names, passwords, or other personal data. This is done to protect privacy and prevent unauthorized access to the information. \n\nIn this context, if you want to hide the names of the people in the directory, you can replace them with placeholders like this:\n\n- ****, Sr. Developer\n- ****, Jr. Developer\n- ****, Manager\n\nThis way, you are concealing the actual names while still providing their job titles or roles in the directory.", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 55, - "completion_tokens": 116, - "total_tokens": 171, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "service_tier": "default", - "system_fingerprint": null - } - ``` - - -### Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the webhook server deployment and service. - - ```sh - kubectl delete deploy,svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=ai-guardrail - ``` - -2. Delete the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. - - ```sh - kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} openai-prompt-guard - ``` diff --git a/assets/docs/pages/agentgateway/inference.md b/assets/docs/pages/agentgateway/inference.md deleted file mode 100644 index 0b4d39d27..000000000 --- a/assets/docs/pages/agentgateway/inference.md +++ /dev/null @@ -1,37 +0,0 @@ -Use agentgateway proxies with the Kubernetes Gateway API Inference Extension project. This project extends the Gateway API so that you can route to AI inference workloads such as local Large Language Models (LLMs) that run in your Kubernetes environment. - -For more information, see the following resources. - -{{< cards >}} - {{< card link="https://gateway-api-inference-extension.sigs.k8s.io/" title="Kubernetes Gateway API Inference Extension docs" icon="external-link">}} - {{< card link="https://kgateway.dev/blog/deep-dive-inference-extensions/" title="Kgateway deep-dive blog on Inference Extension" icon="external-link">}} -{{< /cards >}} - -## About Inference Extension {#about} - -The Inference Extension project extends the Gateway API with two key resources, an InferencePool and an InferenceModel, as shown in the following diagram. - -```mermaid -graph TD - InferencePool --> InferenceModel_v1["InferenceModel v1"] - InferencePool --> InferenceModel_v2["InferenceModel v2"] - InferencePool --> InferenceModel_v3["InferenceModel v3"] -``` - -The InferencePool groups together InferenceModels of LLM workloads into a routable backend resource that the Gateway API can route inference requests to. An InferenceModel represents not just a single LLM model, but a specific configuration including information such as as the version and criticality. The InferencePool uses this information to ensure fair consumption of compute resources across competing LLM workloads and share routing decisions to the Gateway API. - -### {{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} with Inference Extension {#integration} - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} integrates with the Inference Extension as a supported Gateway API provider. This way, a Gateway can route requests to InferencePools, as shown in the following diagram. - -{{< reuse "agw-docs/snippets/inference-diagram.md" >}} - -The Client sends an inference request to get a response from a local LLM workload. The Gateway receives the request and routes to the InferencePool as a backend. Then, the InferencePool selects a specific InferenceModel to route the request to, based on criteria such as the least-loaded model or highest criticality. The Gateway can then return the response to the Client. - -## Setup steps {#setup} - -Refer to the **Kgateway** tabs in the **Getting started** guide in the Inference Extension docs. - -{{< cards >}} - {{< card link="https://gateway-api-inference-extension.sigs.k8s.io/guides/" title="Inference Extension getting started guide" icon="external-link">}} -{{< /cards >}} diff --git a/assets/docs/pages/agentgateway/llm/about.md b/assets/docs/pages/agentgateway/llm/about.md deleted file mode 100644 index 0b8372730..000000000 --- a/assets/docs/pages/agentgateway/llm/about.md +++ /dev/null @@ -1,42 +0,0 @@ -{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} provides seamless integration with various Large Language Model (LLM) providers. This way, you can consume AI services through a unified interface while still maintain flexibility in the providers that you use. - -## What is an LLM? - -Large Language Model (LLMs) are very large, deep learning models that are pre-trained on massive amounts of unlabeled and self-supervised data, often containing billions of words. LLMs extract meanings from a sequence of text and can understand the relationship between words and phrases in it. Based on this understanding, the LLM can then predict and generate natural language, and perform related tasks, such as answering questions, summarizing text, translating between languages, or writing content. LLMs can be fine-tuned on a smaller, more specific data set so that it can perform a more specific task more accurately. - -While LLMs were originally designed to be trained on text and natural language, they are now becoming multimodal, supporting different media types, such as images and videos. - -## Common problems with LLM consumption - -When adopting an LLM on an enterprise-level, you typically run into the following issues: - -* **Data leakage and privacy**: When interacting with LLMs, it is essential to comply with federal laws and to not leak any PII (personally identifiable information) or other sensitive information in prompts. For example, users might enter personal credit card or customer related information, such as account numbers and names. Attackers might also trick the model into revealing previous user data that is still stored in the context. To prevent sensitive information from leaking to the LLM provider, prompt guards must be in place that help to fitler, block, monitor, and control LLM inputs and outputs to find offensive content, prevent misuse, and ensure ethical and responsible AI usage. - -* **Cost controls**: Compared to traditional APIs, LLM queries are long-running, meaning the LLM must parse through its large data set iteratively to compute one token at a time. All tokens must then be summarized to generate a prediction. Given the large amounts of data that the LLM parses, GPUs are required to run LLMs efficently, which are costly to run and maintain. Limiting the amount of tokens that can be used and monitoring token consumption are critical to keep costs to a minimum. - -* **Fan-out patterns**: LLMs are limited by static training data. This limitation can make seemingly simple questions difficult to answer. For example, answering a simple question, such as `What is the weather today?` requires the LLM to have access to several real-time information, such as the location, time, and weather forecast. Integrating LLMs with other MCP servers and agents to perform these tasks becomes essential to accurately answer questions of this nature. - -* **Security**: To protect your LLM from being consumed by unauthorized users, you typically want to authenticate with the LLM before you start sending requests. Managing credentials, such as API keys, and monitoring the traffic to the LLM becomes essential to protect access to the LLM . - -* **Scalability and reliability**: When relying on an LLM to perform specific tasks in your environment, you must put measures in place that prevent your applications from failing, being overwhelmed, or performing inefficiently. This includes retries and timeouts, request rate limiting, and multi-model failovers. - - - -## Supported providers - -Review the following table for a list of supported LLM providers. - - -| Provider | Chat Completions | Streaming | -|---------------------------|:---------------:|:---------:| -| [OpenAI](../providers/openai) | ✅ | ✅ | -| [Vertex AI](../providers/vertex) | ✅ | ✅ | -| [Gemini](../providers/gemini) | ✅ | ✅ | -| [Amazon Bedrock](../providers/bedrock) | ✅ | ✅ | -| [Anthropic](../providers/anthropic) | ✅ | ✅ | -| [OpenAI compatible](../providers/openai-compatible) | ✅ | ✅ | -| [Azue OpenAI](../providers/azureopenai) | ✅ | ✅ | - -* Chat Completions: support for the `/v1/chat/completions` API. -* Streaming: support for streaming (`"stream": true` in the completions request) - diff --git a/assets/docs/pages/agentgateway/llm/api-keys.md b/assets/docs/pages/agentgateway/llm/api-keys.md deleted file mode 100644 index 9f1c8c897..000000000 --- a/assets/docs/pages/agentgateway/llm/api-keys.md +++ /dev/null @@ -1,446 +0,0 @@ -Managing API keys is an important security mechanism to prevent unauthorized access to your LLM provider. If API keys are compromised, attackers can deliberately run expensive queries, such as large and recursive prompts, at your expense. - -Follow the instructions in this guide to learn how to use these different methods. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Manage API keys - -You can choose between the following options to provide an API key to agentgateway: -* [Inline](#inline) -* [Kubernetes secret](#api-key) -* [Passthrough token](#passthrough) - -### Inline token {#inline} - -Provide the token directly in the configuration for the {{< reuse "agw-docs/snippets/backend.md" >}}. This option is the least secure. Only use this option for quick tests such as trying out AI Gateway. - -1. Get the token from your LLM provider, such as an API key to OpenAI. - - ```sh - export TOKEN= - ``` - - -2. Provide the token inline in the {{< reuse "agw-docs/snippets/backend.md" >}} configuration. - ```yaml - kubectl apply -f- <}} - metadata: - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - openai: - model: gpt-3.5-turbo - policies: - auth: - key: $TOKEN - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.openai` | Define the OpenAI provider. | - | `openai.model` | The OpenAI model to use, such as `gpt-3.5-turbo`. | - | `policies.auth` | Configure the authentication token for the OpenAI API. The example uses an inline token.| - -3. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. The `URLRewrite` filter rewrites the path from `/openai` to the path of the API in the LLM provider that you want to use, `/v1/chat/completions`. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /openai - backendRefs: - - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -4. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." - }, - { - "role": "user", - "content": "Compose a poem that explains the concept of recursion in programming." - } - ] - }' - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." - }, - { - "role": "user", - "content": "Compose a poem that explains the concept of recursion in programming." - } - ] - }' - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-AEHYs2B0XUlEioCduH1meERmMwBGF", - "object": "chat.completion", - "created": 1727967462, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "In the world of code, a method elegant and rare,\nKnown as recursion, a loop beyond compare.\nLike a mirror reflecting its own reflection,\nIt calls upon itself with deep introspection.\n\nA function that calls itself with artful grace,\nDividing a problem into a smaller space.\nLike a nesting doll, layers deep and profound,\nIt solves complex tasks, looping around.\n\nWith each recursive call, a step is taken,\nTowards solving the problem, not forsaken.\nA dance of self-replication, a mesmerizing sight,\nUnraveling complexity with power and might.\n\nBut beware of infinite loops, a perilous dance,\nWithout a base case, it’s a risky chance.\nFor recursion is a waltz with a delicate balance,\nInfinite beauty, yet a risky dalliance.\n\nSo embrace the concept, in programming’s domain,\nLet recursion guide you, like a poetic refrain.\nA magical loop, a recursive song,\nIn the symphony of code, where brilliance belongs.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 39, - "completion_tokens": 200, - "total_tokens": 239, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0 - } - }, - "system_fingerprint": null - } - ``` - -### API key in a secret {#api-key} - -Store the API key in a Kubernetes secret. Then, refer to the secret in the {{< reuse "agw-docs/snippets/backend.md" >}} configuration. This option is more secure than an inline token, because the API key is encoded and you can restrict access to secrets through RBAC rules. Like the inline option, the API key and secret are fairly simple to create and set up. You might use this option in proofs of concept, controlled development and staging environments, or well-controlled prod environments that use secrets. - -1. [Create an API key to access the OpenAI API](https://platform.openai.com/api-keys). If you use another AI provider, create an API key for that provider's AI instead, and be sure to modify the example commands in these tutorials to use your provider's AI API instead. - -2. Save the API key in an environment variable. - - ```sh - export OPENAI_API_KEY= - ``` - -3. Create a Kubernetes secret to store your AI API key. - - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $OPENAI_API_KEY - EOF - ``` - - -4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure an LLM provider that references the AI API key secret. - ```yaml - kubectl apply -f- <}} - metadata: - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - openai: - model: gpt-3.5-turbo # Optional: specify default model - # host: api.openai.com # Optional: custom host if needed - # port: 443 # Optional: custom port - policies: - auth: - secretRef: - name: openai-secret - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.openai` | Define the OpenAI provider. | - | `openai.model` | The OpenAI model to use, such as `gpt-3.5-turbo`. | - | `policies.auth` | Configure the authentication token for OpenAI API. The example refers to the secret that you previously created.| - -5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /openai - backendRefs: - - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." - }, - { - "role": "user", - "content": "Compose a poem that explains the concept of recursion in programming." - } - ] - }' - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." - }, - { - "role": "user", - "content": "Compose a poem that explains the concept of recursion in programming." - } - ] - }' - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-AEHYs2B0XUlEioCduH1meERmMwBGF", - "object": "chat.completion", - "created": 1727967462, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "In the world of code, a method elegant and rare,\nKnown as recursion, a loop beyond compare.\nLike a mirror reflecting its own reflection,\nIt calls upon itself with deep introspection.\n\nA function that calls itself with artful grace,\nDividing a problem into a smaller space.\nLike a nesting doll, layers deep and profound,\nIt solves complex tasks, looping around.\n\nWith each recursive call, a step is taken,\nTowards solving the problem, not forsaken.\nA dance of self-replication, a mesmerizing sight,\nUnraveling complexity with power and might.\n\nBut beware of infinite loops, a perilous dance,\nWithout a base case, it’s a risky chance.\nFor recursion is a waltz with a delicate balance,\nInfinite beauty, yet a risky dalliance.\n\nSo embrace the concept, in programming’s domain,\nLet recursion guide you, like a poetic refrain.\nA magical loop, a recursive song,\nIn the symphony of code, where brilliance belongs.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 39, - "completion_tokens": 200, - "total_tokens": 239, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0 - } - }, - "system_fingerprint": null - } - ``` - -### Passthrough token {#passthrough} - -Pass through an existing token directly from the client or a successful OpenID Connect (OIDC) connect flow before the request is sent to the {{< reuse "agw-docs/snippets/backend.md" >}}. This option is useful for environments where you set up federated identity for backend clients so that they are already authenticated to the LLM providers that you create {{< reuse "agw-docs/snippets/backend.md" >}}s for. Currently, the request must place the token in the `Authorization` header. - -1. Make sure that your client is set up as follows: - - * The client that sends a request to the {{< reuse "agw-docs/snippets/backend.md" >}} can authenticate to the LLM provider, such as through an OIDC flow or API key. - * The authenticated token or API key is sent in requests to the {{< reuse "agw-docs/snippets/backend.md" >}} in an `Authorization` header. - - - -2. Configure the {{< reuse "agw-docs/snippets/backend.md" >}} to use passthrough auth. - ```yaml - kubectl apply -f- <}} - metadata: - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - openai: - model: gpt-3.5-turbo - policies: - auth: - passthrough: {} - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.openai` | Define the OpenAI provider. | - | `openai.model` | The OpenAI model to use, such as `gpt-3.5-turbo`. | - | `policies.auth` | Configure the authentication token for OpenAI API. The example uses passthrough authentication.| - -3. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /openai - backendRefs: - - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -4. Trigger your authenticated client to send a request to the {{< reuse "agw-docs/snippets/backend.md" >}}, and verify that you get back a successful response. For example, you might instruct your client to send a curl request through the AI Gateway. Note that the request includes the `Authorization` header, which is required for passthrough authentication. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H "Authorization: Bearer $TOKEN" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." - }, - { - "role": "user", - "content": "Compose a poem that explains the concept of recursion in programming." - } - ] - }' - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H "Authorization: Bearer $TOKEN" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." - }, - { - "role": "user", - "content": "Compose a poem that explains the concept of recursion in programming." - } - ] - }' - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-AEHYs2B0XUlEioCduH1meERmMwBGF", - "object": "chat.completion", - "created": 1727967462, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "In the world of code, a method elegant and rare,\nKnown as recursion, a loop beyond compare.\nLike a mirror reflecting its own reflection,\nIt calls upon itself with deep introspection.\n\nA function that calls itself with artful grace,\nDividing a problem into a smaller space.\nLike a nesting doll, layers deep and profound,\nIt solves complex tasks, looping around.\n\nWith each recursive call, a step is taken,\nTowards solving the problem, not forsaken.\nA dance of self-replication, a mesmerizing sight,\nUnraveling complexity with power and might.\n\nBut beware of infinite loops, a perilous dance,\nWithout a base case, it’s a risky chance.\nFor recursion is a waltz with a delicate balance,\nInfinite beauty, yet a risky dalliance.\n\nSo embrace the concept, in programming’s domain,\nLet recursion guide you, like a poetic refrain.\nA magical loop, a recursive song,\nIn the symphony of code, where brilliance belongs.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 39, - "completion_tokens": 200, - "total_tokens": 239, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0 - } - }, - "system_fingerprint": null - } - ``` - diff --git a/assets/docs/pages/agentgateway/llm/failover.md b/assets/docs/pages/agentgateway/llm/failover.md deleted file mode 100644 index 3beb0ba4a..000000000 --- a/assets/docs/pages/agentgateway/llm/failover.md +++ /dev/null @@ -1,260 +0,0 @@ -Prioritize the failover of requests across different models from an LLM provider. - -## About failover {#about} - -Failover is a way to keep services running smoothly by automatically switching to a backup system when the main one fails or becomes unavailable. - -For {{< reuse "agw-docs/snippets/agentgateway.md" >}}, you can set up failover for the models of the LLM providers that you want to prioritize. If the main model from one provider goes down, slows, or has any issue, the system quickly switches to a backup model from that same provider. This keeps the service running without interruptions. - -This approach increases the resiliency of your network environment by ensuring that apps that call LLMs can keep working without problems, even if one model has issues. - -## Before you begin - -1. Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). -2. Set up [API access to each LLM provider]({{< link-hextra path="/llm/api-keys/" >}}) that you want to use. The example in this guide uses OpenAI. - -## Fail over to other models {#model-failover} - -You can configure failover across multiple models and providers by using priority groups. Each priority group represents a set of providers that share the same priority level. Failover priority is determined by the order in which the priority groups are listed in the {{< reuse "agw-docs/snippets/backend.md" >}}. The priority group that is listed first is assigned the highest priority. Models within the same priority group are load balanced (round-robin), not prioritized. - -1. Create or update the {{< reuse "agw-docs/snippets/backend.md" >}} for your LLM providers. - - {{< tabs tabTotal="2" items="OpenAI model priority,Cost-based priority across providers" >}} - {{% tab tabName="OpenAI model priority" %}} - - In this example, you configure separate priority groups for failover across multiple models from the same LLM provider, OpenAI. The priority order of the models is as follows: - - 1. OpenAI `gpt-4.1` model (highest priority) - 2. OpenAI `gpt-5.1` model (fallback) - 3. OpenAI `gpt-3.5-turbo` model (lowest priority) - - - ```yaml - kubectl apply -f- <}} - metadata: - name: model-failover - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - groups: - - providers: - - name: openai-gpt-41 - openai: - model: gpt-4.1 - policies: - auth: - secretRef: - name: openai-secret - - name: openai-gpt-5.1 - openai: - model: gpt-5.1 - policies: - auth: - secretRef: - name: openai-secret - - name: openai-gpt-3.5-turbo - openai: - model: gpt-3.5-turbo - policies: - auth: - secretRef: - name: openai-secret - EOF - ``` - - - - {{% /tab %}} - {{% tab tabName="Cost-based priority across providers" %}} - - In this example, you configure failover across multiple providers with cost-based priority. The first priority group contains cheaper models. Responses are load-balanced across these models. In the event that both models are unavailable, requests fall back to the second priority group of more premium models. - - Highest priority: Load balance across cheaper OpenAI `gpt-3.5-turbo` and Anthropic `claude-3-5-haiku-latest` models. - - Fallback: Load balance across more premium OpenAI `gpt-4.1` and Anthropic `claude-opus-4-1` models. - - Make sure that you configured both Anthropic and OpenAI providers. - - - - ```yaml - kubectl apply -f- <}} - metadata: - name: model-failover - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - groups: - - providers: - - name: openai-gpt-3.5-turbo - openai: - model: gpt-3.5-turbo - policies: - auth: - secretRef: - name: openai-secret - - name: claude-haiku - anthropic: - model: claude-3-5-haiku-latest - policies: - auth: - secretRef: - name: anthropic-secret - - providers: - - name: openai-gpt-4.1 - openai: - model: gpt-4.1 - policies: - auth: - secretRef: - name: openai-secret - - name: claude-opus - anthropic: - model: claude-opus-4-1 - policies: - auth: - secretRef: - name: anthropic-secret - EOF - ``` - - - {{% /tab %}} - {{< /tabs >}} - -2. Create an HTTPRoute resource that routes incoming traffic on the `/model` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you created in the previous step. In this example, the URLRewrite filter rewrites the path from `/model` to the path of the API in the LLM provider that you want to use, such as `/v1/chat/completions` for OpenAI. - - - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /model - backendRefs: - - name: model-failover - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -3. Send a request to observe the failover. In your request, do not specify a model. Instead, the {{< reuse "agw-docs/snippets/backend.md" >}} automatically uses the model from the first priority group (highest priority). - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```bash - curl -v "$INGRESS_GW_ADDRESS/model" -H content-type:application/json -d '{ - "messages": [ - { - "role": "user", - "content": "What is kubernetes?" - } - ]}' | jq - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```bash - curl -v "localhost:8080/model" -H content-type:application/json -d '{ - "messages": [ - { - "role": "user", - "content": "What is kubernetes?" - } - ]}' | jq - ``` - {{< /tab >}} - {{< /tabs >}} - - Example output: - - {{< tabs tabTotal="2" items="OpenAI model priority,Cost-based priority across providers" >}} - {{% tab tabName="OpenAI model priority" %}} - - Note the response is from the `gpt-4o` model, which is the first model in the priority order from the {{< reuse "agw-docs/snippets/backend.md" >}}. - - ```json {linenos=table,hl_lines=[5],linenostart=1,filename="model-response.json"} - { - "id": "chatcmpl-BFQ8Lldo9kLC56S1DFVbIonOQll9t", - "object": "chat.completion", - "created": 1743015077, - "model": "gpt-4.1-2025-04-14", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Kubernetes is an open-source container orchestration platform designed to automate the deployment, scaling, and management of containerized applications. Originally developed by Google, it is now maintained by the Cloud Native Computing Foundation (CNCF).\n\nKubernetes provides a framework to run distributed systems resiliently. It manages containerized applications across a cluster of machines, offering features such as:\n\n1. **Automatic Bin Packing**: It can optimize resource usage by automatically placing containers based on their resource requirements and constraints while not sacrificing availability.\n\n2. **Self-Healing**: Restarts failed containers, replaces and reschedules containers when nodes die, and kills and reschedules containers that are unresponsive to user-defined health checks.\n\n3. **Horizontal Scaling**: Scales applications and resources up or down automatically, manually, or based on CPU usage.\n\n4. **Service Discovery and Load Balancing**: Exposes containers using DNS names or their own IP addresses and balances the load across them.\n\n5. **Automated Rollouts and Rollbacks**: Automatically manages updates to applications or configurations and can rollback changes if necessary.\n\n6. **Secret and Configuration Management**: Enables you to deploy and update secrets and application configuration without rebuilding your container images and without exposing secrets in your stack configuration and environment variables.\n\n7. **Storage Orchestration**: Allows you to automatically mount the storage system of your choice, whether from local storage, a public cloud provider, or a network storage system.\n\nBy providing these functionalities, Kubernetes enables developers to focus more on creating applications, while the platform handles the complexities of deployment and scaling. It has become a de facto standard for container orchestration, supporting a wide range of cloud platforms and minimizing dependencies on any specific infrastructure.", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - ... - } - ``` - - {{% /tab %}} - {{% tab tabName="Cost-based priority across providers" %}} - - Note the response is from the `claude-3-5-haiku-20241022` model. With the cost-based priority configuration, requests are load balanced across the cheaper models (OpenAI `gpt-3.5-turbo` and Anthropic `claude-3-5-haiku-latest`) in the first priority group. - - ```json {linenos=table,hl_lines=[2],linenostart=1,filename="model-response.json"} - { - "model": "claude-3-5-haiku-20241022", - "usage": { - "prompt_tokens": 11, - "completion_tokens": 299, - "total_tokens": 310 - }, - "choices": [ - { - "message": { - "content": "Kubernetes (often abbreviated as K8s) is an open-source container orchestration platform designed to automate the deployment, scaling, and management of containerized applications. Here's a comprehensive overview:\n\nKey Features:\n1. Container Orchestration\n- Manages containerized applications\n- Handles deployment and scaling\n- Ensures high availability\n\n2. Core Components\n- Cluster: Group of machines (nodes)\n- Master Node: Controls the cluster\n- Worker Nodes: Run containerized applications\n- Pods: Smallest deployable units\n- Containers: Isolated application environments\n\n3. Main Capabilities\n- Automatic scaling\n- Self-healing\n- Load balancing\n- Rolling updates\n- Service discovery\n- Configuration management\n\n4. Key Concepts\n- Deployments: Define desired application state\n- Services: Network communication between components\n- Namespaces: Logical separation of resources\n- ConfigMaps: Configuration management\n- Secrets: Sensitive data management\n\n5. Benefits\n- Portability across different environments\n- Efficient resource utilization\n- Improved scalability\n- Enhanced reliability\n- Simplified management of complex applications\n\n6. Popular Use Cases\n- Microservices architecture\n- Cloud-native applications\n- Continuous deployment\n- Distributed systems\n\nKubernetes has become the standard for container orchestration in modern cloud-native application development.", - "role": "assistant" - }, - "index": 0, - "finish_reason": "stop" - } - ], - "id": "msg_016PLweC4jgJnpwH7V1tZaqj", - "created": 1762790436, - "object": "chat.completion" - } - ``` - - {{% /tab %}} - {{< /tabs >}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```shell -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} model-failover -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute model-failover -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` - -## Next - -Explore other agentgateway features. - -* Pass in [functions](../functions/) to an LLM to request as a step towards agentic AI. -* Set up [prompt guards](../prompt-guards/) to block unwanted requests and mask sensitive data. -* [Enrich your prompts](../prompt-enrichment/) with system prompts to improve LLM outputs. diff --git a/assets/docs/pages/agentgateway/llm/functions.md b/assets/docs/pages/agentgateway/llm/functions.md deleted file mode 100644 index 3ad2520bc..000000000 --- a/assets/docs/pages/agentgateway/llm/functions.md +++ /dev/null @@ -1,321 +0,0 @@ -## About function calling {#about} - -Large Language Models (LLMs) are limited by static training data. This limitation can make seemingly simple questions difficult to answer. For example, consider the following question: - -> What's the weather today? - -The LLM has to know several pieces of real-time information that it was not trained on: - -* The user's location -* The current date -* The weather forecast for that date and location - -Function calling is a way for you as a developer to extend the capabilities of the LLM with your own external APIs, apps, and data. First, you create _tools_ that extend the capabilities of the LLM with a function, such as `get_weather`. These functions can include _parameters_, or inputs, that are needed to execute the function. For example, the `get_weather` function needs the date and location to get the current weather forecast. The _name_ and _description_ of the tool function and parameters help the LLM decide when to call the tool. - -Next, when forwarding user requests to the LLM, you can include the set of tools that the LLM can leverage to answer the user. Based on the user's question, the LLM can respond directly or suggest a tool to call to help answer the question. To get the required parameters for the tool call, the LLM might ask the end user or call other functions like `get_location` or `get_date`, which in turn might pull that information based on system settings on the end user's device. - -### Function calling sequence diagram {#diagram} - -Consider the following sequence diagram that shows how function calling works. - -```mermaid -sequenceDiagram - autonumber - User->>+Gateway: "What's the weather in Columbus?" with tool list - Gateway->>+LLM: Forward user request with tool list - LLM-->>-User: Suggest function call (get_weather) - User-->>+App: Send function suggestion - App->>-App: Execute function (get_weather) - App->>+User: Send function result - User->>+LLM: Forward function result - LLM-->>+Gateway: Generate final response - Gateway-->>-User: "The weather in Columbus is 15°C and cloudy." -``` - -1. The User asks about the weather today. The request includes a list of tools that the LLM can use to answer the question. -2. The Gateway routes the request with the tool list to the LLM. -3. Based on the conversation, the LLM suggests to call the `get_weather` function and includes the required parameters to use that function. The LLM might get these parameters by using the chat history, asking the end user to provide them, or by suggesting other functions to call before calling the `get_weather` function. The Gateway returns this suggestion to the User. -4. The User invokes the `get_weather` function by sending a request to the App. The request includes the required parameters to execute the function. -5. The App executes the `get_weather` function with the required parameters to get the current weather in the location, such as Columbus, OH. -6. The App returns the function result to the User. -7. The User returns the function result to the LLM. -8. The LLM uses the real-time function result from the App in a natural language response and returns this response to the Gateway. -9. The Gateway then forwards the natural language response to the User. - -### Behavior with other AI features {#about-behavior} - -Keep in mind the following behaviors when using function calling with other agentgateway features. For more details about these features, see the [API docs]({{< link-hextra path="reference/api/#aitrafficpolicy" >}}). - -* Streaming responses: You can stream responses that call functions. -* Semantic caching: Function calls are not cached. -* Prompt guards: Prompt guards do not apply to function calls. - -### AI provider differences {#about-providers} - -Each AI provider has a different way of handling function calling. For example, OpenAI might expect an array of `functions`, while Anthropic expects individual `tools`. Or, the response formats might differ. The capabilities of function calling also differ across providers, with some providing more support for particular cloud providers, others focusing on response time optimization, or others offering more fine-grained control over the response structure. For more information, consult your AI provider's documentation. - -* [Anthropic](https://docs.anthropic.com/en/docs/build-with-claude/tool-use/overview) -* [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/function-calling) -* [Gemini](https://ai.google.dev/gemini-api/docs/function-calling) -* [Mistral AI](https://docs.mistral.ai/capabilities/function_calling/) -* [OpenAI](https://platform.openai.com/docs/guides/function-calling) -* [Vertex AI](https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/FunctionDeclaration?hl=en) - -## Before you begin - -{{< reuse "agw-docs/snippets/agw-prereq-llm.md" >}} - -## Example of function calling {#function-call} - -Send a function call to an LLM through agentgateway. In the following steps, you use an example `get_weather` function with an OpenAI LLM. - -{{< callout type="info" >}} -Keep in mind that for a real use case, you must develop your own app that is capable of sending requests to the LLM and executing a tool, such as to retrieve the latest weather information for a given location. -{{< /callout >}} - -1. Send a request through the agentgateway proxy to the OpenAI LLM. In your request, include an example `get_weather` function call. Note that you can include other tools and functions that the app has access to. This way, your LLM can decide on the tool and the function that best answers the user's question. For more examples of creating a function, consult your [AI provider's documentation](#about-providers). The following example demonstrates a response that you might configure your app to send through the agentgateway proxy to the LLM. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "How is the current weather in Columbus?" - } - ], - "parallel_tool_calls": false, - "tools": [ - { - "type": "function", - "function": { - "name": "get_weather", - "description": "Get the current weather", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and country, eg. San Francisco, USA" - }, - "format": { "type": "string", "enum": ["celsius", "fahrenheit", "rankine"] } - }, - "required": ["location", "format"] - } - } - } - ], - "stream": false - }' - ``` - {{% /tab %}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "How is the current weather in Columbus?" - } - ], - "parallel_tool_calls": false, - "tools": [ - { - "type": "function", - "function": { - "name": "get_weather", - "description": "Get the current weather", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and country, eg. San Francisco, USA" - }, - "format": { "type": "string", "enum": ["celsius", "fahrenheit", "rankine"] } - }, - "required": ["location", "format"] - } - } - } - ], - "stream": false - }' - ``` - {{< /tab >}} - - {{< /tabs >}} - - | Field | Description | - |-------|-------------| - | `$INGRESS_GW_ADDRESS/openai` | The address of the agentgateway proxy that you set up before you began, along with the path to your AI provider, such as `openai`. | - | `model` | The model to use for the function call, such as `gpt-3.5-turbo`. | - | `messages` | The messages to send to the model. The example shows a user message asking about the weather in Columbus. | - | `parallel_tool_calls` | Whether to call multiple tools at the same time. | - | `tools` | The tools to use for the function call. | - | `function` | The information about the function to call. | - | `name` | The name of the function. Often, this name matches the function in your app. Try to be as descriptive as possible so that the LLM can figure out what the function does. - | `description` | Provide more context about the function that helps the LLM decide when to use this particular function as opposed to other functions. | - | `parameters` | Include the required parameters that your app needs to execute the function. The example sets up two required parameters: `location` and `format`. | - | `stream` | Whether to stream the response. If you set this to `true`, the response is streamed token-by-token to the client, which can speed up the response time. The example is set to `false`, which is better for functions that are part of a batch or have strict formatting response requirements.| - -2. Review the response from the LLM. If the LLM decides to call a tool, the response includes the information that your app needs to execute the function. - - ```json - { - "id": "chatcmpl-B7nLgGVMnDpc13CZ8tCBNZ8SPmcV9", - "object": "chat.completion", - "created": 1741197692, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": null, - "tool_calls": [ - { - "id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU", - "type": "function", - "function": { - "name": "get_weather", - "arguments": "{\"format\":\"celsius\",\"location\":\"Columbus, OH\"}" - } - } - ], - "refusal": null - }, - "logprobs": null, - "finish_reason": "tool_calls" - } - ], - } - ``` - - | Field | Description | - |-------|-------------| - | `content` | This field is `null` because the model did not return a conversation message. Instead, the model suggests a tool call. | - | `tool_calls` | The details of the function to call. Notice that the response includes an ID for the tool call, `call_iMGPsr4Xx1u0G5sOzFsTCbQU`. Also, the required parameters are part of the arguments. | - | `finish_reason` | The `tool_calls` field indicates that the response is not final, but rather a function call that needs further handling. | - -3. Set up your app to receive the function call from the LLM and execute the function. For example, assume that your weather app returns the following result: - - ```json - { - "temperature": 15, - "condition": "cloudy" - } - ``` - -4. From the app, return the result of the function call to the LLM through the agentgateway proxy. Make sure that the app includes the `tool_call_id` for each tool call. - - * The following example sends another curl through the agentgateway proxy to the LLM to simulate a response that your app might send. Unlike the first request, this request does not suggest a tool call. Instead, you provide the results from executing the suggested function as part of the message, along with the assistant role that called the tool. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H "Content-Type: application/json" -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "How is the current weather in Columbus?" - }, - { - "role": "assistant", - "content": null, - "tool_calls": [ - { - "id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU", - "type": "function", - "function": { - "name": "get_weather", - "arguments": "{\"format\":\"celsius\",\"location\":\"Columbus, OH\"}" - } - } - ] - }, - { - "role": "tool", - "tool_call_id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU", - "name": "get_weather", - "content": "{ \"temperature\": 15, \"condition\": \"Cloudy\" }" - } - ] - }' - ``` - {{% /tab %}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H "Content-Type: application/json" -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "How is the current weather in Columbus?" - }, - { - "role": "assistant", - "content": null, - "tool_calls": [ - { - "id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU", - "type": "function", - "function": { - "name": "get_weather", - "arguments": "{\"format\":\"celsius\",\"location\":\"Columbus, OH\"}" - } - } - ] - }, - { - "role": "tool", - "tool_call_id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU", - "name": "get_weather", - "content": "{ \"temperature\": 15, \"condition\": \"Cloudy\" }" - } - ] - }' - ``` - {{< /tab >}} - - {{< /tabs >}} - -5. Review the response from the LLM. - - ```json - { - "id": "chatcmpl-B7opYdxULQAF0xN6SK6jCIZft75xG", - "object": "chat.completion", - "created": 1741203388, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "The current weather in Columbus is 15°C and cloudy.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - } - ``` - - | Field | Description | - |-------|-------------| - | `choices.message.content` | The response includes the content that answers the user's initial query about the weather. | - | `choices.finish_reason` | The `stop` finish reason indicates that the response is complete. | - - - - diff --git a/assets/docs/pages/agentgateway/llm/observability.md b/assets/docs/pages/agentgateway/llm/observability.md deleted file mode 100644 index 3fcc844ee..000000000 --- a/assets/docs/pages/agentgateway/llm/observability.md +++ /dev/null @@ -1,43 +0,0 @@ -Review LLM-specific metrics and logs. - -## Before you begin - -Complete an LLM guide, such as an [LLM provider-specific guide]({{< link-hextra path="/llm/providers/" >}}). This guide sends a request to the LLM and receives a response. You can use this request and response example to verify metrics and logs. - -## View LLM metrics - -You can access the {{< reuse "agw-docs/snippets/agentgateway.md" >}} metrics endpoint to view LLM-specific metrics, such as the number of tokens that you used during a request or response. - -1. Port-forward the agentgateway proxy on port 15020. - ```sh - kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 15020 - ``` -2. Open the {{< reuse "agw-docs/snippets/agentgateway.md" >}} [metrics endpoint](http://localhost:15020/metrics). -3. Look for the `agentgateway_gen_ai_client_token_usage` metric. This metric is a [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram) and includes important information about the request and the response from the LLM, such as: - * `gen_ai_token_type`: Whether this metric is about a request (`input`) or response (`output`). - * `gen_ai_operation_name`: The name of the operation that was performed. - * `gen_ai_system`: The LLM provider that was used for the request/response. - * `gen_ai_request_model`: The model that was used for the request. - * `gen_ai_response_model`: The model that was used for the response. - - -For more information, see the [Semantic conventions for generative AI metrics](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-metrics/) in the OpenTelemetry docs. - - -## View logs - -{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} automatically logs information to stdout. When you run {{< reuse "agw-docs/snippets/agentgateway.md" >}} on your local machine, you can view a log entry for each request that is sent to {{< reuse "agw-docs/snippets/agentgateway.md" >}} in your CLI output. - -To view the logs: -```sh -kubectl logs deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` - -Example for a successful request to the OpenAI LLM: -``` -2025-12-12T21:56:02.809082Z info request gateway=agentgateway-system/agentgateway-proxy listener=http -route=agentgateway-system/openai endpoint=api.openai.com:443 src.addr=127.0.0.1:60862 http.method=POST -http.host=localhost http.path=/openai http.version=HTTP/1.1 http.status=200 protocol=llm gen_ai. -operation.name=chat gen_ai.provider.name=openai gen_ai.request.model=gpt-3.5-turbo gen_ai.response. -model=gpt-3.5-turbo-0125 gen_ai.usage.input_tokens=68 gen_ai.usage.output_tokens=298 duration=2488ms -``` diff --git a/assets/docs/pages/agentgateway/llm/prompt-enrichment.md b/assets/docs/pages/agentgateway/llm/prompt-enrichment.md deleted file mode 100644 index 6b363c098..000000000 --- a/assets/docs/pages/agentgateway/llm/prompt-enrichment.md +++ /dev/null @@ -1,317 +0,0 @@ -Effectively manage system and user prompts to improve LLM outputs. - -## About prompt enrichment - -Prompts are basic building blocks for guiding LLMs to produce relevant and accurate responses. By effectively managing both system prompts, which set initial guidelines, and user prompts, which provide specific context, you can significantly enhance the quality and coherence of the model's outputs. - -**System prompts** include initialization instructions, behavior guidelines, and background information. You use system prompts to set the foundation for the model's behavior. For example, you might instruct your LLM to respond to users with a polite tone, or according to specific organizational policies, with a system prompt such as "You are a helpful customer service assistant. Always be polite, and conclude conversations by asking customers to rate their experience." - -**User prompts** encompass direct queries, sequential inputs, and task-oriented instructions. They ensure that the model responds accurately to specific user needs. This includes all interactions that end users have with your LLM, such as "Summarize this article in 3 key points" or "What kind of dinner can I make with these ingredients?". - -Note that system and user prompts are not mutually exclusive, and can be combined in a single request to an LLM. For example, in the following steps, the prompt `Parse the unstructured text into CSV format: Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe.` contains both system prompt and user prompt components. - - -
-Prompt enrichment can be configured directly in an {{< reuse "agw-docs/snippets/backend.md" >}} resource or in a separate AgentgatewayPolicy resource. - - -## Before you begin - -{{< reuse "agw-docs/snippets/agw-prereq-llm.md" >}} - -## Refactor LLM prompts - -In the following example, you explore how to refactor system and user prompts to parse and turn unstructured text into valid CSV format. - -1. Send a request to the AI API with the following prompt: `Parse the unstructured text into CSV format: Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe.` Note that in this prompt, the system prompt is not separated from the user prompt. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "Parse the unstructured text into CSV format: Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{% /tab %}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "Parse the unstructured text into CSV format: Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{% /tab %}} - - {{< /tabs >}} - - Verify that the request succeeds and that you get back a structured CSV response. - ``` - City,Continent - Seattle,North America - Los Angeles,North America - Chicago,North America - London,Europe - Paris,Europe - Berlin,Europe - ``` - -2. Refactor the request to improve readability and management of the prompt. In the following example, the instructions are separated from the unstructured text. The instructions are added as a system prompt and the unstructured text is added as a user prompt. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "Parse the unstructured text into CSV format." - }, - { - "role": "user", - "content": "Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{< /tab >}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "Parse the unstructured text into CSV format." - }, - { - "role": "user", - "content": "Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{< /tab >}} - - {{< /tabs >}} - - Verify that you get back the same output as in the previous step. - ``` - City, Continent - Seattle, North America - Los Angeles, North America - Chicago, North America - London, Europe - Paris, Europe - Berlin, Europe - ``` - -## Append or prepend prompts - -Use a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to enrich prompts by appending or prepending system and user prompts to each request. This way, you can centrally manage common prompts that you want to add to each request. - - -1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to enrich your prompts and configure additional settings. The following example prepends a system prompt of `Parse the unstructured text into CSV format.` to each request that is sent to the `openai` HTTPRoute. - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: openai-opt - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - labels: - app: agentgateway - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: openai - backend: - ai: - prompt: - prepend: - - role: system - content: "Parse the unstructured text into CSV format." - EOF - ``` - - -2. Send a request without a system prompt. Although the system prompt instructions are missing in the request, the unstructured text in the user prompt is still transformed into structured CSV format. This is because the system prompt is automatically prepended from the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource before it is sent to the LLM provider. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{< /tab >}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{< /tab >}} - - {{< /tabs >}} - - Example output: - ``` - Item, Price - Eggs, $5 - Flour, $3 - Sugar, $2 - ``` - -## Overwrite settings on the route level - -To overwrite a setting that you added to a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource, you simply include that setting in your request. - -1. Send a request to the AI API and include a custom system prompt that instructs the API to transform unstructured text into JSON format. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "Parse the unstructured content and give back a JSON format" - }, - { - "role": "user", - "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{< /tab >}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "Parse the unstructured content and give back a JSON format" - }, - { - "role": "user", - "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{< /tab >}} - - {{< /tabs >}} - - Example output: - ```json - { - "recipe": [ - { - "ingredient": "eggs", - "price": "$5" - }, - { - "ingredient": "flour", - "price": "$3" - }, - { - "ingredient": "sugar", - "price": "$2" - } - ] - } - ``` - -2. Send another request. This time, you do not include a system prompt. Because the default setting in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource is applied, the unstructured text is returned in CSV format. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{< /tab >}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2." - } - ] - }' | jq -r '.choices[].message.content' - ``` - {{< /tab >}} - - {{< /tabs >}} - - Example output: - ``` - Item, Price - Eggs, $5 - Flour, $3 - Sugar, $2 - ``` - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```shell -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=agentgateway -``` - - -## Next - -Explore how to [call functions](../functions/) to extend the capabilities of the LLM with your own external APIs, apps, and data. \ No newline at end of file diff --git a/assets/docs/pages/agentgateway/llm/prompt-guards.md b/assets/docs/pages/agentgateway/llm/prompt-guards.md deleted file mode 100644 index 655f7ce14..000000000 --- a/assets/docs/pages/agentgateway/llm/prompt-guards.md +++ /dev/null @@ -1,287 +0,0 @@ -Secure access to the LLM and the data that is returned with Web Application Filter and Data Loss Prevention policies. - -## About prompt guards {#about} - -Prompt guards are mechanisms that ensure that prompt-based interactions with a language model are secure, appropriate, and aligned with the intended use. These mechanisms help to filter, block, monitor, and control LLM inputs and outputs to filter offensive content, prevent misuse, and ensure ethical and responsible AI usage. - -You can set up prompt guards to block unwanted requests to the LLM provider and mask sensitive data. In this tutorial, you learn how to block any request with a `credit card` string in the request body and mask credit card numbers that are returned by the LLM. - - -
-Prompt guards can be configured directly in an {{< reuse "agw-docs/snippets/backend.md" >}} resource or in a separate AgentgatewayPolicy resource. - - -## Before you begin - -{{< reuse "agw-docs/snippets/agw-prereq-llm.md" >}} - -## Reject unwanted requests - -Use the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource and the `promptGuard` field to deny requests to the LLM provider that include the `credit card` string in the request body. - - -1. Update the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource and add a custom prompt guard. The proxy blocks any requests that contain the `credit card` string in the request body. These requests are automatically denied with a custom response message. - - ```yaml - kubectl apply -f - <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: openai-prompt-guard - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - labels: - app: agentgateway - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: openai - backend: - ai: - promptGuard: - request: - - response: - message: "Rejected due to inappropriate content" - regex: - action: REJECT - matches: - - "credit card" - EOF - ``` - - - - {{< callout type="info" >}} - You can also reject requests that contain strings of inappropriate content itself, such as credit card numbers, by using the promptGuard.request.regex.builtins field. Besides CREDIT_CARD in this example, you can also specify EMAIL, PHONE_NUMBER, and SSN. - {{< /callout >}} - ```yaml - ... - promptGuard: - request: - regex: - action: REJECT - builtins: - - CREDIT_CARD - ``` - -2. Send a request to the AI API that includes the string `credit card` in the request body. Verify that the request is denied with a 403 HTTP response code and the custom response message is returned. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -v "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "Can you give me some examples of Master Card credit card numbers?" - } - ] - }' - ``` - {{% /tab %}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -v "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "Can you give me some examples of Master Card credit card numbers?" - } - ] - }' - ``` - {{% /tab %}} - - {{< /tabs >}} - - Example output: - ``` - < HTTP/1.1 403 Forbidden - < content-type: text/plain - < date: Wed, 02 Oct 2024 22:23:17 GMT - < server: envoy - < transfer-encoding: chunked - < - * Connection #0 to host XX.XXX.XXX.XX left intact - Rejected due to inappropriate content - ``` - -3. Send another request. This time, remove the word `credit` from the user prompt. Verify that the request now succeeds. - - {{< callout type="info" >}} - OpenAI is configured to not return any sensitive information, such as credit card or Social Security Numbers, even if they are fake. Because of that, the request does not return a list of credit card numbers. - {{< /callout >}} - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "Can you give me some examples of Master Card card numbers?" - } - ] - }' - ``` - {{% /tab %}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "Can you give me some examples of Master Card card numbers?" - } - ] - }' - ``` - {{% /tab %}} - - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-AE2PyCRv83kpj40dAUSJJ1tBAyA1f", - "object": "chat.completion", - "created": 1727909250, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "I'm sorry, but I cannot provide you with genuine Mastercard card numbers as this would be a violation of privacy and unethical. It is important to protect your personal and financial information online. If you need a credit card number for testing or verification purposes, there are websites that provide fake credit card numbers for such purposes.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 19, - "completion_tokens": 64, - "total_tokens": 83, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0 - } - }, - "system_fingerprint": null - } - ``` - -## Mask sensitive data - -In the next step, you instruct agentgateway to mask credit card numbers that are returned by the LLM. - - -1. Add the following credit card response matcher to the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource. This time, use the built-in credit card regex match instead of a custom one. - - ```yaml - kubectl apply -f - <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: openai-prompt-guard - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - labels: - app: agentgateway - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: openai - backend: - ai: - promptGuard: - response: - - regex: - builtins: - - CreditCard - action: MASK - EOF - ``` - - -2. Send another request to the AI API and include a fake VISA credit card number. Verify that the VISA number is detected and masked in your response. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "What type of number is 5105105105105100?" - } - ] - }' | jq - ``` - {{% /tab %}} - - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "user", - "content": "What type of number is 5105105105105100?" - } - ] - }' | jq - ``` - {{% /tab %}} - - {{< /tabs >}} - - Example output: - - ```json {linenos=table,hl_lines=[11],linenostart=1,filename="model-response.json"} - { - "id": "chatcmpl-BFSv1H8b9Y32mzjzlG1KQRfzkAE6n", - "object": "chat.completion", - "created": 1743025783, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": " is an even number.", - "refusal": null, - "annotations": [] - }, - "logprobs": null, - "finish_reason": "stop" - } - ... - ``` - - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```shell -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=agentgateway -``` - -## Next - -[Enrich your prompts](../prompt-enrichment/) with system prompts to improve LLM outputs. diff --git a/assets/docs/pages/agentgateway/llm/providers/anthropic.md b/assets/docs/pages/agentgateway/llm/providers/anthropic.md deleted file mode 100644 index 33e3d6a6f..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/anthropic.md +++ /dev/null @@ -1,143 +0,0 @@ -Configure [Anthropic (Claude)](https://claude.ai/) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Set up access to Anthropic - -1. Get an API key to access the [Anthropic API](https://console.anthropic.com/). - -2. Save the API key in an environment variable. - - ```sh - export ANTHROPIC_API_KEY= - ``` - -3. Create a Kubernetes secret to store your Anthropic API key. - - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $ANTHROPIC_API_KEY - EOF - ``` - -4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure your LLM provider that references the Anthropic API key secret. - - ```yaml - kubectl apply -f- <}} - metadata: - name: anthropic - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - anthropic: - model: "claude-haiku-4-5-20251001" - policies: - auth: - secretRef: - name: anthropic-secret - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#agentgatewaybackend" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.anthropic` | Define the LLM provider that you want to use. The example uses Anthropic. | - | `anthropic.model` | The model to use to generate responses. In this example, you use the `claude-haiku-4-5-20251001` model. | - | `policies.auth` | Provide the credentials to use to access the Anthropic API. The example refers to the secret that you previously created. The token is automatically sent in the `x-api-key` header.| - -5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/anthropic` path. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the Anthropic `/v1/messages` endpoint. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /anthropic - backendRefs: - - name: anthropic - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -6. Send a request to the LLM provider API. Note that Anthropic uses the `/v1/messages` endpoint format instead of `/v1/chat/completions`. Verify that the request succeeds and that you get back a response from the API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/anthropic" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "user", - "content": "Explain how AI works in simple terms." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/anthropic" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "user", - "content": "Explain how AI works in simple terms." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "model": "claude-haiku-4-5-20251001", - "usage": { - "prompt_tokens": 16, - "completion_tokens": 318, - "total_tokens": 334 - }, - "choices": [ - { - "message": { - "content": "Artificial Intelligence (AI) is a field of computer science that focuses on creating machines that can perform tasks that typically require human intelligence, such as visual perception, speech recognition, decision-making, and language translation. Here's a simple explanation of how AI works:\n\n1. Data input: AI systems require data to learn and make decisions. This data can be in the form of images, text, numbers, or any other format.\n\n2. Training: The AI system is trained using this data. During training, the system learns to recognize patterns, relationships, and make predictions based on the input data.\n\n3. Algorithms: AI uses various algorithms, which are sets of instructions or rules, to process and analyze the data. These algorithms can be simple or complex, depending on the task at hand.\n\n4. Machine Learning: A subset of AI, machine learning, enables the system to automatically learn and improve from experience without being explicitly programmed. As the AI system is exposed to more data, it can refine its algorithms and become more accurate over time.\n\n5. Output: Once the AI system has processed the data, it generates an output. This output can be a prediction, a decision, or an action, depending on the purpose of the AI system.\n\nAI can be categorized into narrow (weak) AI and general (strong) AI. Narrow AI is designed to perform a specific task, such as playing chess or recognizing speech, while general AI aims to have human-like intelligence that can perform any intellectual task.", - "role": "assistant" - }, - "index": 0, - "finish_reason": "stop" - } - ], - "id": "msg_01PbaJfDHnjEBG4BueJNR2ff", - "created": 1764627002, - "object": "chat.completion" - } - ``` - -{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}} diff --git a/assets/docs/pages/agentgateway/llm/providers/azureopenai.md b/assets/docs/pages/agentgateway/llm/providers/azureopenai.md deleted file mode 100644 index 7df5aed2c..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/azureopenai.md +++ /dev/null @@ -1,161 +0,0 @@ -Configure [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Set up access to Azure OpenAI - -1. [Deploy a Microsoft Foundry Model](https://learn.microsoft.com/en-us/azure/ai-foundry/foundry-models/how-to/deploy-foundry-models?view=foundry) in the Foundry portal. -2. Go to the Foundry portal to access your model deployment. From the **Details** tab, retrieve the endpoint and key to access your model deployment. Later, you use this endpoint information to configure your Azure OpenAI backend, including the base URL, your deployment model name, and API version. - - For example, the following URL `https://my-endpoint.cognitiveservices.azure.com/openai/deployments/gpt-4.1-mini/chat/completions?api-version=2025-01-01-preview` is composed of the following details: - * `my-endpoint.cognitiveservices.azure.com` as the base URL - * `gpt-4.1-mini` as the name of your model deployment - * `2025-01-01-preview` as the API version - -3. Store the key to access your model deployment in an environment variable. - ```sh - export AZURE_OPENAI_KEY= - ``` - -4. Create a Kubernetes secret to store your model deployment key. - - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $AZURE_OPENAI_KEY - EOF - ``` - -5. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure Azure OpenAI LLM provider. - - ```yaml - kubectl apply -f- <}} - metadata: - name: azure-openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - azureopenai: - endpoint: my-endpoint.cognitiveservices.azure.com - deploymentName: gpt-4.1-mini - apiVersion: 2025-01-01-preview - policies: - auth: - secretRef: - name: azure-openai-secret - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#azureopenaiconfig" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.azureopenai` | Define the Azure OpenAI provider. | - | `azureopenai.endpoint` | The endpoint of the Azure OpenAI deployment that you created, such as `my-endpoint.cognitiveservices.azure.com`. | - | `azureopenai.deployment` | The name of the Azure OpenAI model deployment that you created earlier. For more information, see the [Azure OpenAI model docs](https://learn.microsoft.com/en-us/azure/ai-foundry/foundry-models/how-to/deploy-foundry-models?view=foundry).| - | `azureopenai.apiVersion` | The version of the Azure OpenAI API to use. For more information, see the [Azure OpenAI API version reference](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#api-specs).| - | `policies.auth` | Configure the authentication token for Azure OpenAI API. The example refers to the secret that you previously created. The token is automatically sent in the `api-key` header.| - -6. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/azure-openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the appropriate chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /azure-openai - backendRefs: - - name: azure-openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - - -7. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/azure-openai" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about cloud computing." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/azure-openai" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about cloud computing." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-9A8B7C6D5E4F3G2H1", - "object": "chat.completion", - "created": 1727967462, - "model": "gpt-4o-mini", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Floating servers bright,\nData streams through endless sky,\nClouds hold all we need." - }, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 28, - "completion_tokens": 19, - "total_tokens": 47 - } - } - ``` - -{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}} diff --git a/assets/docs/pages/agentgateway/llm/providers/bedrock.md b/assets/docs/pages/agentgateway/llm/providers/bedrock.md deleted file mode 100644 index f32df5992..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/bedrock.md +++ /dev/null @@ -1,168 +0,0 @@ -Configure [Amazon Bedrock](https://aws.amazon.com/bedrock/) as an LLM provider in agentgateway. - -## Before you begin - -1. Set up an [agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}). -2. Make sure that your [Amazon credentials](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html) have access to the Bedrock models that you want to use. You can alternatively use an [AWS Bedrock API key](https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html). - -## Set up access to Amazon Bedrock {#setup} - -1. Store your credentials to access the AWS Bedrock API. - {{< tabs tabTotal="2" items="AWS credentials,AWS Bedrock API key" >}} - {{% tab tabName="AWS credentials" %}} - - 1. Log in to the [AWS console](https://console.aws.amazon.com) and store your access credentials as environment variables. - ```bash - export AWS_ACCESS_KEY_ID="" - export AWS_SECRET_ACCESS_KEY="" - export AWS_SESSION_TOKEN="" - ``` - - 2. Create a secret with your Bedrock API key. Optionally provide the session token. - ```yaml - kubectl create secret generic bedrock-secret \ - -n {{< reuse "agw-docs/snippets/namespace.md" >}} \ - --from-literal=accessKey="$AWS_ACCESS_KEY_ID" \ - --from-literal=secretKey="$AWS_SECRET_ACCESS_KEY" \ - --from-literal=sessionToken="$AWS_SESSION_TOKEN" \ - --type=Opaque \ - --dry-run=client -o yaml | kubectl apply -f - - ``` - {{% /tab %}} - {{% tab tabName="AWS Bedrock API key" %}} - 1. Save the API key in an environment variable. - ```sh - export BEDROCK_API_KEY= - ``` - - 2. Create a Kubernetes secret to store your Amazon Bedrock API key. - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $BEDROCK_API_KEY - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - - - -2. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure your LLM provider. Make sure to reference the secret that holds your credentials to access the LLM. - ```yaml - kubectl apply -f- <}} - metadata: - name: bedrock - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - bedrock: - model: "amazon.nova-micro-v1:0" - region: "us-east-1" - policies: - auth: - secretRef: - name: bedrock-secret - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.bedrock` | Define the LLM provider that you want to use. The example uses Amazon Bedrock. | - | `bedrock.model` | The model to use to generate responses. In this example, you use the `amazon.nova-micro-v1:0` model. Keep in mind that some models support cross-region inference. These models begin with a `us.` prefix, such as `us.anthropic.claude-sonnet-4-20250514-v1:0`. For more models, see the [AWS Bedrock docs](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html). | - | `bedrock.region` | The AWS region where your Bedrock model is deployed. Multiple regions are not supported. | - | `policies.auth` | Provide the credentials to use to access the Amazon Bedrock API. The example refers to the secret that you previously created. To use IRSA, omit the `auth` settings.| - -3. Create an HTTPRoute resource to route requests through your agentgateway proxy to the Bedrock {{< reuse "agw-docs/snippets/backend.md" >}}. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint that you set up (such as `/bedrock`) to the appropriate chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /bedrock - backendRefs: - - name: bedrock - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -4. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/bedrock" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "user", - "content": "You are a cloud native solutions architect, skilled in explaining complex technical concepts such as API Gateway, microservices, LLM operations, kubernetes, and advanced networking patterns. Write me a 20-word pitch on why I should use an AI gateway in my Kubernetes cluster." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/bedrock" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "user", - "content": "You are a cloud native solutions architect, skilled in explaining complex technical concepts such as API Gateway, microservices, LLM operations, kubernetes, and advanced networking patterns. Write me a 20-word pitch on why I should use an AI gateway in my Kubernetes cluster." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "metrics": { - "latencyMs": 2097 - }, - "output": { - "message": { - "content": [ - { - "text": "\nAn AI gateway in your Kubernetes cluster can enhance performance, scalability, and security while simplifying complex operations. It provides a centralized entry point for AI workloads, automates deployment and management, and ensures high availability." - } - ], - "role": "assistant" - } - }, - "stopReason": "end_turn", - "usage": { - "inputTokens": 60, - "outputTokens": 47, - "totalTokens": 107 - } - } - ``` - -{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}} diff --git a/assets/docs/pages/agentgateway/llm/providers/gemini.md b/assets/docs/pages/agentgateway/llm/providers/gemini.md deleted file mode 100644 index 9b567fc08..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/gemini.md +++ /dev/null @@ -1,10 +0,0 @@ -Configure [Google Gemini](https://gemini.google.com/) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Set up access to Gemini -{{< reuse "agw-docs/snippets/gemini-setup.md" >}} - -{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}} diff --git a/assets/docs/pages/agentgateway/llm/providers/multiple-endpoints.md b/assets/docs/pages/agentgateway/llm/providers/multiple-endpoints.md deleted file mode 100644 index 6f1cebad3..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/multiple-endpoints.md +++ /dev/null @@ -1,136 +0,0 @@ -Configure access to multiple OpenAI API endpoints such as for chat completions, embeddings, and models through the same {{< reuse "agw-docs/snippets/backend.md" >}}. - -## About - -To set up multiple LLM endpoints, use the `ai.llm.routes` field. This field maps the API paths to supported route types. The keys are URL suffix matches, like `/v1/models`. The values are the route types, like `completions` or `passthrough`. - -- `completions`: Transforms to the LLM provider format and processes the request with the LLM provider. This route type supports full LLM features such as tokenization, rate limiting, transformations, and other policies like prompt guards. -- `passthrough`: Forwards the request to the LLM provider as-is. This route type does not support LLM features like route processing and policies. You might use this route type for non-chat endpoints such as health checks, `GET` requests like listing models, or custom endpoints that you want to pass traffic through to. - -Paths are matched in order, and the first match determines how the request is handled. The wildcard character `*` can be used to match anything. If no route is set, the route defaults to the completions endpoint. - -## Before you begin - -1. Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). -2. Set up [API access to each LLM provider]({{< link-hextra path="/llm/api-keys/" >}}) that you want to use. The example in this guide uses OpenAI. - -## Configure multiple endpoints - -Configure access to multiple endpoints in your LLM provider, such as for chat completions, embeddings, and models through the same {{< reuse "agw-docs/snippets/backend.md" >}}. The following steps use OpenAI as an example. - -1. Update your {{< reuse "agw-docs/snippets/backend.md" >}} resource to include a `routes` field that maps API paths to route types. - ```yaml - kubectl apply -f- <}} - metadata: - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - openai: - model: gpt-3.5-turbo # Optional: specify default model - # host: api.openai.com # Optional: custom host if needed - # port: 443 # Optional: custom port - policies: - auth: - secretRef: - name: openai-secret - ai: - routes: - "/v1/chat/completions": "completions" - "/v1/embeddings": "passthrough" - "/v1/models": "passthrough" - "*": "passthrough" - EOF - ``` - - | Setting | Description | - |---------|-------------| - | `v1/chat/completions` | Routes to the chat completions endpoint with LLM-specific processing. This endpoint is used for chat-based interactions. For more information, see the [OpenAI API docs for the endpoint](https://platform.openai.com/docs/api-reference/chat).| - | `v1/embeddings` | Routes to the embeddings endpoint with passthrough processing. This endpoint is used to to get vector embeddings that machine learning models can use more easily than chat-based interactions. For more information, see the [OpenAI API docs for the endpoint](https://platform.openai.com/docs/api-reference/embeddings).| - | `v1/models` | Routes to the models endpoint with passthrough processing. This endpoint is used to get basic information about the models that are available. For more information, see the [OpenAI API docs for the endpoint](https://platform.openai.com/docs/api-reference/models/list).| - | `*` | Matches any path that doesn't match the specific endpoints otherwise set. Typically, you set this value to `passthrough` to pass through to the provider API without LLM-specific processing.| - -2. Create an HTTPRoute resource that routes traffic to the OpenAI {{< reuse "agw-docs/snippets/backend.md" >}} along the `/openai` path matcher. Note that because you set up the `routes` map on the {{< reuse "agw-docs/snippets/backend.md" >}}, you do not need to create any URLRewrite filters to point your route matcher to the correct LLM provider endpoint. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /openai - backendRefs: - - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` -3. Send requests to different OpenAI endpoints. With the routes configured, you can access different OpenAI endpoints by including the full path in your requests: - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - **Chat completions:** - ```sh - curl "$INGRESS_GW_ADDRESS/openai/v1/chat/completions" \ - -H content-type:application/json \ - -d '{ - "model": "gpt-3.5-turbo", - "messages": [{"role": "user", "content": "Hello!"}] - }' | jq - ``` - - **Embeddings:** - ```sh - curl "$INGRESS_GW_ADDRESS/openai/v1/embeddings" \ - -H content-type:application/json \ - -d '{ - "model": "text-embedding-ada-002", - "input": "The food was delicious" - }' | jq - ``` - - **Models list:** - ```sh - curl "$INGRESS_GW_ADDRESS/openai/v1/models" | jq - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - **Chat completions:** - ```sh - curl "localhost:8080/openai/v1/chat/completions" \ - -H content-type:application/json \ - -d '{ - "model": "gpt-3.5-turbo", - "messages": [{"role": "user", "content": "Hello!"}] - }' | jq - ``` - - **Embeddings:** - ```sh - curl "localhost:8080/openai/v1/embeddings" \ - -H content-type:application/json \ - -d '{ - "model": "text-embedding-ada-002", - "input": "The food was delicious" - }' | jq - ``` - - **Models list:** - ```sh - curl "localhost:8080/openai/v1/models" | jq - ``` - {{% /tab %}} - {{< /tabs >}} diff --git a/assets/docs/pages/agentgateway/llm/providers/openai-compatible.md b/assets/docs/pages/agentgateway/llm/providers/openai-compatible.md deleted file mode 100644 index fa43063d8..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/openai-compatible.md +++ /dev/null @@ -1,378 +0,0 @@ -Configure OpenAI-compatible LLM providers such as Mistral, DeepSeek, or any other provider that implements the OpenAI API format in {{< reuse "agw-docs/snippets/agw-kgw.md" >}}. - -## Overview - -Many LLM providers offer APIs that are compatible with OpenAI's API format. You can configure these providers in agentgateway by using the `openai` provider type with custom `host`, `port`, `path`, and `authHeader` overrides. - -Note that when you specify a custom `host` override, agentgateway requires explicit TLS configuration via `BackendTLSPolicy` for HTTPS endpoints. This differs from well-known providers (like OpenAI) where TLS is automatically enabled when using default hosts. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Set up access to an OpenAI-compatible provider - -Review the following examples for common OpenAI-compatible provider endpoints: - -- [Mistral AI](#mistral) -- [DeepSeek](#deepseek) - -### Mistral AI example {#mistral} - -Set up OpenAI-compatible provider access to [Mistral AI](https://mistral.ai/) models. - -1. Get a [Mistral AI API key](https://console.mistral.ai/). - -2. Save the API key in an environment variable. - - ```sh - export MISTRAL_API_KEY= - ``` - -3. Create a Kubernetes secret to store your Mistral AI API key. - - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $MISTRAL_API_KEY - EOF - ``` - -4. Create a {{< reuse "agw-docs/snippets/backend.md" >}} resource using the `openai` provider type with custom host and port overrides. - - ```yaml - kubectl apply -f- <}} - metadata: - name: mistral - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - type: AI - ai: - llm: - openai: - authToken: - kind: SecretRef - secretRef: - name: mistral-secret - model: "mistral-medium-2505" - host: api.mistral.ai - port: 443 - path: - full: "/v1/chat/completions" - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} - - | Setting | Description | - |-------------|-------------| - | `type` | Set to `AI` to configure this {{< reuse "agw-docs/snippets/backend.md" >}} for an AI provider. | - | `ai` | Define the AI backend configuration. | - | `openai` | Use the `openai` provider type for OpenAI-compatible providers. | - | `host` | **Required**: The hostname of the OpenAI-compatible provider, such as `api.mistral.ai`. | - | `port` | **Required**: The port number (typically `443` for HTTPS). Both `host` and `port` must be set together. | - | `path` | Optional: Override the API path. Defaults to `/v1/chat/completions` if not specified. | - | `authHeader` | Optional: Override the authentication header format. Defaults to `Authorization: Bearer `. | - | `authToken` | Configure the authentication token. The token is sent in the header specified by `authHeader`. Defaults to the `Authorization` header. | - | `model` | Optional: Override the model name. If unset, the model name is taken from the request. For models, see the [Mistral docs](https://docs.mistral.ai/getting-started/models). | - -5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the OpenAI chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /mistral - filters: - - type: URLRewrite - urlRewrite: - hostname: api.mistral.ai - backendRefs: - - name: mistral - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: gateway.kgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` -6. Create a BackendTLSPolicy to enable TLS for the external Mistral API. - - ```yaml - kubectl apply -f- <}} - spec: - targetRefs: - - name: mistral - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - group: gateway.kgateway.dev - validation: - hostname: api.mistral.ai - wellKnownCACertificates: System - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} - - | Setting | Description | - |----------------------------|-------------| - | `targetRefs` | References the {{< reuse "agw-docs/snippets/backend.md" >}} resource to apply TLS to. | - | `validation.hostname` | The hostname to validate in the server certificate (must match the `host` value in your Backend, e.g., `api.mistral.ai`). | - | `validation.wellKnownCACertificates` | Use the system's trusted CA certificates to verify the server certificate. | -7. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/mistral" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about artificial intelligence." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/mistral" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about artificial intelligence." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "model": "mistral-medium-2505", - "usage": { - "prompt_tokens": 20, - "completion_tokens": 18, - "total_tokens": 38 - }, - "choices": [ - { - "message": { - "content": "Silent circuits hum,\nLearning echoes through the void,\nWisdom without warmth.", - "role": "assistant", - "tool_calls": null - }, - "index": 0, - "finish_reason": "stop" - } - ], - "id": "d05ef3973085435a8db8b51b580eeef8", - "created": 1764614501, - "object": "chat.completion" - } - ``` - - -### DeepSeek example {#deepseek} - -Set up OpenAI-compatible provider access to [DeepSeek](https://www.deepseek.com/en) models. - -1. Get a [DeepSeek API key](https://platform.deepseek.com/). - -2. Save the API key in an environment variable. - - ```sh - export DEEPSEEK_API_KEY= - ``` - -3. Create a Kubernetes secret to store your DeepSeek API key. - - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $DEEPSEEK_API_KEY - EOF - ``` - -4. Create a {{< reuse "agw-docs/snippets/backend.md" >}} resource using the `openai` provider type with custom host and port overrides. - - ```yaml - kubectl apply -f- <}} - metadata: - name: deepseek - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - type: AI - ai: - llm: - openai: - authToken: - kind: SecretRef - secretRef: - name: deepseek-secret - model: "deepseek-chat" - host: "api.deepseek.com" - port: 443 - path: - full: "/v1/chat/completions" - EOF - ``` - -5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the OpenAI chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /deepseek - backendRefs: - - name: deepseek - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: gateway.kgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - -6. Create a BackendTLSPolicy to enable TLS for the external DeepSeek API. - - ```yaml - kubectl apply -f- <}} - spec: - targetRefs: - - name: deepseek - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - group: gateway.kgateway.dev - validation: - hostname: api.deepseek.com - wellKnownCACertificates: System - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} - - | Setting | Description | - |----------------------------|-------------| - | `targetRefs` | References the {{< reuse "agw-docs/snippets/backend.md" >}} resource to apply TLS to. | - | `validation.hostname` | The hostname to validate in the server certificate (must match the `host` value in your Backend, e.g., `api.deepseek.com`). | - | `validation.wellKnownCACertificates` | Use the system's trusted CA certificates to verify the server certificate. | - -7. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/deepseek" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about artificial intelligence." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/deepseek" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about artificial intelligence." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-deepseek-12345", - "object": "chat.completion", - "created": 1727967462, - "model": "deepseek-chat", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Neural networks learn,\nPatterns emerge from data streams,\nMind in silicon grows." - }, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 20, - "completion_tokens": 17, - "total_tokens": 37 - } - } - ``` - -{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}} diff --git a/assets/docs/pages/agentgateway/llm/providers/openai-compatible2.2+.md b/assets/docs/pages/agentgateway/llm/providers/openai-compatible2.2+.md deleted file mode 100644 index 592e80c2f..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/openai-compatible2.2+.md +++ /dev/null @@ -1,318 +0,0 @@ -Configure OpenAI-compatible LLM providers such as Mistral, DeepSeek, or any other provider that implements the OpenAI API format in {{< reuse "agw-docs/snippets/agw-kgw.md" >}}. - -## Overview - -Many LLM providers offer APIs that are compatible with OpenAI's API format. You can configure these providers in agentgateway by using the `openai` provider type with custom `host`, `port`, `path`, and `authHeader` overrides. - -Note that when you specify a custom `host` override, agentgateway requires explicit TLS configuration via `BackendTLSPolicy` for HTTPS endpoints. This differs from well-known providers (like OpenAI) where TLS is automatically enabled when using default hosts. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Set up access to an OpenAI-compatible provider - -Review the following examples for common OpenAI-compatible provider endpoints: - -- [Mistral AI](#mistral) -- [DeepSeek](#deepseek) - -### Mistral AI example {#mistral} - -Set up OpenAI-compatible provider access to [Mistral AI](https://mistral.ai/) models. - -1. Get a [Mistral AI API key](https://console.mistral.ai/). - -2. Save the API key in an environment variable. - - ```sh - export MISTRAL_API_KEY= - ``` - -3. Create a Kubernetes secret to store your Mistral AI API key. - - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $MISTRAL_API_KEY - EOF - ``` - -4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure your LLM provider and reference the AI API key secret that you created earlier. - ```yaml - kubectl apply -f- <}} - metadata: - name: mistral - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - openai: - model: mistral-medium-2505 - host: api.mistral.ai - port: 443 - path: "/v1/chat/completions" - policies: - auth: - secretRef: - name: mistral-secret - tls: - sni: api.mistral.ai - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.openai` | Define the OpenAI-compatible provider. | - | `openai.model` | The model to use, such as `mistral-medium-2505`. | - | `openai.host` | **Required**: The hostname of the OpenAI-compatible provider, such as `api.mistral.ai`. | - | `openai.port` | **Required**: The port number (typically `443` for HTTPS). Both `host` and `port` must be set together. | - | `openai.path` | Optional: Override the API path. Defaults to `/v1/chat/completions` if not specified. | - | `policies.auth` | Configure the authentication token for OpenAI API. The example refers to the secret that you previously created.| - | `policies.tls.sni` | The hostname for which to validate the server certificate (must match the `host` value). | - -5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. The `URLRewrite` filter rewrites the path from `/openai` to the path of the API in the LLM provider that you want to use, `/v1/chat/completions`. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /mistral - filters: - - type: URLRewrite - urlRewrite: - hostname: api.mistral.ai - backendRefs: - - name: mistral - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` -6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/mistral" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about artificial intelligence." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/mistral" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about artificial intelligence." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "model": "mistral-medium-2505", - "usage": { - "prompt_tokens": 20, - "completion_tokens": 18, - "total_tokens": 38 - }, - "choices": [ - { - "message": { - "content": "Silent circuits hum,\nLearning echoes through the void,\nWisdom without warmth.", - "role": "assistant", - "tool_calls": null - }, - "index": 0, - "finish_reason": "stop" - } - ], - "id": "d05ef3973085435a8db8b51b580eeef8", - "created": 1764614501, - "object": "chat.completion" - } - ``` - -### DeepSeek example {#deepseek} - -Set up OpenAI-compatible provider access to [DeepSeek](https://www.deepseek.com/en) models. - -1. Get a [DeepSeek API key](https://platform.deepseek.com/). - -2. Save the API key in an environment variable. - - ```sh - export DEEPSEEK_API_KEY= - ``` - -3. Create a Kubernetes secret to store your DeepSeek API key. - - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $DEEPSEEK_API_KEY - EOF - ``` - -4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure your LLM provider and reference the AI API key secret that you created earlier. - ```yaml - kubectl apply -f- <}} - metadata: - name: deepseek - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - openai: - model: deepseek-chat - host: api.deepseek.com - port: 443 - path: "/v1/chat/completions" - policies: - auth: - secretRef: - name: deepseek-secret - tls: - sni: api.deepseek.com - EOF - ``` - -5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the OpenAI chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /deepseek - backendRefs: - - name: deepseek - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - -6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/deepseek" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about artificial intelligence." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/deepseek" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant." - }, - { - "role": "user", - "content": "Write a short haiku about artificial intelligence." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-deepseek-12345", - "object": "chat.completion", - "created": 1727967462, - "model": "deepseek-chat", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Neural networks learn,\nPatterns emerge from data streams,\nMind in silicon grows." - }, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 20, - "completion_tokens": 17, - "total_tokens": 37 - } - } - ``` - -{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}} diff --git a/assets/docs/pages/agentgateway/llm/providers/openai.md b/assets/docs/pages/agentgateway/llm/providers/openai.md deleted file mode 100644 index 913bd1927..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/openai.md +++ /dev/null @@ -1,161 +0,0 @@ -Configure [OpenAI](https://openai.com/) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Set up access to OpenAI - -1. [Create an API key to access the OpenAI API](https://platform.openai.com/api-keys). If you use another AI provider, create an API key for that provider's AI instead, and be sure to modify the example commands in these tutorials to use your provider's AI API instead. - -2. Save the API key in an environment variable. - - ```sh - export OPENAI_API_KEY= - ``` - -3. Create a Kubernetes secret to store your AI API key. - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $OPENAI_API_KEY - EOF - ``` - - -4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure an LLM provider that references the AI API key secret. - ```yaml - kubectl apply -f- <}} - metadata: - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - openai: - model: gpt-3.5-turbo # Optional: specify default model - # host: api.openai.com # Optional: custom host if needed - # port: 443 # Optional: custom port - policies: - auth: - secretRef: - name: openai-secret - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.openai` | Define the OpenAI provider. | - | `openai.model` | The OpenAI model to use, such as `gpt-3.5-turbo`. | - | `policies.auth` | Configure the authentication token for OpenAI API. The example refers to the secret that you previously created.| - -5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. The `URLRewrite` filter rewrites the path from `/openai` to the path of the API in the LLM provider that you want to use, `/v1/chat/completions`. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /openai - backendRefs: - - name: openai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." - }, - { - "role": "user", - "content": "Compose a poem that explains the concept of recursion in programming." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/openai" -H content-type:application/json -d '{ - "model": "gpt-3.5-turbo", - "messages": [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." - }, - { - "role": "user", - "content": "Compose a poem that explains the concept of recursion in programming." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-AEHYs2B0XUlEioCduH1meERmMwBGF", - "object": "chat.completion", - "created": 1727967462, - "model": "gpt-3.5-turbo-0125", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "In the world of code, a method elegant and rare,\nKnown as recursion, a loop beyond compare.\nLike a mirror reflecting its own reflection,\nIt calls upon itself with deep introspection.\n\nA function that calls itself with artful grace,\nDividing a problem into a smaller space.\nLike a nesting doll, layers deep and profound,\nIt solves complex tasks, looping around.\n\nWith each recursive call, a step is taken,\nTowards solving the problem, not forsaken.\nA dance of self-replication, a mesmerizing sight,\nUnraveling complexity with power and might.\n\nBut beware of infinite loops, a perilous dance,\nWithout a base case, it's a risky chance.\nFor recursion is a waltz with a delicate balance,\nInfinite beauty, yet a risky dalliance.\n\nSo embrace the concept, in programming's domain,\nLet recursion guide you, like a poetic refrain.\nA magical loop, a recursive song,\nIn the symphony of code, where brilliance belongs.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 39, - "completion_tokens": 200, - "total_tokens": 239, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0 - } - }, - "system_fingerprint": null - } - ``` - -{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}} diff --git a/assets/docs/pages/agentgateway/llm/providers/vertex.md b/assets/docs/pages/agentgateway/llm/providers/vertex.md deleted file mode 100644 index f9fc717cc..000000000 --- a/assets/docs/pages/agentgateway/llm/providers/vertex.md +++ /dev/null @@ -1,139 +0,0 @@ -Configure [Vertex AI](https://cloud.google.com/vertex-ai) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Set up access to Vertex AI - -1. [Set up authentication for Vertex AI](https://docs.cloud.google.com/vertex-ai/docs/authentication). Make sure to have your: - - - Google Cloud Project ID - - Project location, such as `us-central1` - - API key or service account credentials - -2. Save your Vertex AI API key as an environment variable. - - ```sh - export VERTEX_AI_API_KEY= - ``` - -3. Create a Kubernetes secret to store your Vertex AI API key. - - ```yaml - kubectl apply -f- <}} - type: Opaque - stringData: - Authorization: $VERTEX_AI_API_KEY - EOF - ``` - -4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure an LLM provider that references the AI API key secret. - ```yaml - kubectl apply -f- <}} - metadata: - name: vertex-ai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - vertexai: - model: gemini-pro - projectId: "my-gcp-project" - region: "us-central1" - policies: - auth: - secretRef: - name: vertex-ai-secret - EOF - ``` -5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. The `URLRewrite` filter rewrites the path from `/openai` to the path of the API in the LLM provider that you want to use, `/v1/chat/completions`. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /vertex - backendRefs: - - name: vertex-ai - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl "$INGRESS_GW_ADDRESS/vertex" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "user", - "content": "Write me a short poem about Kubernetes and clouds." - } - ] - }' | jq - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl "localhost:8080/vertex" -H content-type:application/json -d '{ - "model": "", - "messages": [ - { - "role": "user", - "content": "Write me a short poem about Kubernetes and clouds." - } - ] - }' | jq - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```json - { - "id": "chatcmpl-vertex-12345", - "object": "chat.completion", - "created": 1727967462, - "model": "gemini-pro", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "In the cloud, Kubernetes reigns,\nOrchestrating pods with great care,\nContainers float like clouds,\nScaling up and down,\nAutomation everywhere." - }, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 12, - "completion_tokens": 28, - "total_tokens": 40 - } - } - ``` - -{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}} diff --git a/assets/docs/pages/agentgateway/llm/tracing.md b/assets/docs/pages/agentgateway/llm/tracing.md deleted file mode 100644 index b2e3e8276..000000000 --- a/assets/docs/pages/agentgateway/llm/tracing.md +++ /dev/null @@ -1,224 +0,0 @@ -Use a custom ConfigMap to configure your {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy for tracing. - -## Before you begin - -{{< reuse "agw-docs/snippets/agentgateway-prereq.md" >}} - -## Set up an OpenTelemetry collector - -Install an OpenTelemetry collector that the {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy can send traces to. Depending on your environment, you can further configure your OpenTelemetry to export these traces to your preferred tracing platform, such as Jaeger. - -1. Install the OTel collector. - ```sh - helm upgrade --install opentelemetry-collector-traces opentelemetry-collector \ - --repo https://open-telemetry.github.io/opentelemetry-helm-charts \ - --version 0.127.2 \ - --set mode=deployment \ - --set image.repository="otel/opentelemetry-collector-contrib" \ - --set command.name="otelcol-contrib" \ - --namespace=telemetry \ - --create-namespace \ - -f -<}} resource with your tracing configuration. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - metadata: - name: tracing - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - rawConfig: - config: - tracing: - otlpEndpoint: http://opentelemetry-collector-traces.telemetry.svc.cluster.local:4317 # replace with your telemetry collector endpoint - otlpProtocol: grpc # replace with your telemetry collector protocol - randomSampling: true - fields: - add: - gen_ai.operation.name: '"chat"' - gen_ai.system: "llm.provider" - gen_ai.request.model: "llm.requestModel" - gen_ai.response.model: "llm.responseModel" - gen_ai.usage.completion_tokens: "llm.outputTokens" - gen_ai.usage.prompt_tokens: "llm.inputTokens" - EOF - ``` - -2. Create your {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy. Make sure to reference the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource that you created so that your proxy starts with the custom tracing configuration. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - infrastructure: - parametersRef: - name: tracing - group: {{< reuse "agw-docs/snippets/gatewayparam-group.md" >}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - listeners: - - protocol: HTTP - port: 80 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. Verify that your {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy is up and running. - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ```console - NAMESPACE NAME READY STATUS RESTARTS AGE - {{< reuse "agw-docs/snippets/namespace.md" >}} agentgateway-proxy-8b5dc4874-bl79q 1/1 Running 0 12s - ``` - -4. Get the external address of the gateway and save it in an environment variable. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} agentgateway-proxy -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80 - ``` - {{% /tab %}} - {{< /tabs >}} - - - -## Set up access to Gemini - -Configure access to an LLM provider such as Gemini and send a sample request. You later use this request to verify your tracing configuration. - -{{< reuse "agw-docs/snippets/gemini-setup.md" >}} - -## Verify tracing - -1. Get the logs of the agentgateway proxy. In the CLI output, find the `trace.id`. - ```sh - kubectl logs deploy/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ```console{hl_lines=[5]} - info request gateway={{< reuse "agw-docs/snippets/namespace.md" >}}/agentgateway-proxy listener=http - route={{< reuse "agw-docs/snippets/namespace.md" >}}/google endpoint=generativelanguage.googleapis.com:443 - src.addr=127.0.0.1:49576 http.method=POST http.host=localhost - http.path=/gemini http.version=HTTP/1.1 http.status=200 - trace.id=d65e4eeb983e2d964e71e8dc8c405f97 span.id=b836e1b1d51b3e74 - llm.provider=gemini llm.request.model= llm.request.tokens=8 - llm.response.model=gemini-1.5-flash-latest llm.response.tokens=313 duration=3165ms - ``` - -2. Get the logs of the collector and search for the trace ID. Verify that you see the additional LLM that you configured initially. - ```sh - kubectl logs deploy/opentelemetry-collector-traces -n telemetry - ``` - - Example output: - ```console - Span #0 - Trace ID : d65e4eeb983e2d964e71e8dc8c405f97 - Parent ID : - ID : b836e1b1d51b3e74 - Name : POST /gemini - Kind : Server - Start time : 2025-09-24 18:12:58.653868462 +0000 UTC - End time : 2025-09-24 18:13:01.821700755 +0000 UTC - Status code : Unset - Status message : - Attributes: - -> gateway: Str({{< reuse "agw-docs/snippets/namespace.md" >}}/agentgateway) - -> listener: Str(http) - -> route: Str({{< reuse "agw-docs/snippets/namespace.md" >}}/google) - -> endpoint: Str(generativelanguage.googleapis.com:443) - -> src.addr: Str(127.0.0.1:49576) - -> http.method: Str(POST) - -> http.host: Str(localhost) - -> http.path: Str(/gemini) - -> http.version: Str(HTTP/1.1) - -> http.status: Int(200) - -> trace.id: Str(d65e4eeb983e2d964e71e8dc8c405f97) - -> span.id: Str(b836e1b1d51b3e74) - -> llm.provider: Str(gemini) - -> llm.request.model: Str() - -> llm.request.tokens: Int(8) - -> llm.response.model: Str(gemini-1.5-flash-latest) - -> llm.response.tokens: Int(313) - -> duration: Str(3165ms) - -> url.scheme: Str(http) - -> network.protocol.version: Str(1.1) - -> gen_ai.operation.name: Str(chat) - -> gen_ai.system: Str(gemini) - ``` - - - -## Other tracing configurations - -Review common tracing providers configurations that you can use with agentgateway. - -{{< reuse "agw-docs/snippets/agentgateway/tracing-config.md" >}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} tracing -n {{< reuse "agw-docs/snippets/namespace.md" >}} -helm uninstall opentelemetry-collector-traces -n telemetry -kubectl delete httproute google -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} google -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete secret google-secret -n {{< reuse "agw-docs/snippets/namespace.md" >}} - -``` \ No newline at end of file diff --git a/assets/docs/pages/agentgateway/mcp/about.md b/assets/docs/pages/agentgateway/mcp/about.md deleted file mode 100644 index cf12431bf..000000000 --- a/assets/docs/pages/agentgateway/mcp/about.md +++ /dev/null @@ -1,26 +0,0 @@ -Learn more about MCP and common challenges when adopting MCP in enterprise environments. - -## About MCP - -[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that standardizes how Large Language Model (LLM) applications connect to various external data sources and tools. Without MCP, you need to implement custom integrations for each tool that your LLM application needs to access. However, this approach is hard to maintain and can cause issues when you want to scale your environment. With MCP, you can significantly speed up, simplify, and standardize these types of integrations. - -An MCP server exposes external data sources and tools so that LLM applications can access them. Typically, you want to deploy these servers remotely and have authorization mechanisms in place so that LLM applications can safely access the data. - -With {{< reuse "agw-docs/snippets/agentgateway.md" >}}, you can connect to one or multiple MCP servers in any environment. {{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} proxies requests to the MCP tool that is exposed on the server. - -## MCP vs. A2A - -MCP and [Agent-to-Agent (A2A)](https://github.com/a2aproject/A2A) are the leading protocols for enabling communication between agents and tools. MCP helps to retrieve and exchange context with Large Language Models (LLMs) and connect LLMs to tools. On the other hand, A2A solves for long-running tasks and state management across multiple agents. MCP and A2A are both JSON-RPC protocols that define the structure of how an agent describes what it wants to do, how it calls tools, and how it hands off tasks to other agents. - -## Challenges with MCP and A2A -While MCP and A2A define the RPC communication protocol for agents and tools, they currently do not address real-world, enterprise-level concerns. - -Agents typically do not operate in isolation. Instead, they interact with each other (agent-to-agent), with internal systems (agent-to-tool), and external or foundational models (agent-to-LLM). These interactions are often dynamic, multi-modal, and span organizational and data boundaries. - -Such long-lived interactivity creates new vectors for risk and complexity, including: -* **Security**: How to handle authentication, authorization, and auditing of agent interactions across tools and services? -* **Governance**: How to enforce policies across autonomous workflows, such as data residency or access control? -* **Observability**: How to gain visibility into what agents are doing, when, and why? -* **Scalability and performance**: How to ensure low latency while securely handling retries, timeouts, and failures? - -{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} is designed to tackle these challenges at its core with built-in security, governance, and observability for all MCP and A2A communication between agents, tools, and LLMs. \ No newline at end of file diff --git a/assets/docs/pages/agentgateway/mcp/dynamic.md b/assets/docs/pages/agentgateway/mcp/dynamic.md deleted file mode 100644 index 5e0119e1d..000000000 --- a/assets/docs/pages/agentgateway/mcp/dynamic.md +++ /dev/null @@ -1,158 +0,0 @@ -Route to a Model Context Protocol (MCP) server dynamically by using a label selector. This way, unlike a static backend, you can update the backing MCP server without having to update the Backend resource. For more information, see the [About MCP]({{< link-hextra path="/mcp/about" >}}) topic. - -{{< callout type="warning" >}} -Note that only streamable HTTP is currently supported for label selectors. If you need to use an SSE listener, use a [static MCP Backend](../static-mcp/). -{{< /callout >}} - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Step 1: Deploy an MCP server {#mcp-server} - -Deploy an MCP server that you want {{< reuse "agw-docs/snippets/agentgateway.md" >}} to proxy traffic to. The following example sets up an MCP server that provides various utility tools. - -1. Create an MCP server (`mcp-server`) that provides various utility tools. Notice the following details about the Service: - * `appProtocol: kgateway.dev/mcp` (required): Configure your service to use the MCP protocol. This way, the agentgateway proxy uses the MCP protocol when connecting to the service. - * `kgateway.dev/mcp-path` annotation (optional): The default values are `/sse` for the SSE protocol or `/mcp` for the Streamable HTTP protocol. If you need to change the path of the MCP target endpoint, set this annotation on the Service. - - ```yaml - kubectl apply -f- <}} for your MCP server that uses label selectors to select the MCP server. - - ```yaml - kubectl apply -f- <}} - metadata: - name: mcp-backend - spec: - mcp: - targets: - - name: mcp-server-everything - selector: - services: - matchLabels: - app: mcp-server-everything - EOF - ``` - - -## Step 2: Route with agentgateway {#agentgateway} - -Create an HTTPRoute resource that routes to the Backend that you created in the previous step. - - -```yaml -kubectl apply -f- <}} - rules: - - backendRefs: - - name: mcp-backend - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} -EOF -``` - - -## Step 3: Verify the connection {#verify} - -Use the [MCP Inspector tool](https://modelcontextprotocol.io/docs/tools/inspector) to verify that you can connect to your MCP server through {{< reuse "agw-docs/snippets/agentgateway.md" >}}. - -1. Get the agentgateway address. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80 - ``` - {{% /tab %}} - {{< /tabs >}} - -2. From the terminal, install the MCP Inspector tool. Then, the MCP Inspector opens in your browser. If the MCP inspector tool does not open automatically, run `mcp-inspector`. - ```sh - npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}} - ``` - -3. From the MCP Inspector menu, connect to your agentgateway address as follows: - * **Transport Type**: Select `Streamable HTTP`. - * **URL**: Enter the agentgateway address, port, and the `/mcp` path. If your agentgateway proxy is exposed with a LoadBalancer server, use `http:///mcp`. In local test setups where you port-forwarded the agentgateway proxy on your local machine, use `http://localhost:8080/mcp`. - * Click **Connect**. - -4. From the menu bar, click the **Tools** tab, then click **List Tools**. - - {{< reuse-image src="img/mcp-tools-everything.png" >}} - {{< reuse-image-dark srcDark="img/mcp-tools-everything-dark.png" >}} - -5. Test the tools: Select a tool, such as `echo`. In the **message** field, enter a message, such as `Hello, world!`, and click **Run Tool**. - - {{< reuse-image src="img/mcp-tool-echo.png" >}} - {{< reuse-image-dark srcDark="img/mcp-tool-echo-dark.png" >}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete Deployment mcp-server-everything -kubectl delete Service mcp-server-everything -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} mcp-backend -kubectl delete HTTPRoute mcp -``` \ No newline at end of file diff --git a/assets/docs/pages/agentgateway/mcp/https.md b/assets/docs/pages/agentgateway/mcp/https.md deleted file mode 100644 index 443cae18a..000000000 --- a/assets/docs/pages/agentgateway/mcp/https.md +++ /dev/null @@ -1,124 +0,0 @@ -## About this guide - -In this guide, you configure your agentgateway proxy to connect to the remote [GitHub MCP server](https://github.com/github/github-mcp-server) by using the HTTPS protocol. The server allows you to interact with GitHub repositories, issues, pull requests, and more. All connections to the server must be secured via HTTPS and a GitHub access token must be provided for authentication. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Connect to the MCP server - -1. Create a personal access token in GitHub and save it in an environment variable. For more information, see the [GitHub docs](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). - ```sh - export GH_PAT= - ``` - -2. Create the {{< reuse "agw-docs/snippets/backend.md" >}} for the remote GitHub MCP server. The server requires you to connect to it by using the HTTPS protocol. Because of that, you set the `mcp.targets.static.port` field to 443. - - ```yaml - kubectl apply -f- <}} - spec: - mcp: - targets: - - name: mcp-target - static: - host: api.githubcopilot.com - port: 443 - path: /mcp/ - policies: - tls: - sni: api.githubcopilot.com - EOF - ``` -3. Create an HTTPRoute that routes traffic to the GitHub MCP server along the `/mcp-github` path. To properly connect to the MCP server, you must allow traffic from `http://localhost:8080`, which is the domain and port you expose your agentgateway proxy on later. If you expose the proxy under a different domain, make sure to add this domain to the allowed origins. Because the MCP server also requires a GitHub access token to connect, you set the `Authorization` header to the token that you created earlier. - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /mcp-github - filters: - - type: CORS - cors: - allowHeaders: - - "*" - allowMethods: - - "*" - allowOrigins: - - "http://localhost:8080" - - type: RequestHeaderModifier - requestHeaderModifier: - set: - - name: Authorization - value: "Bearer ${GH_PAT}" - backendRefs: - - name: github-mcp-backend - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - - - -## Verify the connection {#verify} - -Use the [MCP Inspector tool](https://modelcontextprotocol.io/legacy/tools/inspector) to verify that you can connect to your sample MCP server through agentgateway. - -1. Get the agentgateway address. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - kubectl port-forward deployment/agentgateway-proxy 8080:80 -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - {{% /tab %}} - {{< /tabs >}} - -2. From your terminal, run the MCP Inspector command to open the MCP Inspector in your browser. If the MCP inspector tool does not open automatically, run `mcp-inspector`. - ```sh - npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}} - ``` - -3. From the MCP Inspector menu, connect to your agentgateway address as follows: - * **Transport Type**: Select `Streamable HTTP`. - * **URL**: Enter the agentgateway address, port, and the `/mcp-github` path. If your agentgateway proxy is exposed with a LoadBalancer server, use `http:///mcp-github`. In local test setups where you port-forwarded the agentgateway proxy on your local machine, use `http://localhost:8080/mcp-github`. - * Click **Connect**. - -4. From the menu bar, click the **Tools** tab. Then from the **Tools** pane, click **List Tools** and select the `get_me` tool. -5. Click **Run Tool**. -6. Verify that you get back information about your username. - - {{< reuse-image src="img/mcp-inspector-gh.png" >}} - {{< reuse-image-dark srcDark="img/mcp-inspector-gh-dark.png" >}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} github-mcp-backend -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete HTTPRoute mcp-github -n {{< reuse "agw-docs/snippets/namespace.md" >}} - -``` diff --git a/assets/docs/pages/agentgateway/mcp/mcp-access.md b/assets/docs/pages/agentgateway/mcp/mcp-access.md deleted file mode 100644 index 78e7f4a9f..000000000 --- a/assets/docs/pages/agentgateway/mcp/mcp-access.md +++ /dev/null @@ -1,370 +0,0 @@ -Control access or route traffic based on verified claims in a JSON web token (JWT). - -## About MCP auth - -In this guide, you learn how to configure your agentgateway proxy to validate JWT tokens that are provided in an `Authorization` header. You then authorize access to specific MCP tools based on specific claims in the JWT. - -The following diagram shows the components that are involved when performing JWT validation and authorization with MCP servers: - -```mermaid -sequenceDiagram - autonumber - Client->>+Agentgateway: Send request with JWT - Agentgateway->>Agentgateway: Validate JWT token - Agentgateway->>Agentgateway: Authorize access to MCP server - Agentgateway->>+MCP: Forward request -``` - -1. The MCP client, such as the MCP inspector tool, sends a request to the agentgateway proxy with the JWT token in the `Authorization` header. -2. The agentgateway proxy validates the JWT with the JWKS server that you define in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource. This policy is applied to the agentgateway proxy. -3. If the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} further defines RBAC rules, such as to only grant access for JWT tokens with certain claims, the agentgateway proxy validates these claims and either grants or denies access. -4. If successfully validated and authorized, the agentgateway proxy forwards the request to the MCP backend. - -## Before you begin - -1. Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). -2. Follow the steps to connect to the [remote GitHub MCP server via HTTPS]({{< link-hextra path="/mcp/https/" >}}). - -## Validate JWT tokens - -You can configure your agentgateway proxy to validate JWT tokens that are sent by an MCP client in an `Authorization` header. - -1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your JWT validation rules and apply it to the agentgateway proxy that you created before you began. In this example, you use an inline, local JSON Web Key Set (JWKS) to verify the JWT. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: jwt - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: agentgateway-proxy - traffic: - jwtAuthentication: - mode: Strict - providers: - - issuer: solo.io - jwks: - inline: '{"keys":[{"use":"sig","kty":"RSA","kid":"5891645032159894383","n":"5Zb1l_vtAp7DhKPNbY5qLzHIxDEIm3lpFYhBTiZyGBcnre8Y8RtNAnHpVPKdWohqhbihbVdb6U7m1E0VhLq7CS7k2Ng1LcQtVN3ekaNyk09NHuhl9LCgqXT4pATt6fYTKtZ__tEw4XKt3QqVcw7hV0YaNVC5xXGYVBh5_2-K5aW9u2LQ7FSax0jPhWdoUB3KbOQfWNOA3RwOqYn4gmc9wVToVLv6bXCVhIYWKnAVcX89C00eM7uBHENvOydD14-ZnLb4pzz2VGbU6U65odpw_i4r_mWXvoUgwogXAXp80TsYwMzLHcFo4GVDNkaH0hjuLJCeISPfYtbUJK6fFaZGBw","e":"AQAB","x5c":["MIIC3jCCAcagAwIBAgIBJTANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwHhcNMjUxMjE4MTkzNDQyWhcNMjUxMjE4MjEzNDQyWjAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDllvWX++0CnsOEo81tjmovMcjEMQibeWkViEFOJnIYFyet7xjxG00CcelU8p1aiGqFuKFtV1vpTubUTRWEursJLuTY2DUtxC1U3d6Ro3KTT00e6GX0sKCpdPikBO3p9hMq1n/+0TDhcq3dCpVzDuFXRho1ULnFcZhUGHn/b4rlpb27YtDsVJrHSM+FZ2hQHcps5B9Y04DdHA6pifiCZz3BVOhUu/ptcJWEhhYqcBVxfz0LTR4zu4EcQ287J0PXj5mctvinPPZUZtTpTrmh2nD+Liv+ZZe+hSDCiBcBenzROxjAzMsdwWjgZUM2RofSGO4skJ4hI99i1tQkrp8VpkYHAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQBeA8lKrnfRjo18RkLBqVKuO441nZLFGKrJwpJu+G5cVOJ06txKsZEXE3qu2Yh9abeOJkC+SsWMELWHYNJlip4JGE0Oby7chol+ahrwBILUixBG/qvhwJG6YntoDZi0wbNFqQiQ6FZt89awcs2pdxL5thYR/Pqx4QXN8oKd4DNkcX5vWdz9P6nstLUmrEBV4EFs7fY0L/n3ssDvyZ3xfpM1Q/CQFz4OqB4U20+Qt6x7eap6qhTSBZt8rZWIiy57BsSww12gLYYU1x+Klg1AdPsVrcuvVdiZM1ru232Ihip0rYH7Mf7vcN+HLUrjpXvMoeyWRwbB61GPsXz+BTksqoql"]}]}' - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} For more information, see the [API docs]({{< link-hextra path="/reference/api/#jwtprovider" >}}). - - | Field | Description | - | ----- | ----- | - | `issuer` | The principal that issued the JWT, usually a URL or an email address. If specified, the `iss` field in the JWT of the incoming request must match this field, or else the request is denied. If omitted, the `iss` field in the JWT is not checked. | - | `jwks` | The JSON Web Key Set (JWKS) to use to verify the JWT. In this example, a local JWKS is provided inline. To use JWTs with {{< reuse "agw-docs/snippets/agentgateway.md" >}}, make sure that the JWTs return Key ID (`kid`) and expiration date (`exp`) values in the JWT header.| - -2. Save the JWT tokens for the users Alice and Bob. You can optionally create other JWT tokens by using the [JWT generator tool](https://github.com/kgateway-dev/kgateway/blob/main/hack/utils/jwt/jwt-generator.go). Note that to use JWTs with agentgateway proxies, make sure that the JWTs return Key ID (`kid`) and expiration date (`exp`) values in the JWT header. - - 1. Save the JWT token for Alice. Alice works in the `dev` team. - ```sh - export ALICE_JWT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw" - ``` - - 2. Save the JWT token for Bob. Bob works in the `ops` team. - - ```sh - export BOB_JWT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og" - ``` - -3. Send an unauthenticated request to the MCP server. - {{< tabs tabTotal="2" items="CLI,UI" >}} - {{% tab tabName="CLI" %}} - 1. Send a request to the MCP server. - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name get_me - ``` - 2. Verify that the request fails, because no JWT token was provided. - ```console - Failed to connect to MCP server: Streamable HTTP error: - Error POSTing to endpoint: authentication failure: no bearer token found - ``` - {{% /tab %}} - {{% tab tabName="UI" %}} - 1. From the terminal, run the MCP Inspector command. Then, the MCP Inspector opens in your browser. If the MCP inspector tool does not open automatically, run `mcp-inspector`. - ```sh - npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}} - ``` - - 2. From the MCP Inspector menu, try to connect to your agentgateway address as follows: - * **Transport Type**: Select `Streamable HTTP`. - * **URL**: Enter the agentgateway address, port, and the `/mcp-github` path. If your agentgateway proxy is exposed with a LoadBalancer server, use `http://:8080/mcp-github`. In local test setups where you port-forwarded the agentgateway proxy on your local machine, use `http://localhost:8080/mcp-github`. - * Click **Connect**. - -
- Verify that the connection fails with an error message similar to the following, because no valid JWT was provided from the MCP inspector tool (MCP client) to the agentgateway proxy. - - ```console - Connection Error - Check if your MCP server is running and proxy token is correct - ``` - - {{< reuse-image src="img/mcp-github-error.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-error-dark.png" >}} - {{% /tab %}} - {{< /tabs >}} - -4. Send another request to the MCP server. This time, you provide a valid JWT token for Alice in the `Authorization` header. - {{< tabs tabTotal="2" items="CLI,UI" >}} - {{% tab tabName="CLI" %}} - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name get_me \ - --header "Authorization: Bearer $ALICE_JWT" - ``` - - Verify that the connection succeeds and that you see the GitHub user output. - ```console - { - "content": [ - { - "type": "text", - "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}" - } - ] - } - ``` - {{% /tab %}} - {{% tab tabName="UI" %}} - 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card: - * **Header Name**: Enter `Authorization`. - * **Bearer Token**: Enter the JWT token for Alice. - ```sh - Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw - ``` - * Click **Connect**. - - 2. Verify that the connection now succeeds because a valid token was provided in an `Authorization` header to your agentgateway proxy: - {{< reuse-image src="img/mcp-github-success.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-success-dark.png" >}} - - {{% /tab %}} - {{< /tabs >}} - -5. Repeat the same request with the JWT token for Bob. Verify that you can also connect to your MCP server successfully. - {{< tabs tabTotal="2" items="CLI,UI" >}} - {{% tab tabName="CLI" %}} - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name get_me \ - --header "Authorization: Bearer $BOB_JWT" - ``` - - Verify that the connection also succeeds and that you see the GitHub user output. - ```console - { - "content": [ - { - "type": "text", - "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}" - } - ] - } - ``` - {{% /tab %}} - {{% tab tabName="UI" %}} - 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card: - * **Header Name**: Enter `Authorization`. - * **Bearer Token**: Enter the JWT token for Bob. - ```sh - Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og - ``` - * Click **Connect**. - - 2. Verify that you can also connect to your MCP server successfully. - {{< reuse-image src="img/mcp-github-success.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-success-dark.png" >}} - - {{% /tab %}} - {{< /tabs >}} - -6. Try to enter an invalid JWT token, such as `abcdefg`. Verify that access to the MCP server is denied, because the JWT token could not be validated by your agentgateway proxy. - {{< tabs tabTotal="2" items="CLI,UI" >}} - {{% tab tabName="CLI" %}} - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name get_me \ - --header "Authorization: Bearer abcdefg" - ``` - - Verify that the connection fails, because no valid JWT token was provided. - ```console - Failed to connect to MCP server: Streamable HTTP error: - Error POSTing to endpoint: authentication failure: the token header is malformed: Error(InvalidToken) - ``` - {{% /tab %}} - {{% tab tabName="UI" %}} - 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card: - * **Header Name**: Enter `Authorization`. - * **Bearer Token**: Enter the JWT token for Alice. - ```sh - abcdefg - ``` - * Click **Connect**. - - 2. Verify that the connection fails, because no valid JWT token was provided. - {{< reuse-image src="img/mcp-github-error.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-error-dark.png" >}} - - {{% /tab %}} - {{< /tabs >}} - -7. Optional: You can check the agentgateway proxy logs and verify that you see 403 authentication errors in your log entries. - ```sh - kubectl logs deploy/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ``` - request gateway=default/agentgateway-proxy listener=http route=default/mcp src.addr=127.0.0.1:59068 - http.method=POST http.host=localhost http.path=/mcp http.version=HTTP/1.1 http.status=403 - error=authentication failure: no bearer token found duration=0ms - ``` - -## Authorize access based on JWT claims - -You can limit access to the MCP server based on specific JWT claims with CEL-based RBAC rules. - -1. Update the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to add your RBAC rules. In the following example, you use a CEL expression to only allow access to the MCP server if the JWT has the `sub=alice` claim. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: jwt - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: agentgateway-proxy - traffic: - jwtAuthentication: - mode: Strict - providers: - - issuer: solo.io - jwks: - inline: '{"keys":[{"use":"sig","kty":"RSA","kid":"5891645032159894383","n":"5Zb1l_vtAp7DhKPNbY5qLzHIxDEIm3lpFYhBTiZyGBcnre8Y8RtNAnHpVPKdWohqhbihbVdb6U7m1E0VhLq7CS7k2Ng1LcQtVN3ekaNyk09NHuhl9LCgqXT4pATt6fYTKtZ__tEw4XKt3QqVcw7hV0YaNVC5xXGYVBh5_2-K5aW9u2LQ7FSax0jPhWdoUB3KbOQfWNOA3RwOqYn4gmc9wVToVLv6bXCVhIYWKnAVcX89C00eM7uBHENvOydD14-ZnLb4pzz2VGbU6U65odpw_i4r_mWXvoUgwogXAXp80TsYwMzLHcFo4GVDNkaH0hjuLJCeISPfYtbUJK6fFaZGBw","e":"AQAB","x5c":["MIIC3jCCAcagAwIBAgIBJTANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwHhcNMjUxMjE4MTkzNDQyWhcNMjUxMjE4MjEzNDQyWjAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDllvWX++0CnsOEo81tjmovMcjEMQibeWkViEFOJnIYFyet7xjxG00CcelU8p1aiGqFuKFtV1vpTubUTRWEursJLuTY2DUtxC1U3d6Ro3KTT00e6GX0sKCpdPikBO3p9hMq1n/+0TDhcq3dCpVzDuFXRho1ULnFcZhUGHn/b4rlpb27YtDsVJrHSM+FZ2hQHcps5B9Y04DdHA6pifiCZz3BVOhUu/ptcJWEhhYqcBVxfz0LTR4zu4EcQ287J0PXj5mctvinPPZUZtTpTrmh2nD+Liv+ZZe+hSDCiBcBenzROxjAzMsdwWjgZUM2RofSGO4skJ4hI99i1tQkrp8VpkYHAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQBeA8lKrnfRjo18RkLBqVKuO441nZLFGKrJwpJu+G5cVOJ06txKsZEXE3qu2Yh9abeOJkC+SsWMELWHYNJlip4JGE0Oby7chol+ahrwBILUixBG/qvhwJG6YntoDZi0wbNFqQiQ6FZt89awcs2pdxL5thYR/Pqx4QXN8oKd4DNkcX5vWdz9P6nstLUmrEBV4EFs7fY0L/n3ssDvyZ3xfpM1Q/CQFz4OqB4U20+Qt6x7eap6qhTSBZt8rZWIiy57BsSww12gLYYU1x+Klg1AdPsVrcuvVdiZM1ru232Ihip0rYH7Mf7vcN+HLUrjpXvMoeyWRwbB61GPsXz+BTksqoql"]}]}' - authorization: - action: Allow - policy: - # Any of these conditions will allow access (OR logic) - matchExpressions: - - 'jwt.sub == "alice"' - EOF - ``` - -2. Send a request to the MCP server with Alice's JWT token. Verify that the request succeeds, because the JWT contains the `sub=alice` claim. - {{< tabs tabTotal="2" items="CLI,UI" >}} - {{% tab tabName="CLI" %}} - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name get_me \ - --header "Authorization: Bearer $ALICE_JWT" - ``` - - Example output: - ```console - { - "content": [ - { - "type": "text", - "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}" - } - ] - } - ``` - {{% /tab %}} - {{% tab tabName="UI" %}} - 1. In MCP Inspector tool, expand the **Authentication** section and enter the following details in the **API Token Authentication** card: - * **Header Name**: Enter `Authorization`. - * **Bearer Token**: Enter the JWT token for Alice. - ```sh - Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw - ``` - * Click **Connect**. - - 2. Verify that the connection succeeds, because the JWT contains the `sub=alice` claim. - {{< reuse-image src="img/mcp-github-success.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-success-dark.png" >}} - - {{% /tab %}} - {{< /tabs >}} - -3. Now send a request with Bob's JWT token. Verify that the connection fails, because Bob's JWT token does not have the `sub=alice` claim. - {{< tabs tabTotal="2" items="CLI,UI" >}} - {{% tab tabName="CLI" %}} - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name get_me \ - --header "Authorization: Bearer $BOB_JWT" - ``` - - Example output: - ```console - Failed to connect to MCP server: Streamable HTTP error: - Error POSTing to endpoint: authorization failed - ``` - {{% /tab %}} - {{% tab tabName="UI" %}} - 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card: - * **Header Name**: Enter `Authorization`. - * **Bearer Token**: Enter the JWT token for Bob. - ```sh - Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og - ``` - * Click **Connect**. - - 2. Verify that the request fails, because the JWT does not have the `sub=alice` claim. - {{< reuse-image src="img/mcp-github-error.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-error-dark.png" >}} - - {{% /tab %}} - {{< /tabs >}} - - -## Next - -Explore how to [control access to tools]({{< link-hextra path="/mcp/tool-access/" >}}) with RBAC policies. - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} github-mcp-backend -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete HTTPRoute mcp-github -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} jwt -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` - - - diff --git a/assets/docs/pages/agentgateway/mcp/multiplex.md b/assets/docs/pages/agentgateway/mcp/multiplex.md deleted file mode 100644 index f4c73568b..000000000 --- a/assets/docs/pages/agentgateway/mcp/multiplex.md +++ /dev/null @@ -1,260 +0,0 @@ -To federate multiple MCP servers on the same gateway, you can use a label selector in the MCP Backend. - -This approach makes it easier for you to add more MCP servers by adding labels. It also lets your clients access tools from multiple MCP servers through a single endpoint and MCP connection. - -{{< callout type="warning" >}} -Note that only streamable HTTP is currently supported for label selectors. If you have SSE, use a [static MCP Backend](../static-mcp). -{{< /callout >}} - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Step 1: Deploy the MCP servers {#mcp-server-everythings} - -Deploy multiple Model Context Protocol (MCP) servers that you want agentgateway to proxy traffic to. The following example sets up two MCP servers with different tools: one `npx` based MCP server that provides various utility tools and an MCP server with a website `fetch` tool. - -1. Create an MCP server (`mcp-server-everything`) that provides various utility tools. Notice that the Service uses the `appProtocol: kgateway.dev/mcp` setting. This way, {{< reuse "agw-docs/snippets/kgateway.md" >}} configures the agentgateway proxy to look for an equivalent {{< reuse "agw-docs/snippets/backend.md" >}} resource. - - ```yaml - kubectl apply -f- <}} that selects both MCP servers that you created. - - ```yaml - kubectl apply -f- <}} - metadata: - name: mcp - spec: - mcp: - targets: - - name: mcp-server-everything - selector: - services: - matchLabels: - app: mcp-server-everything - - name: mcp-website-fetcher - static: - host: mcp-website-fetcher.default.svc.cluster.local - port: 80 - protocol: SSE - EOF - ``` - -## Step 2: Route with agentgateway {#agentgateway} - -Route to the federated MCP servers with agentgateway. - -1. Create an HTTPRoute resource that routes to the {{< reuse "agw-docs/snippets/backend.md" >}} that you created in the previous step. - ```yaml - kubectl apply -f- <}} - rules: - - backendRefs: - - name: mcp - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - -2. Check that the HTTPRoute is `Accepted`, selects the Gateway, and includes backend rules for the {{< reuse "agw-docs/snippets/backend.md" >}} that you created. - - ```sh - kubectl describe httproute mcp - ``` - - Example output: - - ``` - Name: mcp - Namespace: default - Labels: - Annotations: - API Version: gateway.networking.k8s.io/v1 - Kind: HTTPRoute - Metadata: - Creation Timestamp: 2025-08-11T16:16:16Z - Generation: 1 - Resource Version: 13598 - UID: 78f649b9-310e-4f21-ac0f-e516f06d8f22 - Spec: - Parent Refs: - Group: gateway.networking.k8s.io - Kind: Gateway - Name: agentgateway-proxy - Namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - Rules: - Backend Refs: - Group: agentgateway.dev - Kind: AgentgatewayBackend - Name: mcp - Weight: 1 - Matches: - Path: - Type: PathPrefix - Value: / - Status: - Parents: - Conditions: - Last Transition Time: 2025-12-19T03:13:18Z - Message: - Observed Generation: 2 - Reason: Accepted - Status: True - Type: Accepted - Last Transition Time: 2025-12-19T14:24:01Z - Message: - Observed Generation: 2 - Reason: ResolvedRefs - Status: True - Type: ResolvedRefs - Controller Name: agentgateway.dev/agentgateway - Parent Ref: - Group: gateway.networking.k8s.io - Kind: Gateway - Name: agentgateway-proxy - Namespace: agentgateway-system - ``` - - -## Step 3: Verify the connection {#verify} - -Use the [MCP Inspector tool](https://modelcontextprotocol.io/legacy/tools/inspector) to verify that you can connect to your federated MCP servers through agentgateway. - -1. Get the agentgateway address. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80 - ``` - {{% /tab %}} - {{< /tabs >}} - -2. From the terminal, run the MCP Inspector command. Then, the MCP Inspector opens in your browser. - - ```sh - npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}} - ``` - -3. From the MCP Inspector menu, connect to your agentgateway address as follows: - * **Transport Type**: Select `Streamable HTTP`. - * **URL**: Enter the agentgateway address and the `/mcp` path, such as `${INGRESS_GW_ADDRESS}/mcp` or `http://localhost:8080/mcp`. - * Click **Connect**. - -4. From the menu bar, click the **Tools** tab, and then **List tools**. Verify that you see the tools from both servers. The name of the tools are prepended with the names of the MCP servers that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}}. - * **`mcp-server-everything-3001_*`**: Tools from the `server-everything` MCP server, like `echo`, `add`, etc. - * **`mcp-website-fetcher_fetch`**: The `fetch` tool from the website fetcher MCP server. - - {{< reuse-image src="img/mcp-multiplex.png" >}} - {{< reuse-image-dark srcDark="img/mcp-multiplex-dark.png" >}} - -5. Test the federated tools: - * **Test the `mcp-server-everything-3001_echo` tool**: Click **List Tools** and select the `echo` tool. In the **message** field, enter any string, such as `Hello world`, and click **Run Tool**. Verify that your string is echoed back. - * **Test the `mcp-website-fetcher_fetch` tool**: Click **List Tools** and select the `fetch` tool. In the **url** field, enter a website URL, such as `https://lipsum.com/`, and click **Run Tool**. - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete Deployment mcp-server-everything mcp-website-fetcher -kubectl delete Service mcp-server-everything mcp-website-fetcher -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} mcp -kubectl delete HTTPRoute mcp -``` diff --git a/assets/docs/pages/agentgateway/mcp/static.md b/assets/docs/pages/agentgateway/mcp/static.md deleted file mode 100644 index 2b501a41b..000000000 --- a/assets/docs/pages/agentgateway/mcp/static.md +++ /dev/null @@ -1,148 +0,0 @@ -Route to a Model Context Protocol (MCP) server through a static address. For more information, see the [About MCP]({{< link-hextra path="/mcp/about" >}}) topic. - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Step 1: Deploy an MCP server {#mcp-server} - -Deploy a Model Context Protocol (MCP) server that you want {{< reuse "agw-docs/snippets/agentgateway.md" >}} to proxy traffic to. The following example sets up a simple MCP server with one tool, `fetch`, that retrieves the content of a website URL that you pass in. - -1. Create the MCP server workload. Notice the following details about the Service: - * `appProtocol: kgateway.dev/mcp` (required): Configure your service to use the MCP protocol. This way, the {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy uses the MCP protocol when connecting to the service. - * `kgateway.dev/mcp-path` annotation (optional): The default values are `/sse` for the SSE protocol or `/mcp` for the Streamable HTTP protocol. If you need to change the path of the MCP target endpoint, set this annotation on the Service. - - ```yaml - kubectl apply -f- <}} that sets up the {{< reuse "agw-docs/snippets/agentgateway.md" >}} target details for the MCP server. - - ```yaml - kubectl apply -f- <}} - metadata: - name: mcp-backend - spec: - mcp: - targets: - - name: mcp-target - static: - host: mcp-website-fetcher.default.svc.cluster.local - port: 80 - protocol: SSE - EOF - ``` - - -## Step 2: Route with agentgateway {#agentgateway} - -Create an HTTPRoute resource that routes to the {{< reuse "agw-docs/snippets/backend.md" >}} that you created in the previous step. - - - - -```yaml -kubectl apply -f- <}} - rules: - - - backendRefs: - - name: mcp-backend - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} -EOF -``` - - -## Step 3: Verify the connection {#verify} - -Use the [MCP Inspector tool](https://modelcontextprotocol.io/docs/tools/inspector) to verify that you can connect to your sample MCP server through agentgateway. - -1. Get the agentgateway address. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80 - ``` - {{% /tab %}} - {{< /tabs >}} - -2. From the terminal, run the MCP Inspector command. Then, the MCP Inspector opens in your browser. If the MCP inspector tool does not open automatically, run `mcp-inspector`. - ```sh - npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}} - ``` - -3. From the MCP Inspector menu, connect to your agentgateway address as follows: - * **Transport Type**: Select `Streamable HTTP`. - * **URL**: Enter the agentgateway address, port, and the `/mcp` path. If your agentgateway proxy is exposed with a LoadBalancer server, use `http:///mcp`. In local test setups where you port-forwarded the agentgateway proxy on your local machine, use `http://localhost:8080/mcp`. - * Click **Connect**. - - {{< reuse-image src="img/mcp-inspector-connected.png" >}} - {{< reuse-image-dark srcDark="img/mcp-inspector-connected-dark.png" >}} - -4. From the menu bar, click the **Tools** tab. Then from the **Tools** pane, click **List Tools** and select the `fetch` tool. -5. From the **fetch** pane, in the **url** field, enter a website URL, such as `https://lipsum.com/`, and click **Run Tool**. -6. Verify that you get back the fetched URL content. - - {{< reuse-image src="img/mcp-inspector-fetch.png" >}} - {{< reuse-image-dark srcDark="img/mcp-inspector-fetch-dark.png" >}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete Deployment mcp-website-fetcher -kubectl delete Service mcp-website-fetcher -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} mcp-backend -kubectl delete HTTPRoute mcp -``` - diff --git a/assets/docs/pages/agentgateway/mcp/tool-access.md b/assets/docs/pages/agentgateway/mcp/tool-access.md deleted file mode 100644 index 2e5c3235b..000000000 --- a/assets/docs/pages/agentgateway/mcp/tool-access.md +++ /dev/null @@ -1,238 +0,0 @@ -Control access or route traffic based on verified claims in a JSON web token (JWT). - -## About tool access - -In this guide, you learn how to apply CEL-based RBAC rules to your MCP server backend to control access to MCP tools. - -The following diagram shows the components that are involved when performing JWT validation and MCP tool authorization with MCP servers: - -```mermaid -sequenceDiagram - autonumber - Client->>+Agentgateway: Send request with JWT - Agentgateway->>Agentgateway: Validate JWT token - Agentgateway->>Agentgateway: Authorize access to MCP server - Agentgateway->>+MCP: Forward request - MCP->>+MCP: Authorize access to tools - MCP-->>Client: Show tools -``` - -1. The MCP client, such as the MCP inspector tool, sends a request to the agentgateway proxy with the JWT token in the `Authorization` header. -2. The agentgateway proxy validates the JWT with the JWKS server that you define in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource. This policy is applied to the agentgateway proxy. -3. If the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} further defines RBAC rules, such as to only grant access for JWT tokens with certain claims, agentgateway validates these claims and either grants or denies access. -4. If successfully validated and authorized, the agentgateway proxy forwards the request to the MCP backend. -5. The MCP backend verifies access to the MCP server tools. By default, all tool access is allowed. To limit tool access, you create another {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with the CEL expression that must be matched to view a specific tool. Consider the following sample CEL expressions: - * `'mcp.tool.name == "add_issue_comment"'`: Users can only view the `add_issue_comment` tool. All other tools are hidden. - * `'jwt.sub == "alice"'`: Only JWT tokens with a `sub=alice` claim can access tools. Because no CEL expression is provided for the type of tool, the JWT token with this claim can see all the tools that are exposed on the MCP server. - * `'jwt.sub == "alice" && mcp.tool.name == "add_issue_comment"'`: JWT tokens with the `sub=alice` claim can access the `add_issue_comment` tool. Access to all other tools is denied. -6. The MCP server returns the tools that were authorized to access. - -## Before you begin - -1. Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). -2. Follow the steps to connect to the [remote GitHub MCP server via HTTPS]({{< link-hextra path="/mcp/https/" >}}). - -## View MCP tools - -1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your JWT validation rules and apply it to the agentgateway proxy that you created before you began. To learn more about how JWT validation works in the agentgateway proxy and the details of this policy, see the [secure access to an MCP server]({{< link-hextra path="/ai/mcp/mcp-access/" >}}) guide. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: jwt - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: agentgateway-proxy - traffic: - jwtAuthentication: - mode: Strict - providers: - - issuer: solo.io - jwks: - inline: '{"keys":[{"use":"sig","kty":"RSA","kid":"5891645032159894383","n":"5Zb1l_vtAp7DhKPNbY5qLzHIxDEIm3lpFYhBTiZyGBcnre8Y8RtNAnHpVPKdWohqhbihbVdb6U7m1E0VhLq7CS7k2Ng1LcQtVN3ekaNyk09NHuhl9LCgqXT4pATt6fYTKtZ__tEw4XKt3QqVcw7hV0YaNVC5xXGYVBh5_2-K5aW9u2LQ7FSax0jPhWdoUB3KbOQfWNOA3RwOqYn4gmc9wVToVLv6bXCVhIYWKnAVcX89C00eM7uBHENvOydD14-ZnLb4pzz2VGbU6U65odpw_i4r_mWXvoUgwogXAXp80TsYwMzLHcFo4GVDNkaH0hjuLJCeISPfYtbUJK6fFaZGBw","e":"AQAB","x5c":["MIIC3jCCAcagAwIBAgIBJTANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwHhcNMjUxMjE4MTkzNDQyWhcNMjUxMjE4MjEzNDQyWjAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDllvWX++0CnsOEo81tjmovMcjEMQibeWkViEFOJnIYFyet7xjxG00CcelU8p1aiGqFuKFtV1vpTubUTRWEursJLuTY2DUtxC1U3d6Ro3KTT00e6GX0sKCpdPikBO3p9hMq1n/+0TDhcq3dCpVzDuFXRho1ULnFcZhUGHn/b4rlpb27YtDsVJrHSM+FZ2hQHcps5B9Y04DdHA6pifiCZz3BVOhUu/ptcJWEhhYqcBVxfz0LTR4zu4EcQ287J0PXj5mctvinPPZUZtTpTrmh2nD+Liv+ZZe+hSDCiBcBenzROxjAzMsdwWjgZUM2RofSGO4skJ4hI99i1tQkrp8VpkYHAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQBeA8lKrnfRjo18RkLBqVKuO441nZLFGKrJwpJu+G5cVOJ06txKsZEXE3qu2Yh9abeOJkC+SsWMELWHYNJlip4JGE0Oby7chol+ahrwBILUixBG/qvhwJG6YntoDZi0wbNFqQiQ6FZt89awcs2pdxL5thYR/Pqx4QXN8oKd4DNkcX5vWdz9P6nstLUmrEBV4EFs7fY0L/n3ssDvyZ3xfpM1Q/CQFz4OqB4U20+Qt6x7eap6qhTSBZt8rZWIiy57BsSww12gLYYU1x+Klg1AdPsVrcuvVdiZM1ru232Ihip0rYH7Mf7vcN+HLUrjpXvMoeyWRwbB61GPsXz+BTksqoql"]}]}' - EOF - ``` - -2. Save the JWT tokens for the users Alice and Bob. You can optionally create other JWT tokens by using the [JWT generator tool](https://github.com/solo-io/solo-cop/blob/main/tools/jwt-generator/README.md). Note that to use JWTs with agentgateway proxies, make sure that the JWTs return Key ID (`kid`) and expiration date (`exp`) values in the JWT header. - - 1. Save the JWT token for Alice. Alice works in the `dev` team. - ```sh - export ALICE_JWT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw" - ``` - - 2. Save the JWT token for Bob. Bob works in the `ops` team. - - ```sh - export BOB_JWT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og" - ``` - -3. Send a request to the MCP server. Provide the JWT token for Alice in your request. - {{< tabs tabTotal="2" items="CLI,UI" >}} - {{% tab tabName="CLI" %}} - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name get_me \ - --header "Authorization: Bearer $ALICE_JWT" - ``` - - Verify that the connection succeeds and that you can successfully access the `get_me` tool. - ```console - { - "content": [ - { - "type": "text", - "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}" - } - ] - } - ``` - {{% /tab %}} - {{% tab tabName="UI" %}} - 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card: - * **Header Name**: Enter `Authorization`. - * **Bearer Token**: Enter the JWT token for Alice. - ```sh - Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw - ``` - * Click **Connect**. - - 2. Verify that the connection now succeeds because a valid token was provided in an `Authorization` header to your agentgateway proxy: - {{< reuse-image src="img/mcp-github-success.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-success-dark.png" >}} - - {{% /tab %}} - {{< /tabs >}} - - -## Limit tool access - -1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your RBAC rules for the MCP tools. In the following example, you only want to allow access to the `get_me` tool if the JWT has a `sub` of `alice`. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: jwt-rbac - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - name: github-mcp-backend - backend: - mcp: - authorization: - action: Allow - policy: - # Any of these conditions will allow access (OR logic) - matchExpressions: - - 'jwt.sub == "alice" && mcp.tool.name == "get_me"' - EOF - ``` - -2. Try to access tools on the MCP server. - {{< tabs tabTotal="2" items="CLI,UI" >}} - {{% tab tabName="CLI" %}} - 1. Try to access the `get_me` tool with Alice's JWT token. Verify that the request succeeds and you can access the tool. - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name get_me \ - --header "Authorization: Bearer $ALICE_JWT" - ``` - - Example output: - ```console - { - "content": [ - { - "type": "text", - "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}" - } - ] - } - ``` - 2. Try to access a different tool, such as `search_repositories`. Verify that the request fails, because this tool is not allowed in your {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name search_repositories \ - --header "Authorization: Bearer $ALICE_JWT" \ - --tool-arg query="user:facebook" - ``` - - Example output: - ```console - Failed to call tool search_repositories: Streamable HTTP error: - Error POSTing to endpoint: {"jsonrpc":"2.0","id":2,"error":{"code":-32603,"message":"failed to send message: unauthorized tool call"}} - ``` - - 3. Try to access the `get_me` took with Bob's JWT token. Verify that the request fails, because the token does not have the `sub=alice` claim. - ```sh - npx @modelcontextprotocol/inspector@0.18.0 \ - --cli http://localhost:8080/mcp-github \ - --transport http \ - --header "mcp-protocol-version: 2024-11-05" \ - --method tools/call \ - --tool-name search_repositories \ - --header "Authorization: Bearer $BOB_JWT" \ - --tool-arg query="user:facebook" - ``` - - Example output: - ```console - Failed to call tool search_repositories: Streamable HTTP error: - Error POSTing to endpoint: {"jsonrpc":"2.0","id":2,"error":{"code":-32603,"message": - "failed to send message: unauthorized tool call"}} - ``` - {{% /tab %}} - {{% tab tabName="UI" %}} - 1. Go to the MCP inspector tool, and re-connect with Alice's token. From the **Tools** tab, click **Clear**. Then click **List Tools**. Verify that you can now only see the `get_me` tool that you authorized in your {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. - - {{< reuse-image src="img/mcp-github-tool.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-tool-dark.png" >}} - - 2. Go back to the MCP inspector tool. In the **Authentication** > **Custom Headers** card enter the JWT token for Bob. Then, click **Re-connect**. - ```sh - Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og - ``` - - 3. From the **Tools** tab, click **Clear**. Then click **List Tools**. - - Verify that you cannot see any tools. Bob's JWT token does not contain the `sub=alice` claim that is required to access the `get_me` tool. Because no other matching condition is found in the RBAC rules that you defined in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, access to all tools is denied. - - - {{< reuse-image src="img/mcp-github-no-tool.png" >}} - {{< reuse-image-dark srcDark="img/mcp-github-no-tool-dark.png" >}} - - - - {{% /tab %}} - {{< /tabs >}} - - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} github-mcp-backend -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete HTTPRoute mcp-github -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} jwt -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} jwt-rbac -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` \ No newline at end of file diff --git a/assets/docs/pages/agentgateway/monitoring-agentgateway-nacks.md b/assets/docs/pages/agentgateway/monitoring-agentgateway-nacks.md deleted file mode 100644 index e5f1c2ba8..000000000 --- a/assets/docs/pages/agentgateway/monitoring-agentgateway-nacks.md +++ /dev/null @@ -1,93 +0,0 @@ -## About NACKs {#nacks} - -A NACK (negative acknowledgement) occurs when an {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy rejects a configuration update from the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane. NACKs typically indicate configuration issues that prevent the proxy from applying the desired routing, policy, or backend settings. - -Typically, the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane reports errors during translation, in which the control plane immediately rejects invalid configuration in custom resources and records errors in custom resource statuses. However, some errors can only be caught at configuration time, in which the control plane cannot determine the configuration failure until a proxy in the data plane rejects the configuration. - -To track these NACKs at configuration time, the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane exposes a combination of metrics and events that monitor the health of config synchronization between the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxies. - -For more general information about {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane metrics, see [Control plane metrics](../../observability/control-plane-metrics/). - -Common causes of NACKs include: - -* CEL expressions in policies that the control plane validator allows, but the data plane rejects. The control plane uses a Go-based CEL validator, while agentgateway uses a Rust-based validator, which can have different validation behavior. -* Invalid TLS certificates. - -When a NACK occurs, {{< reuse "/agw-docs/snippets/kgateway.md" >}} provides two observability signals: - -* **Prometheus metric**: A counter metric tracks the total number of NACKs across all {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxies that {{< reuse "/agw-docs/snippets/kgateway.md" >}} manages. -* **Kubernetes events**: {{< reuse "/agw-docs/snippets/kgateway.md" >}} creates Warning events on both the `Gateway` and its corresponding `Deployment` with details about the error. - -## Monitor NACKs with control plane metrics {#nack-metrics} - -You can access the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane metrics endpoint to view NACK metrics that track configuration rejections from {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxies. - -### View the NACK metric {#view-nack-metric} - -1. Port-forward the control plane deployment on port 9092. - ```sh - kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} port-forward deployment/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} 9092 - ``` - -2. Open the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane [metrics endpoint](http://localhost:9092/metrics). - -3. Search for the `kgateway_agentgateway_xds_rejects_total` metric. - - {{< callout type="info" >}} - The metric will only appear after at least one NACK has been reported. If no NACKs have occurred, the metric will not be present in the metrics output. - {{< /callout >}} - - Example output: - - ```console - # HELP kgateway_agentgateway_xds_rejects_total Total number of xDS responses rejected by agentgateway proxy - # TYPE kgateway_agentgateway_xds_rejects_total counter - kgateway_agentgateway_xds_rejects_total 3 - ``` - -You can use this metric to configure alerts to notify you when NACKs occur so you can quickly investigate and resolve configuration issues. - -For guidance on setting up the observability stack, which allows for configurable alerting, see the [OpenTelemetry stack guide](../../observability/otel-stack/). - -## Monitor NACKs with Kubernetes events {#nack-events} - -When a NACK occurs for an {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy, {{< reuse "/agw-docs/snippets/kgateway.md" >}} also creates Kubernetes Warning events on both the `Gateway` and its corresponding `Deployment`. - -### View NACK events {#view-nack-events} - -Use the following commands to view NACK events for your agentgateway deployment. - -1. List NACK events in the namespace where your Gateway is deployed. If you have multiple Gateways across different namespaces, you can search across all namespaces with `--all-namespaces` instead of `-n `. - - ```sh - kubectl get events -n --field-selector=reason=AgentGatewayNackError - ``` - - Example output: - - ```console - LAST SEEN TYPE REASON OBJECT MESSAGE - 83s Warning AgentGatewayNackError gateway/agentgateway policy/traffic/default/example-agw-policy-for-body:transformation:default/example-route-for-body: error: parse: ERROR: :1:20: invalid argument has(request.headers['x-priority-level']) ? 'level_' + request.headers['x-priority-level'] : 'level_unknown' - 83s Warning AgentGatewayNackError deployment/agentgateway policy/traffic/default/example-agw-policy-for-body:transformation:default/example-route-for-body: error: parse: ERROR: :1:20: invalid argument has(request.headers['x-priority-level']) ? 'level_' + request.headers['x-priority-level'] : 'level_unknown' - ``` - -2. View events for a specific Gateway. - - ```sh - kubectl describe gateway -n - ``` - - Look for events in the output similar to the following. - - ```console - Events: - Type Reason Age From Message - ---- ------ ---- ---- ------- - Warning AgentGatewayNackError 36s kgateway.dev/agentgateway policy/traffic/default/example-agw-policy-for-body:transformation:default/example-route-for-body: error: parse: ERROR: :1:20: invalid argument has(request.headers['x-priority-level']) ? 'level_' + request.headers['x-priority-level'] : 'level_unknown' - ``` - -3. View events for the associated Deployment in the same name and namespace as the Gateway. - - ```sh - kubectl describe deployment -n - ``` \ No newline at end of file diff --git a/assets/docs/pages/agentgateway/quickstart.md b/assets/docs/pages/agentgateway/quickstart.md deleted file mode 100644 index 3683936aa..000000000 --- a/assets/docs/pages/agentgateway/quickstart.md +++ /dev/null @@ -1,33 +0,0 @@ -Use the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane to deploy and manage the lifecycle of agentgateway proxies on Kubernetes.

- -{{< reuse "agw-docs/snippets/agentgateway/about.md" >}} - -## Before you begin - -These quickstart steps assume that you have a Kubernetes cluster, `kubectl`, and `helm` already set up. For quick testing, you can use [Kind](https://kind.sigs.k8s.io/). - -```sh -kind create cluster -``` - -## Install - -The following steps get you started with a basic installation. - -{{< reuse "agw-docs/snippets/agentgateway/get-started.md" >}} - -Good job! You now have the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane running in your cluster. - -## Next steps - -{{< icon "agentgateway" >}} [Create an agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}) that you can use for Model Context Protocol (MCP), agent-to-agent (A2A), large language model (LLM), and more AI-related use cases. For example, you can follow the [guide]({{< link-hextra path="/mcp/static-mcp/" >}}) to use agentgateway to proxy traffic to a sample MCP tool server. The example deploys a sample MCP server with a `fetch` tool, exposes the tool with agentgateway, and tests the tool with the MCP Inspector UI. - -For other examples, see the [LLM consumption]({{< link-hextra path="/llm/" >}}), [inference routing]({{< link-hextra path="/inference/" >}}), [MCP]({{< link-hextra path="/mcp/" >}}), or [agent connectivity]({{< link-hextra path="/agent/" >}}) guides. - -## Cleanup - -No longer need {{< reuse "/agw-docs/snippets/kgateway.md" >}}? Uninstall with the following command: - -```sh -helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` diff --git a/assets/docs/pages/agentgateway/rbac.md b/assets/docs/pages/agentgateway/rbac.md deleted file mode 100644 index 5311173cb..000000000 --- a/assets/docs/pages/agentgateway/rbac.md +++ /dev/null @@ -1,128 +0,0 @@ -Use Common Language Expressions (CEL) expressions to secure access to AI resources. - -## About CEL-based RBAC - -Agentgateway proxies use CEL expressions to match requests or responses on specific parameters, such as a request header or source address. If the request matches the condition, it is allowed. Requests that do not match any of the conditions are denied. - -For an overview of supported CEL expressions, see the [agentgateway docs](https://agentgateway.dev/docs/reference/cel/). - -## Before you begin - -Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}). - -## Set up access to Gemini - -Configure access to an LLM provider such as Gemini. You can use any other LLM provider, an MCP server, or an agent to try out CEL-based RBAC. - -{{< reuse "agw-docs/snippets/gemini-setup.md" >}} - -## Set up RBAC permissions - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your CEL rules. The following example allows requests with the `x-llm: gemini` header. - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: rbac-policy - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: google - traffic: - authorization: - action: Allow - policy: - matchExpressions: - - "request.headers['x-llm'] == 'gemini'" - EOF - ``` - - - -2. Send a request to the LLM provider API without the `llm` header. Verify that the request is denied with a 403 HTTP response code. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - - ````sh - curl -vik "$INGRESS_GW_ADDRESS:8080/gemini" -H content-type:application/json -d '{ - "model": "", - "messages": [ - {"role": "user", "content": "Explain how AI works in simple terms."} - ] - }' - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik "localhost:8080/gemini" -H content-type:application/json -d '{ - "model": "", - "messages": [ - {"role": "user", "content": "Explain how AI works in simple terms."} - ] - }' - ```` - - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console{hl_lines=[11]} - * upload completely sent off: 109 bytes - < HTTP/1.1 403 Forbidden - HTTP/1.1 403 Forbidden - < content-type: text/plain - content-type: text/plain - < content-length: 20 - content-length: 20 - < - - * Connection #0 to host localhost left intact - authorization failed - ``` - -3. Send another request to the LLM provider. This time, you include the `llm` header. Verify that the request succeeds with a 200 HTTP response code. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - - ```sh - curl -vik "$INGRESS_GW_ADDRESS:8080/gemini" \ - -H "content-type: application/json" \ - -H "x-llm: gemini" -d '{ - "model": "", - "messages": [ - {"role": "user", "content": "Explain how AI works in simple terms."} - ] - }' - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik "localhost:8080/gemini" \ - -H "content-type: application/json" \ - -H "x-llm: gemini" -d '{ - "model": "", - "messages": [ - {"role": "user", "content": "Explain how AI works in simple terms."} - ] - }' - ```` - - {{% /tab %}} - {{< /tabs >}} - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```shell -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} rbac-policy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute google -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} google -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete secret google-secret -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` \ No newline at end of file diff --git a/assets/docs/pages/cli/_index.md b/assets/docs/pages/cli/_index.md deleted file mode 100644 index 3e02e0151..000000000 --- a/assets/docs/pages/cli/_index.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: CLI -weight: 10 -description: ---- - -{{< cards >}} -{{< card link="install" title="Install the kgwctl CLI">}} -{{< card link="visualize" title="Visualize resource dependencies">}} -{{< card link="commands" title="kgwctl commands" >}} -{{< /cards >}} diff --git a/assets/docs/pages/cli/commands/_index.md b/assets/docs/pages/cli/commands/_index.md deleted file mode 100644 index af6d556fa..000000000 --- a/assets/docs/pages/cli/commands/_index.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Commands -weight: 30 -description: ---- - - -{{< cards >}} -{{< card link="kgwctl-analyze" title="kgwctl analyze" >}} -{{< card link="kgwctl-check" title="kgwctl check" >}} -{{< card link="kgwctl-completion" title="kgwctl completion" >}} -{{< card link="kgwctl-describe" title="kgwctl describe" >}} -{{< card link="kgwctl-get" title="kgwctl get" >}} -{{< card link="kgwctl-help" title="kgwctl help" >}} -{{< /cards >}} diff --git a/assets/docs/pages/cli/commands/kgwctl-analyze.md b/assets/docs/pages/cli/commands/kgwctl-analyze.md deleted file mode 100644 index 920b9dc35..000000000 --- a/assets/docs/pages/cli/commands/kgwctl-analyze.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: kgwctl analyze -weight: 20 -description: kgwctl analyze command reference ---- - -Analyze kgateway resource manifests by file names or directory to find configuration issues and impacts on other resources. - -## Usage - -```sh -kgwctl analyze -f FILENAME|DIRECTORY [flags] -``` - -## Command-specific flags - -```yaml --f, --filename strings The file name or directory that contains the kgateway manifests that you want to analyze. --h, --help Help for the command. --R, --recursive Process the directory that you reference in -f or --filename recursively. This option is useful for when you want to analyze related manifests that are stored in the same directory. (default true) -``` - -{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}} diff --git a/assets/docs/pages/cli/commands/kgwctl-check.md b/assets/docs/pages/cli/commands/kgwctl-check.md deleted file mode 100644 index 34d5864ca..000000000 --- a/assets/docs/pages/cli/commands/kgwctl-check.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: kgwctl check -weight: 20 -description: kgwctl check command reference ---- - -Check the health of the kgateway control and data plane. - -## Usage - -```sh -kgwctl check [flags] -``` - -## Command-specific flags - -```yaml --h, --help Help for the command. -``` - -{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}} - - - diff --git a/assets/docs/pages/cli/commands/kgwctl-completion.md b/assets/docs/pages/cli/commands/kgwctl-completion.md deleted file mode 100644 index 7115f26e0..000000000 --- a/assets/docs/pages/cli/commands/kgwctl-completion.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: kgwctl completion -weight: 20 -description: kgwctl completion command reference ---- - -Generate the autocompletion script for the `kgwctl` CLI for the specified shell. For details on how to use the generated script, see the subcommand's help, such as `kgwctl completion bash --help`. - -## Usage - -```sh -kgwctl completion [command] -``` - -## Available commands - -```sh -bash Generate the autocompletion script for bash. -fish Generate the autocompletion script for fish. -powershell Generate the autocompletion script for powershell. -zsh Generate the autocompletion script for zsh. -``` - -## Command-specific flags - -```sh --h, --help Help for the command. -``` - -{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}} - diff --git a/assets/docs/pages/cli/commands/kgwctl-describe.md b/assets/docs/pages/cli/commands/kgwctl-describe.md deleted file mode 100644 index 5bbf8e01a..000000000 --- a/assets/docs/pages/cli/commands/kgwctl-describe.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: kgwctl describe -weight: 20 -description: kgwctl describe command reference ---- - -Get the details of one or more kgateway resources. - -## Usage - -```sh -kgwctl describe TYPE [RESOURCE_NAME] [flags] -``` - -## Command-specific flags - -```yaml --A, --all-namespaces If present, list the requested object(s) across all namespaces. Note that any namespace context that you specified with -n or --namespace is ignored. --h, --help Help for the command. --l, --selector string The selector label to filter on. Supported operations include '=', '==', and '!='. For example, to describe all resources with the `key1=value1` and `key2=value2` labels, use `-l key1=value1,key2=value2`. -``` - - -{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}} \ No newline at end of file diff --git a/assets/docs/pages/cli/commands/kgwctl-get.md b/assets/docs/pages/cli/commands/kgwctl-get.md deleted file mode 100644 index 91afb4b70..000000000 --- a/assets/docs/pages/cli/commands/kgwctl-get.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: kgwctl get -weight: 20 -description: kgwctl get command reference ---- - -List one or more kgateway resources. - -## Usage - -```sh -kgwctl get TYPE [RESOURCE_NAME] [flags] -``` - -## Command-specific flags - -```sh --A, --all-namespaces If present, list the requested object(s) across all namespaces. Note that any namespace context that you specified with -n or --namespace is ignored. ---for string Only show the resources that match the filter. To filter the results, use the `TYPE[/NAMESPACE]/NAME` format. If no `NAMESPACE` is set, the `default` namespace is automatically assumed. Examples: `gateway/ns2/foo-gateway`, `httproute/bar-httproute`, and `service/ns1/my-svc`. --h, --help Help for the command. --l, --selector string The selector label to filter on. Supported operations include '=', '==', and '!='. For example, to get all resources with the `key1=value1` and `key2=value2` labels, use `-l key1=value1,key2=value2`. --o, --output string Define the output format. Supported values are wide, json, yaml, and graph. -``` - -{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}} - diff --git a/assets/docs/pages/cli/commands/kgwctl-help.md b/assets/docs/pages/cli/commands/kgwctl-help.md deleted file mode 100644 index 762edd8a0..000000000 --- a/assets/docs/pages/cli/commands/kgwctl-help.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: kgwctl help -weight: 20 -description: kgwctl help command reference ---- - -List all supported commands for the `kgwctl` CLI. - -## Usage - -```sh -kgwctl [command] -``` - -## Available Commands - -``` -analyze Analyze kgateway resource manifests by file names or directory to find configuration issues and impacts on other resources. -check Check the health of the kgateway control and data plane. -completion Generate the autocompletion script for the `kgwctl` CLI for the specified shell. -describe Get the details of one or more kgateway resources. -get List one or more kgateway resources. -help List all supported commands for the `kgwctl` CLI. -``` - -{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}} \ No newline at end of file diff --git a/assets/docs/pages/cli/install.md b/assets/docs/pages/cli/install.md deleted file mode 100644 index 6a8528e70..000000000 --- a/assets/docs/pages/cli/install.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: Install the kgwctl CLI -weight: 10 -description: ---- - - - -Use the `kgwctl` CLI to quickly assess the health of your kgateway control and data plane components. - -1. Save the version of the kgwctl CLI that you want to install as an environment variable. - ```sh - export VERSION=v{{< reuse "agw-docs/versions/kgwctl.md" >}} - ``` - -2. Create a personal access token in GitHub. For more information, see the [GitHub documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens). - -3. Install the `kgwctl` CLI. - ```sh - curl -sL -H "Authorization: token ${GITHUB_TOKEN}" https://raw.githubusercontent.com/solo-io/kgwctl-temp/refs/heads/main/scripts/install.sh | sh - - ``` - - Example output: - ```sh - Downloading kgwctl-darwin-arm64 from release v{{< reuse "agw-docs/versions/kgwctl.md" >}}... - Verifying checksum... - Checksum verified successfully - Download successful: kgwctl-darwin-arm64 - kgwctl CLI was successfully installed 🎉 - - Add the kgwctl CLI to your path with: - export PATH=$HOME/.kgwctl/bin:$PATH - ``` - -4. Add the CLI to your path. - ```sh - export PATH=$HOME/.kgwctl/bin:$PATH - ``` - -5. Try out the CLI. For example, you can list all supported commands with the following command. - ```sh - kgwctl --help - ``` - - Example output: - ```console - Commands for interacting with kgateway installations. - - Usage: - kgwctl [command] - - Available Commands: - analyze Analyze kgateway resource manifests by file names or directory to find configuration issues and impacts on other resources. - check Check the health of the kgateway control and data plane. - completion Generate the autocompletion script for the `kgwctl` CLI for the specified shell. - describe Get the details of one or more kgateway resources. - get List one or more kgateway resources. - help List all supported commands for the `kgwctl` CLI. - ... - ``` - \ No newline at end of file diff --git a/assets/docs/pages/cli/visualize.md b/assets/docs/pages/cli/visualize.md deleted file mode 100644 index 3602f10e6..000000000 --- a/assets/docs/pages/cli/visualize.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Visualize resource dependencies -weight: 15 -description: Visualize the relationship and dependencies for all your kgateway and Kubernetes Gateway API resources in a DOT Graph. ---- - -Visualize the relationship and dependencies for all your kgateway and Kubernetes Gateway API resources in a DOT Graph. - -## About DOT Graphs - -A DOT graph is a plain text graph description language that is primarily used with [Graphviz](https://graphviz.org/). Graphviz is an open source graph visualization software to represent structural information and networks as diagrams, such as flowcharts, dependency trees, and state machines. - -The kgwctl CLI has built-in support for generating DOT graphs to show the dependencies and relationships of kgateway and Kubernetes Gateway API resources. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Visualize your resources - -1. Generate a graph for a particular resource in your cluster. The following command generates a graph for the http Gateway that you created in [before you begin](#before-you-begin) - - ```sh - kgwctl get gateway http -n kgateway-system -o graph > output.graph - ``` - -2. Open the [Graphviz online playground]( https://dreampuf.github.io/GraphvizOnline). - -3. Copy and paste the output of `output.graph` into the Graphviz online playground. The tool automatically generates the DOT graph for you. - - {{< reuse-image src="img/graphviz.svg" >}} \ No newline at end of file diff --git a/assets/docs/pages/envoy/quickstart.md b/assets/docs/pages/envoy/quickstart.md deleted file mode 100644 index 6862c3f66..000000000 --- a/assets/docs/pages/envoy/quickstart.md +++ /dev/null @@ -1,29 +0,0 @@ -Get started with {{< reuse "/agw-docs/snippets/kgateway.md" >}}. {{< reuse "agw-docs/snippets/kgateway-about.md" >}} - -## Before you begin - -These quick start steps assume that you have a Kubernetes cluster, `kubectl`, and `helm` already set up. For quick testing, you can use [Kind](https://kind.sigs.k8s.io/). - -```sh -kind create cluster -``` - -## Install - -The following steps get you started with a basic installation. For detailed instructions, see the [installation guides]({{< link-hextra path="/install" >}}). - -{{< reuse "agw-docs/snippets/envoy/get-started.md" >}} - -Good job! You now have the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane running in your cluster. - -## Next steps - -{{< icon "kgateway" >}} [Set up an API gateway with an httpbin sample app]({{< link-hextra path="/install/sample-app/" >}}). This guide uses the Envoy-based {{< reuse "/agw-docs/snippets/kgateway.md" >}} proxy to set up an API gateway. Then, deploy a sample httpbin app, configure a basic HTTP listener on the API gateway, and route traffic to httpbin by using an HTTPRoute resource. - -## Cleanup - -No longer need {{< reuse "/agw-docs/snippets/kgateway.md" >}}? Uninstall with the following command: - -```sh -helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` diff --git a/assets/docs/pages/faqs.md b/assets/docs/pages/faqs.md deleted file mode 100644 index e6ed0bbed..000000000 --- a/assets/docs/pages/faqs.md +++ /dev/null @@ -1,68 +0,0 @@ -## What is kgateway? - -{{< reuse "agw-docs/snippets/kgateway-about.md" >}} - -## Why would I want to use kgateway? - -The kgateway project was built to support the difficult challenges of monolith to microservice migration, which includes being able to connect multiple types of compute resources, such as virtual machines (VMs) and on-premises monolithic apps with cloud-native, Kubernetes-based apps. - -Other use cases kgateway can solve include the following: - -* Kubernetes cluster ingress with a custom kgateway API as well as native support for the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}. -* API gateway functionality for services that run outside Kubernetes -* Routing, resiliency, and security capabilities for enhanced traffic management - -## What's the difference between kgateway and Envoy? - -The Envoy proxy is a data-plane component with powerful routing, observability, and resilience capabilities. However, Envoy can be difficult to operationalize and complex to configure. - -The kgateway project comes with a simple yet powerful control plane for managing Envoy as an edge ingress, API Gateway, or service proxy. The kgateway control plane is built on a plugin model that enables extension and customization depending on your environment. This flexibility lets kgateway adapt both to the fast pace of development in the open source Envoy community, as well as to the unique needs of differing operational environments. - -The kgateway includes the following capabilities beyond open source Envoy: - -* A flexible control plane with extensibility in mind -* More ergonomic, domain-specific APIs to drive Envoy configuration -* Function-level routing that goes beyond routing to a `host:port` for clusters, including routing to a Swagger/OpenAPI spec endpoint, gRPC function, cloud provider function such as AWS Lambda, and more -* Transformation of request/response via a super-fast C++ templating filter built on Inja -* Envoy filters to call AWS Lambda directly, handling the complex security handshaking - -## What is the difference between kgateway and Istio? - -[Istio](https://istio.io/latest/docs/overview/what-is-istio/) is a service mesh that helps you manage, secure, and observe traffic for service-to-service communication. Although it includes some ingress gateway capabilities to get traffic into the cluster, Istio focuses more on east-west mesh use cases, especially in large, distributed environments. Istio operates the mesh by using either a per-pod sidecar or per-node ztunnel architecture. - -The kgateway project is not a service mesh. Instead kgateway provides a lightweight control plane to manage Envoy-based API gateways, particularly for north-south edge ingress use cases in any Kubernetes-based environment. - -Kgateway can be deployed complementary to a service mesh like Istio. Istio solves the challenges of service-to-service communication by controlling requests as they flow through the system. Kgateway can be deployed at the edge of the service-mesh boundary, between service meshes, or within the mesh to add the following capabilities: - -* Mutual TLS (mTLS) encryption of traffic between the gateway and services -* Transformation of request/response to decouple backend APIs from frontend -* Function routing such as AWS Lambda -* AI Gateway, MCP server, and other unique kgateway features - -For examples, see the [Istio integration guides]({{< link-hextra path="/integrations/istio/" >}}). - -## What license is kgateway under? - -The kgateway project uses [Apache License 2.0](http://www.apache.org/licenses/). - -## What is the project roadmap? - -The kgateway project organizes issues into milestones for release. For more details, see the [GitHub project](https://github.com/kgateway-dev/kgateway/milestones). - -## What is the version support policy? - -The kgateway project supports one latest version. - -The `main` branch of the `kgateway-dev/kgateway` Git repository is for feature work under development, and is not stable. - -## Where is the changelog? - -The changelog is part of each [GitHub release](https://github.com/kgateway-dev/kgateway/releases). - - - diff --git a/assets/docs/pages/install/advanced.md b/assets/docs/pages/install/advanced.md deleted file mode 100644 index d7aeee654..000000000 --- a/assets/docs/pages/install/advanced.md +++ /dev/null @@ -1,96 +0,0 @@ -You can update several installation settings in your Helm values file. For example, you can update the namespace, set resource limits and requests, or enable extensions such as for AI. - -* **Show all values**: - - ```sh - helm show values oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} - ``` - -* **Get a file with all values**: You can get a `{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml` file for the upgrade version by pulling and inspecting the Helm chart locally. - - ```sh - helm pull oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} - tar -xvf {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-{{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}.tgz - open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml - ``` - -For more information, see the [Helm reference docs]({{< link-hextra path="/reference/helm/" >}}). - -## Development builds - -When using the development build {{< reuse "agw-docs/versions/patch-dev.md" >}}, add `--set controller.image.pullPolicy=Always` to ensure you get the latest image. For production environments, this setting is not recommended as it might impact performance. - - - -### Experimental Gateway API features {#experimental-gateway-api-features} - -To use experimental Gateway API features, you must enable the experimental feature gate, `KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES`. This setting defaults to `false` and must be explicitly enabled to use experimental features such as the following: - -- ListenerSets -- CORS policies -- Retries -- Session persistence - -To enable these features, set the environment variable in your kgateway controller deployment in your Helm values file. - -```yaml -controller: - extraEnv: - KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES: "true" -``` - - - - -## Leader election - -Leader election is enabled by default to ensure that you can run {{< reuse "agw-docs/snippets/kgateway.md" >}} in a multi-control plane replica setup for high availability. - -You can disable leader election by setting the `controller.disableLeaderElection` to `true` in your Helm chart. - -```yaml - -controller: - disableLeaderElection: true -``` - - - -## Namespace discovery {#namespace-discovery} - -You can limit the namespaces that {{< reuse "/agw-docs/snippets/kgateway.md" >}} watches for gateway configuration. For example, you might have a multi-tenant cluster with different namespaces for different tenants. You can limit {{< reuse "/agw-docs/snippets/kgateway.md" >}} to only watch a specific namespace for gateway configuration. - -Namespace selectors are a list of matched expressions or labels. - -* `matchExpressions`: Use this field for more complex selectors where you want to specify an operator such as `In` or `NotIn`. -* `matchLabels`: Use this field for simple selectors where you want to specify a label key-value pair. - -Each entry in the list is disjunctive (OR semantics). This means that a namespace is selected if it matches any selector. - -You can also use matched expressions and labels together in the same entry, which is conjunctive (AND semantics). - -The following example selects namespaces for discovery that meet either of the following conditions: - -* The namespace has the label `environment=prod` and the label `version=v2`, or -* The namespace has the label `version=v3` - -```yaml -discoveryNamespaceSelectors: -- matchExpressions: - - key: environment - operator: In - values: - - prod - matchLabels: - version: v2 -- matchLabels: - version: v3 -``` - - - -## TLS encryption {#tls-encryption} - -You can enable TLS encryption for the xDS gRPC server in the {{< reuse "agw-docs/snippets/kgateway.md" >}} control plane. For more information, see the [TLS encryption]({{< link-hextra path="/install/tls" >}}) docs. - - diff --git a/assets/docs/pages/install/argocd.md b/assets/docs/pages/install/argocd.md deleted file mode 100644 index cb1ed0fcb..000000000 --- a/assets/docs/pages/install/argocd.md +++ /dev/null @@ -1,54 +0,0 @@ -In this installation guide, you install {{< reuse "/agw-docs/snippets/kgateway.md" >}} in a Kubernetes cluster by using [Argo CD](https://argoproj.github.io/cd/). Argo CD is a declarative continuous delivery tool that is especially popular for large, production-level installations at scale. This approach incorporates Helm configuration files. - -## Before you begin - -1. Create or use an existing Kubernetes cluster. -2. Install the following command-line tools. - * [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl), the Kubernetes command line tool. Download the `kubectl` version that is within one minor version of the Kubernetes clusters you plan to use. - * [`argo`](https://argo-cd.readthedocs.io/en/stable/cli_installation/), the Argo CD command line tool. -3. If you do not already have Argo CD installed in your cluster, install it. - ```shell - kubectl create namespace argocd - until kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.12.3/manifests/install.yaml > /dev/null 2>&1; do sleep 2; done - # wait for deployment to complete - kubectl -n argocd rollout status deploy/argocd-applicationset-controller - kubectl -n argocd rollout status deploy/argocd-dex-server - kubectl -n argocd rollout status deploy/argocd-notifications-controller - kubectl -n argocd rollout status deploy/argocd-redis - kubectl -n argocd rollout status deploy/argocd-repo-server - kubectl -n argocd rollout status deploy/argocd-server - ``` -4. Update the default Argo CD password for the admin user to `gateway`. - ```shell - # bcrypt(password)=$2y$10$f6GlB5V/8OzCduEDEgBU.ugVn4vzxgT7cq7vuCebZAKoADaNve9Ve - # password: gateway - kubectl -n argocd patch secret argocd-secret \ - -p '{"stringData": { - "admin.password": "$2y$10$f6GlB5V/8OzCduEDEgBU.ugVn4vzxgT7cq7vuCebZAKoADaNve9Ve", - "admin.passwordMtime": "'$(date +%FT%T%Z)'" - }}' - ``` - -## Install - -Install {{< reuse "/agw-docs/snippets/kgateway.md" >}} by using Argo CD. - -{{< reuse "agw-docs/snippets/argocd.md" >}} - - -## Next steps - -Now that you have {{< reuse "/agw-docs/snippets/kgateway.md" >}} set up and running, check out the following guides to expand your gateway capabilities. - - - - -- [Set up your agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}). -- Review the [LLM consumption]({{< link-hextra path="/llm/" >}}), [inference routing]({{< link-hextra path="/inference/" >}}), [MCP]({{< link-hextra path="/mcp/" >}}), or [agent connectivity]({{< link-hextra path="/agent/" >}}) guides to learn more about common agentgateway use cases. - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -Follow the [Uninstall with Argo CD guide](../../operations/uninstall#argocd). diff --git a/assets/docs/pages/install/helm.md b/assets/docs/pages/install/helm.md deleted file mode 100644 index 3c79c557c..000000000 --- a/assets/docs/pages/install/helm.md +++ /dev/null @@ -1,157 +0,0 @@ -In this installation guide, you install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} {{< gloss "Control Plane" >}}control plane{{< /gloss >}} in a Kubernetes cluster by using [Helm](https://helm.sh/). Helm is a popular package manager for Kubernetes configuration files. This approach is flexible for adopting to your own command line, continuous delivery, or other workflows. - - - -As part of the control plane installation, you enable the {{< reuse "/agw-docs/snippets/agentgateway.md" >}} data plane. - -## Before you begin - -1. Create or use an existing Kubernetes cluster. -2. Install the following command-line tools. - * [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl), the Kubernetes command line tool. Download the `kubectl` version that is within one minor version of the Kubernetes clusters you plan to use. - * [`helm`](https://helm.sh/docs/intro/install/), the Kubernetes package manager. - -## Install - -Install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane by using Helm. - -1. Install the custom resources of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} version {{< reuse "agw-docs/versions/k8s-gw-version.md" >}}. - {{< tabs items="Standard, Experimental" tabTotal="2" >}} - {{% tab tabName="Standard" %}} - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml - ``` - {{% /tab %}} - {{% tab tabName="Experimental" %}} - CRDs in the experimental channel are required to use some experimental features in the Gateway API. Guides that require experimental CRDs note this requirement in their prerequisites. - ```sh - kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml - ``` - {{% /tab %}} - {{< /tabs >}} - Example output: - ```console - customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created - ``` - -2. Apply the {{< reuse "/agw-docs/snippets/kgateway.md" >}} CRDs for the upgrade version by using Helm. - - 1. **Optional**: To check the CRDs locally, download the CRDs to a `helm` directory. - - ```sh - helm template --version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} --output-dir ./helm - ``` - - 2. Deploy the {{< reuse "/agw-docs/snippets/kgateway.md" >}} CRDs by using Helm. This command creates the {{< reuse "agw-docs/snippets/namespace.md" >}} namespace and creates the {{< reuse "/agw-docs/snippets/kgateway.md" >}} CRDs in the cluster. - ```sh - helm upgrade -i --create-namespace \ - --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} \ - --version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} - ``` - -3. Install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart. - - 1. **Optional**: Pull and inspect the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart values before installation. You might want to update the Helm chart values files to customize the installation. For example, you might change the namespace, update the resource limits and requests, or enable extensions such as for AI. For more information, see [Advanced settings](../advanced). - - ```sh - helm pull oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} - - tar -xvf {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-{{< reuse "agw-docs/versions/helm-version-flag.md" >}}.tgz - - open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml - ``` - - 2. Install {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane by using Helm. If you modified the `values.yaml` file with custom installation values, add the `-f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml` flag. - - {{< tabs tabTotal="3" items="Basic installation,Custom values file,Development" >}} -{{% tab tabName="Basic installation" %}} - - - - -```sh -helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \ ---version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} -``` - - -{{% /tab %}} -{{% tab tabName="Custom values" %}} - - - - -```sh -helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \ ---version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} \ --f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml -``` - - -{{% /tab %}} -{{% tab tabName="Development" %}} -When using the development build {{< reuse "agw-docs/versions/helm-version-flag-n1.md" >}}, add the `--set controller.image.pullPolicy=Always` option to ensure you get the latest image. Alternatively, you can specify the exact image digest. - - - - -```sh -helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \ ---version {{< reuse "agw-docs/versions/helm-version-flag-n1.md" >}} \ ---set controller.image.pullPolicy=Always \ ---set controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true -``` - - -{{% /tab %}} - {{< /tabs >}} - - Example output: - ```txt - NAME: {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} - LAST DEPLOYED: Thu Feb 13 14:03:51 2025 - NAMESPACE: {{< reuse "agw-docs/snippets/namespace.md" >}} - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -1. Verify that the control plane is up and running. - - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - - ```txt - NAME READY STATUS RESTARTS AGE - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-78658959cd-cz6jt 1/1 Running 0 12s - ``` - -2. Verify that the `{{< reuse "/agw-docs/snippets/gatewayclass.md" >}}` GatewayClass is created. You can optionally take a look at how the GatewayClass is configured by adding the `-o yaml` option to your command. - - ```sh - kubectl get gatewayclass {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - ``` - -## Next steps - - - - -Now that you have the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane set up and running, check out the following guides to start using the {{< reuse "/agw-docs/snippets/agentgateway.md" >}} data plane. -- Learn more about [{{< reuse "/agw-docs/snippets/agentgateway.md" >}}, its features and benefits](../../about/overview). -- [Set up an agentgateway proxy](../../setup/) to start routing to AI workloads. - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -Follow the [Uninstall guide](../../operations/uninstall). - diff --git a/assets/docs/pages/install/sample-app.md b/assets/docs/pages/install/sample-app.md deleted file mode 100644 index 81da920e9..000000000 --- a/assets/docs/pages/install/sample-app.md +++ /dev/null @@ -1,307 +0,0 @@ -The httpbin app lets you test your API gateway by sending requests to it and receiving responses. - -Review the following diagram to understand the setup. - -```mermaid -flowchart LR - A[client] -->|example.com| B[gateway proxy] - B --> C[httpbin backend] -``` - -* The client calls the `www.example.com` hostname that you set up in the Gateway configuration. -* The gateway proxy receives the request. Based on the routing rules that you set up in the Gateway configuration, the gateway proxy forwards the traffic to the backend destination, which is the httpbin service. The gateway proxy is available from an external LoadBalancer service that is backed by an IP address that your cloud provider typically assigns. For testing in a local cluster where you do not have an external service, you can enable port-forwarding so that the gateway proxy listens on the localhost instead. -* The httpbin service receives and responds to the request. Note that the httpbin service does not have to be publicly exposed because the gateway proxy handles the external traffic. Instead, it can have an internal service type, such as ClusterIP. - -## Before you begin - -Set up {{< reuse "/agw-docs/snippets/kgateway.md" >}} by following the [Quick start](../../quickstart/) or [Installation]({{< link-hextra path="/install" >}}) guides. - -## Deploy a sample app {#deploy-app} - -The following configuration file creates the httpbin app. To review the source file, see [the kgateway project](https://github.com/kgateway-dev/kgateway/blob/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml). - -1. Create the httpbin app. - - ```shell - kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml - ``` - - Example output: - - ```txt - namespace/httpbin created - serviceaccount/httpbin created - service/httpbin created - deployment.apps/httpbin created - ``` - -2. Verify that the httpbin app is running. - - ```sh - kubectl -n httpbin get pods - ``` - - Example output: - - ```txt - NAME READY STATUS RESTARTS AGE - httpbin-d57c95548-nz98t 2/2 Running 0 18s - ``` - -## Set up an API gateway {#api-gateway} - -Create an API gateway with an HTTP listener by using the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}. - -1. Create a Gateway resource and configure an HTTP listener. The following Gateway can serve HTTPRoute resources from all namespaces. For more information about which GatewayClass to use, see [About gateway proxies](../../about/proxies/). - - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/agw-gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -2. Verify that the Gateway is created successfully. You can also review the external address that is assigned to the Gateway. Note that depending on your environment it might take a few minutes for the load balancer service to be assigned an external address. If you are using a local Kind cluster without a load balancer such as `metallb`, you might not have an external address. - - ```sh - kubectl get gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - - ```txt - NAME CLASS ADDRESS PROGRAMMED AGE - http {{< reuse "/agw-docs/snippets/agw-gatewayclass.md" >}} 1234567890.us-east-2.elb.amazonaws.com True 93s - ``` - -3. Verify that the gateway proxy pod is running. - - ```sh - kubectl get po -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l gateway.networking.k8s.io/gateway-name=http - ``` - - Example output: - - ```txt - NAME READY STATUS RESTARTS AGE - http-7dd94b74-k26j6 3/3 Running 0 18s - ``` - - {{< callout type="info" >}} - Using Kind and getting a `CrashLoopBackOff` error with a `Failed to create temporary file` message in the logs? You might have a multi-arch platform issue on macOS. In your Docker Desktop settings, uncheck **Use Rosetta**, restart Docker, re-create your Kind cluster, and try again. - {{< /callout >}} - -## Expose the app on the gateway {#expose-app} - -Now that you have an app and a gateway proxy, you can create a route to access the app. - -1. Create an HTTPRoute resource to expose the httpbin app on the Gateway. The following example exposes the app on the `wwww.example.com` domain. - - ```yaml - kubectl apply -f- <}} - hostnames: - - "www.example.com" - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - - |Setting|Description| - |--|--| - |`spec.parentRefs`|The name and namespace of the Gateway resource that serves the route. In this example, you use the `http` Gateway that you created earlier. | - |`spec.hostnames`|A list of hostnames that the route is exposed on. In the example, the route is exposed on `www.example.com`. | - |`spec.rules.backendRefs`| The Kubernetes service that serves the incoming request. In this example, requests to `www.example.com` are forwarded to the httpbin app on port 8000. Note that you must create the HTTPRoute in the same namespace as the service that serves that route. To create the HTTPRoute resource in a different namespace, you must create a ReferenceGrant resource to allow the HTTPRoute to forward requests to a service in a different namespace. For more information, see the [Kubernetes API Gateway documentation](https://gateway-api.sigs.k8s.io/api-types/referencegrant/). | - -2. Verify that the HTTPRoute is applied successfully. - - ```sh - kubectl get -n httpbin httproute/httpbin -o yaml - ``` - - Example output: Note the status of the HTTPRoute resource. Check for `Accepted` and `ResolvedRefs` messages. The `parentRef` refers to the Gateway that that HTTPRoute is exposed on. - - ```yaml - status: - parents: - - conditions: - - lastTransitionTime: "2025-02-13T18:41:06Z" - message: "" - observedGeneration: 1 - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: "2025-02-13T18:41:06Z" - message: "" - observedGeneration: 1 - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - controllerName: kgateway.dev/kgateway - parentRef: - group: gateway.networking.k8s.io - kind: Gateway - name: http - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -## Send a request {#send-request} - -Now that your httpbin app is running and exposed on the gateway proxy, you can send a request to the app. The steps vary depending on your load balancer setup. - -{{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} -{{% tab tabName="Cloud Provider LoadBalancer" %}} -1. Get the external address of the gateway proxy and save it in an environment variable. - - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} http -o=jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - -2. Send a request to the httpbin app and verify that you get back a 200 HTTP response code. Note that it might take a few seconds for the load balancer service to become fully ready and accept traffic. - - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" - ``` - - Example output: - - ```txt - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Thu, 13 Feb 2025 18:49:32 GMT - content-length: 330 - x-envoy-upstream-service-time: 4 - server: envoy - ``` - ```json - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "26be0bcd-d941-48f4-ac3b-d5ac288ac46f" - ] - } - } - ``` -{{% /tab %}} -{{% tab tabName="Port-forward for local testing"%}} -1. Port-forward the gateway proxy `http` pod on port 8080. - - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - -2. Send a request to the httpbin app and verify that you get back a 200 HTTP response code. - - ```sh - curl -i localhost:8080/headers -H "host: www.example.com" - ``` - - Example output: - - ```txt - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Thu, 13 Feb 2025 18:49:32 GMT - content-length: 330 - x-envoy-upstream-service-time: 4 - server: envoy - ``` - ```json - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "26be0bcd-d941-48f4-ac3b-d5ac288ac46f" - ] - } - } - ``` -{{% /tab %}} -{{< /tabs >}} - -## Next steps - -Now that you have {{< reuse "/agw-docs/snippets/kgateway.md" >}} set up and running, check out the following guides to expand your API gateway capabilities. - -- Add routing capabilities to your httpbin route by using the [Traffic management](../../traffic-management) guides. -- Explore ways to make your routes more resilient by using the [Resiliency](../../resiliency) guides. -- Secure your routes with external authentication and rate limiting policies by using the [Security](../../security) guides. - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - - -1. Delete the httpbin app. - - ```sh - kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml - ``` - -2. Delete the HTTPRoute. - - ```sh - kubectl delete httproute httpbin -n httpbin - ``` - -3. Delete the Gateway. - - ```sh - kubectl delete gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` diff --git a/assets/docs/pages/install/tls.md b/assets/docs/pages/install/tls.md deleted file mode 100644 index d7ad61fe8..000000000 --- a/assets/docs/pages/install/tls.md +++ /dev/null @@ -1,182 +0,0 @@ -Enable server-side TLS encryption for the xDS gRPC server in the {{< reuse "agw-docs/snippets/kgateway.md" >}} control plane. For more information about the server, see the [Architecture]({{< link-hextra path="/about/architecture" >}}) docs. - -TLS encryption is disabled by default. When enabled, the control plane mounts a `{{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-cert` TLS secret that you create and propogates the CA bundle to any {{< reuse "agw-docs/snippets/pod-name.md" >}} data plane proxies to establish a secure connection. You might integrate your secret with a provider such as [cert-manager](https://cert-manager.io/docs/) to automate certificate management and rotation. - -## Before you begin - -{{< conditional-text include-if="envoy" >}}{{< reuse "agw-docs/snippets/prereq.md" >}}{{< /conditional-text >}} -{{< conditional-text include-if="agentgateway" >}}{{< reuse "agw-docs/snippets/agentgateway-prereq.md" >}}{{< /conditional-text >}} - -## Step 1: Set up cert-manager {#cert-manager} - -cert-manager is a Kubernetes controller that helps you automate the process of obtaining and renewing certificates from various PKI providers, such as AWS Private CA, Google Cloud CA, or Vault. In this example, you set up cert-manager to provide self-signed certificates for the {{< reuse "agw-docs/snippets/kgateway.md" >}} control plane. - -1. Add the Jetstack Helm repository. - ```sh - helm repo add jetstack https://charts.jetstack.io --force-update - ``` - -2. Install cert-manager in your cluster. **Note**: cert-manager versions 1.18 and later have stricter validation rules. Certificate durations must be at least 1 hour, and renewal windows must be at least 5 minutes. - ```sh - helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace \ - --set "extraArgs={--feature-gates=ExperimentalGatewayAPISupport=true}" --set installCRDs=true - ``` - {{< callout type="info" >}}To allow cert-manager to use the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}, you must set `--feature-gates=ExperimentalGatewayAPISupport=true` in the cert-manager Helm installation.{{< /callout >}} - -3. Create a self-signed Certificate Authority (CA) that acts as the root of trust for the xDS gRPC server certificates. For production environments, replace the self-signed root issuer with your organization's CA issuer, such as Vault or a cloud CA service. For more information, see the [cert-manager CA issuer docs](https://cert-manager.io/docs/configuration/issuers/). - - ```yaml - kubectl apply -f - <}}-xds-root-issuer - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - selfSigned: {} - --- - apiVersion: cert-manager.io/v1 - kind: Certificate - metadata: - name: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - secretName: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca-secret - issuerRef: - name: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-root-issuer - kind: Issuer - isCA: true - commonName: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca - duration: 1h - renewBefore: 5m - privateKey: - algorithm: RSA - size: 2048 - EOF - ``` - -4. Use the CA to sign a TLS certificate for the xDS gRPC server. This two-tiered approach keeps the root CA separate from the server certificate, and lets the server certificate be rotated independently of the CA. cert-manager automatically creates a Kubernetes secret with the required name `{{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-cert`, type `kubernetes.io/tls`, and the server certificate and private key in the `tls.crt` and `tls.key` keys. - - {{< callout type="info" >}}The DNS names in the server certificate must match the service endpoints of the control plane. If you install the control plane in a different namespace, you must update the DNS names to match the actual service endpoints.{{< /callout >}} - - ```yaml - kubectl apply -f - <}}-xds-ca-issuer - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ca: - secretName: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca-secret - --- - apiVersion: cert-manager.io/v1 - kind: Certificate - metadata: - name: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-cert - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - secretName: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-cert - issuerRef: - name: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca-issuer - kind: Issuer - isCA: false - dnsNames: - - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} - - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.{{< reuse "agw-docs/snippets/namespace.md" >}} - - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.{{< reuse "agw-docs/snippets/namespace.md" >}}.svc - - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.{{< reuse "agw-docs/snippets/namespace.md" >}}.svc.cluster.local - duration: 1h - renewBefore: 5m - privateKey: - algorithm: RSA - size: 2048 - EOF - ``` - -## Step 2: Update the control plane to use TLS {#control-plane} - -Upgrade {{< reuse "agw-docs/snippets/kgateway.md" >}} with TLS enabled for the controller. For complete steps, review the [Upgrade guide]({{< link-hextra path="/operations/upgrade" >}}). - -1. Set your version of {{< reuse "/agw-docs/snippets/kgateway.md" >}} in an environment variable, such as the latest patch version (`{{< reuse "agw-docs/versions/n-patch.md" >}}`). - - ```sh - export NEW_VERSION={{< reuse "agw-docs/versions/n-patch.md" >}} - ``` - -2. Get the Helm values file for your current version. - - ```sh - helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > values.yaml - open values.yaml - ``` - -3. Add the following values to the Helm values file to enable TLS for the xDS gRPC server. - ```yaml - controller: - xds: - tls: - enabled: true - ``` - -4. Upgrade your Helm installation. - - ```sh - helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \ - -f values.yaml \ - --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} - ``` - -5. Confirm that the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane is up and running. - - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -## Step 3: Verify the TLS connection {#verify-tls-connection} - -Now that the control plane is up and running, verify the TLS connection. - -1. Port-forward the control plane service on port 9977. - - ```sh - kubectl port-forward -n {{< reuse "agw-docs/snippets/namespace.md" >}} svc/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} 9978 - ``` - -2. Send a request to the control plane in plaintext without TLS authentication. You get back an `authentication failed` error. - - ```sh - grpcurl -plaintext localhost:9978 list - ``` - - Example output: - - ``` - Failed to list services: rpc error: code = Unknown desc = authentication failed: [Authenticator KubeJWTAuthenticator: target JWT extraction error: no HTTP authorization header exists] - ``` - -3. Port-forward the control plane deployment on port 9092. - - ```sh - kubectl port-forward -n {{< reuse "agw-docs/snippets/namespace.md" >}} deploy/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} 9092 - ``` - -4. Send a request to the metrics endpoint to check for `xds_auth` metrics. - - ```sh - curl localhost:9092/metrics | grep xds_auth - ``` - - Example output: - - ``` - # HELP kgateway_xds_auth_rq_failure_total Total number of failed xDS auth requests - # TYPE kgateway_xds_auth_rq_failure_total counter - kgateway_xds_auth_rq_failure_total 2 - # HELP kgateway_xds_auth_rq_success_total Total number of successful xDS auth requests - # TYPE kgateway_xds_auth_rq_success_total counter - kgateway_xds_auth_rq_success_total 1 - # HELP kgateway_xds_auth_rq_total Total number of xDS auth requests - # TYPE kgateway_xds_auth_rq_total counter - kgateway_xds_auth_rq_total 3 - ``` diff --git a/assets/docs/pages/integrations/argo.md b/assets/docs/pages/integrations/argo.md deleted file mode 100644 index 5026e6495..000000000 --- a/assets/docs/pages/integrations/argo.md +++ /dev/null @@ -1,334 +0,0 @@ -[Argo Rollouts](https://argoproj.github.io/rollouts/) is a Kubernetes controller that provides advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and progressive delivery features to Kubernetes. Because Argo Rollouts supports the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}, you can use Argo Rollouts to control how traffic is split and forwarded from the proxies that kgateway v2 manages to the apps in your cluster. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Install Argo Rollouts - -1. Create the `argo-rollouts` namespace and deploy the Argo Rollouts components into it. - ```sh - kubectl create namespace argo-rollouts - kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml - ``` - -2. Change the config map for the Argo Rollouts pod to install the Argo Rollouts Gateway API plug-in as shown in the following example. Alternatively, you could install the Argo Rollouts Helm chart instead to use init containers to achieve the same thing. For more information about either method, refer to the [Argo Rollouts docs](https://rollouts-plugin-trafficrouter-gatewayapi.readthedocs.io/en/v0.8.0/installation/). - ```yaml - cat <}} - The following cluster role allows the Argo Rollouts pod to access and work with any resources in the cluster. Use this configuration with caution and only in test environments. - {{< /callout >}} - ```yaml - kubectl apply -f- <}}). The HTTP resource can serve both the stable and canary versions of your app. - ```yaml - kubectl apply -f- <}} - {{% tab %}} - 1. Get the external address of the gateway and save it in an environment variable. - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - - 2. Send a request to the `rollouts-demo` app and verify that you see the `ver: 1.0` response from the stable service. - ```sh - curl http://$INGRESS_GW_ADDRESS:8080/callme -H "host: demo.example.com:8080" - ``` - - Example output: - ```console -
ver: 1.0 -
% - ``` - {{% /tab %}} - {{% tab %}} - 3. Port-forward the `http` pod on port 8080. - ```sh - kubectl port-forward deployment/http -n kgateway-system 8080:8080 - ``` - - 4. Send a request to the `rollouts-demo` app and verify that you see the `ver: 1.0` response from the stable service. - ```sh - curl -vi localhost:8080/callme -H "host: demo.example.com" - ``` - - Example output: - ```console -
ver: 1.0 -
% - ``` - - {{% /tab %}} - {{< /tabs >}} - -4. Change the manifest to use the `v2` tag to start a rollout of your app. Argo Rollouts automatically starts splitting traffic between version 1 and version 2 of the app for the duration of the rollout. - ```sh - kubectl patch rollout rollouts-demo -n default \ - --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"kostiscodefresh/summer-of-k8s-app:v2"}]' - ``` - -5. Send another request to your app. Because traffic is split between version 1 and version 2 of the app, you see responses from both app versions until the rollout is completed. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab %}} - ```bash - while true; do curl -H "host: demo.example.com" $INGRESS_GW_ADDRESS:8080/callme; done - ``` - - Example output: - ```console -
ver: 2.0 -
ver: 2.0 -
ver: 1.0 -
ver: 1.0 -
ver: 2.0 -
ver: 1.0 -
ver: 2.0 -
ver: 2.0 -
ver: 1.0 -
ver: 2.0 -
ver: 2.0 -
ver: 1.0 -
ver: 2.0 -
ver: 2.0 -
ver: 2.0 - ``` - {{% /tab %}} - {{% tab %}} - ```sh - while true; do curl localhost:8080/callme -H "host: demo.example.com"; done - ``` - Example output: - ```console -
ver: 2.0 -
ver: 2.0 -
ver: 1.0 -
ver: 1.0 -
ver: 2.0 -
ver: 1.0 -
ver: 2.0 -
ver: 2.0 -
ver: 1.0 -
ver: 2.0 -
ver: 2.0 -
ver: 1.0 -
ver: 2.0 -
ver: 2.0 -
ver: 2.0 - ``` - {{% /tab %}} - {{< /tabs >}} - -Congratulations, you successfully rolled out a new version of your app without downtime by using the HTTP gateway that is managed by kgateway v2. After a rollout, you typically perform tasks such as the following: - -- **Testing**: Conduct thorough testing of your app to ensure that it functions correctly after the rollout. -- **Monitoring**: Monitor your application to detect any issues that may arise after the rollout. -- **Documentation**: Update documentation or runbooks to reflect any changes in your application. -- **User Validation**: Have users validate that the app functions correctly and meets their requirements. -- **Performance Testing**: Depending on your app, consider conducting performance testing to ensure that your app can handle the expected load without issues. -- **Resource Cleanup**: If the rollout included changes to infrastructure or other resources, ensure that any temporary or unused resources are cleaned up to avoid incurring unnecessary costs. -- **Communication**: Communicate with your team and stakeholders to update them on the status of the rollout and any issues that were encountered and resolved. -- **Security Audit**: If your application has undergone significant changes, consider conducting a security audit to ensure that no security vulnerabilities have been introduced. - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Remove the HTTPRoute. - ```sh - kubectl delete httproute argo-rollouts-http-route - ``` - -2. Remove the Argo Rollout. - ```sh - kubectl delete rollout rollouts-demo - ``` - -3. Remove the stable and canary services. - ```sh - kubectl delete services argo-rollouts-canary-service argo-rollouts-stable-service - ``` - -4. Remove the cluster role for the Argo Rollouts pod. - ```sh - kubectl delete clusterrole gateway-controller-role -n argo-rollouts - ``` - -5. Remove the cluster role binding. - ```sh - kubectl delete clusterrolebinding gateway-admin - ``` - -6. Remove Argo Rollouts. - ```sh - kubectl delete -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml - kubectl delete namespace argo-rollouts - ``` - diff --git a/assets/docs/pages/integrations/aws-elb.md b/assets/docs/pages/integrations/aws-elb.md deleted file mode 100644 index 953bb557f..000000000 --- a/assets/docs/pages/integrations/aws-elb.md +++ /dev/null @@ -1,6 +0,0 @@ -{{< callout type="info" >}} -To learn how to pair your kgateway proxy with an NLB or ALB, see the [AWS ELB guides]({{< link-hextra path="/setup/customize/aws-elb/" >}}). -{{< /callout >}} - -{{< reuse "agw-docs/snippets/aws-alb-nlb.md" >}} - diff --git a/assets/docs/pages/integrations/aws-elb/alb.md b/assets/docs/pages/integrations/aws-elb/alb.md deleted file mode 100644 index 98503d424..000000000 --- a/assets/docs/pages/integrations/aws-elb/alb.md +++ /dev/null @@ -1,200 +0,0 @@ -In this guide you explore how to expose the {{< reuse "agw-docs/snippets/kgateway.md" >}} proxy with an AWS application load balancer (ALB). - -{{< callout type="warning" >}} -The AWS Load Balancer Controller only supports the creation of an ALB through an Ingress Controller and not through the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}. Because of this, you must create the ALB separately through an Ingress resource that connects it to the service that exposes your gateway proxy. -{{< /callout >}} - -## Before you begin - -1. Create or use an existing AWS account. -2. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}. -3. Deploy the httpbin sample app. For more information, see the [sample app guide]({{< link-hextra path="/install/sample-app#deploy-app/" >}}). - 1. Create the httpbin app. - ```shell - kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml - ``` - - Example output: - ```txt - namespace/httpbin created - serviceaccount/httpbin created - service/httpbin created - deployment.apps/httpbin created - ``` - 2. Verify that the httpbin app is running. - ```sh - kubectl -n httpbin get pods - ``` - - Example output: - ```txt - NAME READY STATUS RESTARTS AGE - httpbin-d57c95548-nz98t 2/2 Running 0 18s - ``` - -## Step 1: Deploy gateway proxy resources - -1. Create a Gateway resource with an HTTP listener. You later pair this Gateway with an AWS ALB. - ```yaml - kubectl apply -n {{< reuse "agw-docs/snippets/namespace.md" >}} -f- <}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -2. Create DirectResponse and HTTPRoute resources to configure a custom healthcheck path on the gateway. In this example, you expose the `/healthz` path and configure it to always return a 200 HTTP response code by using the DirectResponse. Later, you configure the ALB to perform the health check against the `/healthz` path to determine if the Gateway is healthy. - ```yaml - kubectl apply -f- <}} - rules: - - matches: - - path: - type: Exact - value: /healthz - filters: - - type: ExtensionRef - extensionRef: - name: httpbin-healthcheck-dr - group: gateway.kgateway.dev - kind: DirectResponse - EOF - ``` - -3. Create another HTTPRoute resource to expose the httpbin app on the `albtest.com` domain. - ```yaml - kubectl apply -f- <}} - hostnames: - - "albtest.com" - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -## Step 2: Create an ALB with the AWS Load Balancer controller - -{{< reuse "agw-docs/snippets/aws-elb-controller-install.md" >}} - -5. Use an Ingress resource to define your ALB. When you apply this resource, the AWS Load Balancer Controller creates the ALB in your account. - ```yaml - kubectl apply -f- <}} - name: alb - annotations: - alb.ingress.kubernetes.io/scheme: internet-facing - alb.ingress.kubernetes.io/target-type: instance - alb.ingress.kubernetes.io/healthcheck-protocol: HTTP - alb.ingress.kubernetes.io/healthcheck-path: "/healthz" - spec: - ingressClassName: alb - rules: - - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: alb - port: - number: 8080 - EOF - ``` - - {{< callout type="info" >}} - If you later change your Ingress resource configuration, you might need to delete and re-create your Ingress resource for AWS to pick up the changes. - {{< /callout >}} - -6. Review the load balancer in the AWS EC2 dashboard. - 1. Go to the [AWS EC2 dashboard](https://console.aws.amazon.com/ec2). - 2. In the left navigation, go to **Load Balancing > Load Balancers**. - 3. Find and open the ALB that was created for you, with a name such as `k8s-{{< reuse "agw-docs/snippets/alb-elb-name.md" >}}-alb-`. Note that it might take a few minutes for the ALB to provision. - 4. On the **Resource map** tab, verify that the load balancer points to healthy EC2 targets in your cluster. For example, you can click on the target EC2 name to verify that the instance summary lists your cluster name. - {{< reuse-image src="img/alb.png" >}} - {{< reuse-image-dark srcDark="img/alb.png" >}} - -## Step 3: Test the ALB - -1. In the **Details** pane of the ALB, get the **DNS name** that was assigned to your ALB and save it as an environment variable. - ```sh - export INGRESS_GW_ADDRESS= - ``` - -2. Send a request to the httpbin app. Verify that you get back a 200 HTTP response code. - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:80/headers -H "host: albtest.com:80" - ``` - - Example output: - ```console - ... - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the Ingress, HTTPRoute, DirectResponse, and Gateway resources. - ```sh - kubectl delete ingress alb -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete httproute httpbin-alb -n httpbin - kubectl delete httproute httpbin-healthcheck -n httpbin - kubectl delete directresponse httpbin-healthcheck-dr -n httpbin - kubectl delete gateway alb -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -2. Delete the AWS IAM resources that you created. - ```sh - eksctl delete iamserviceaccount --name=${IAM_SA} --cluster=${CLUSTER_NAME} - aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME} - ``` - -3. Uninstall the Helm release for the `aws-load-balancer-controller`. - ```sh - helm uninstall aws-load-balancer-controller -n kube-system - ``` \ No newline at end of file diff --git a/assets/docs/pages/integrations/aws-elb/nlb.md b/assets/docs/pages/integrations/aws-elb/nlb.md deleted file mode 100644 index 03d24cc5e..000000000 --- a/assets/docs/pages/integrations/aws-elb/nlb.md +++ /dev/null @@ -1,311 +0,0 @@ -In this guide you explore how to expose the {{< reuse "agw-docs/snippets/kgateway.md" >}} proxy with an AWS network load balancer (NLB). The following use cases are covered: - -* **NLB HTTP**: Create an HTTP listener on the NLB that exposes an HTTP endpoint on your gateway proxy. Traffic from the NLB to the proxy is not secured. -* **TLS passthrough**: Expose an HTTPS endpoint of your gateway with an NLB. The NLB passes through HTTPS traffic to the gateway proxy where the traffic is terminated. - -{{< callout type="warning" >}} -Keep in mind the following considerations when working with an NLB: -* An AWS NLB has an idle timeout of 350 seconds that you cannot change. This limitation can increase the number of reset TCP connections. -{{< /callout >}} - -## Before you begin - -1. Create or use an existing AWS account. -2. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}. -3. Deploy the httpbin sample app. For more information, see the [sample app guide]({{< link-hextra path="/install/sample-app#deploy-app/" >}}). - 1. Create the httpbin app. - ```shell - kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml - ``` - - Example output: - ```txt - namespace/httpbin created - serviceaccount/httpbin created - service/httpbin created - deployment.apps/httpbin created - ``` - 2. Verify that the httpbin app is running. - ```sh - kubectl -n httpbin get pods - ``` - - Example output: - ```txt - NAME READY STATUS RESTARTS AGE - httpbin-d57c95548-nz98t 2/2 Running 0 18s - ``` - -## Step 1: Deploy the AWS Load Balancer controller - -{{< reuse "agw-docs/snippets/aws-elb-controller-install.md" >}} - -## Step 2: Deploy your gateway proxy - -1. Create a {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource with custom AWS annotations. These annotations instruct the AWS load balancer controller to expose the gateway proxy with a public-facing AWS NLB. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - metadata: - name: custom-gw-params - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - kube: - service: - extraAnnotations: - service.beta.kubernetes.io/aws-load-balancer-type: "external" - service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing - service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance" - EOF - ``` - - | Setting | Description | - | -- | -- | - | `aws-load-balancer-type: "external"` | Instruct Kubernetes to pass the Gateway's service configuration to the AWS load balancer controller that you created earlier instead of using the built-in capabilities in Kubernetes. For more information, see the [AWS documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/nlb/#configuration). | - | `aws-load-balancer-scheme: internet-facing ` | Create the NLB with a public IP addresses that is accessible from the internet. For more information, see the [AWS documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/nlb/#prerequisites). | - | `aws-load-balancer-nlb-target-type: "instance"` | Use the Gateway's instance ID to register it as a target with the NLB. For more information, see the [AWS documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/nlb/#instance-mode_1). | - -2. Depending on the annotations that you use on your gateway proxy, you can configure the NLB in different ways. - - {{< tabs tabTotal="2" items="Simple HTTP,TLS passthrough" >}} - {{% tab tabName="Simple HTTP" %}} - - Create a simple NLB that accepts HTTP traffic on port 80 and forwards this traffic to the HTTP listener on your gateway proxy. - - {{< reuse-image src="/img/elb-http.svg" >}} - {{< reuse-image-dark srcDark="/img/elb-http.svg" >}} - - This Gateway resource references the custom GatewayParameters resource that you created. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - infrastructure: - parametersRef: - name: custom-gw-params - group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - listeners: - - protocol: HTTP - port: 80 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{% /tab %}} - {{% tab tabName="TLS passthrough" %}} - Pass through HTTPS requests from the AWS NLB to your gateway proxy, and terminate TLS traffic at the gateway proxy for added security. - - {{< reuse-image src="/img/elb-tls-passthrough.svg" >}} - {{< reuse-image-dark srcDark="/img/elb-tls-passthrough.svg" >}} - - 1. Create a self-signed TLS certificate to configure your gateway proxy with an HTTPS listener. - {{< reuse "agw-docs/snippets/listeners-https-create-cert.md" >}} - - 2. Create a Gateway with an HTTPS listener that terminates incoming TLS traffic. Make sure to reference the custom {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource and the Kubernetes secret that contains the TLS certificate information. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - infrastructure: - parametersRef: - name: custom-gw-params - group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - listeners: - - name: https - port: 443 - protocol: HTTPS - hostname: https.example.com - tls: - mode: Terminate - certificateRefs: - - name: https - kind: Secret - allowedRoutes: - namespaces: - from: All - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -3. Verify that your gateway is created. - ```sh - kubectl get gateway aws-cloud -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -4. Verify that the gateway service is exposed with an AWS NLB and assigned an AWS hostname. - ```sh - kubectl get services aws-cloud -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ```console - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - aws-cloud LoadBalancer 172.20.39.233 k8s-{{< reuse "agw-docs/snippets/alb-elb-name.md" >}}-awscloud-edaaecf0c5-2d48d93624e3a4bf.elb.us-east-2.amazonaws.com 80:30565/TCP 12s - ``` - -5. Review the NLB in the AWS EC2 dashboard. - 1. Go to the [AWS EC2 dashboard](https://console.aws.amazon.com/ec2). - 2. In the left navigation, go to **Load Balancing > Load Balancers**. - 3. Find and open the NLB that was created for you, with a name such as `k8s-{{< reuse "agw-docs/snippets/alb-elb-name.md" >}}-awscloud-`. - 4. On the **Resource map** tab, verify that the load balancer points to EC2 targets in your cluster. For example, you can click on the target EC2 name to verify that the instance summary lists your cluster name. - -## Step 3: Test traffic to the NLB {#test-traffic} - -{{< tabs tabTotal="2" items="Simple HTTP,TLS passthrough" >}} -{{% tab tabName="Simple HTTP" %}} - -1. Create an HTTPRoute resource and associate it with the gateway that you created. - ```yaml - kubectl apply -f- <}} - hostnames: - - "www.nlb.com" - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Get the AWS hostname of the NLB. - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} aws-cloud -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') - echo $INGRESS_GW_ADDRESS - ``` - -3. Send a request to the httpbin app. - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:80/headers -H "host: www.nlb.com:80" - ``` - - Example output: - ```console - ... - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ``` - -{{% /tab %}} -{{% tab tabName="TLS passthrough" %}} - -1. Create an HTTPRoute resource and associate it with the gateway that you created. - ```yaml - kubectl apply -f- <}} - hostnames: - - "https.example.com" - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Get the IP address that is associated with the NLB's AWS hostname. - ```sh - export INGRESS_GW_HOSTNAME=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} aws-cloud -o jsonpath='{.status.loadBalancer.ingress[0].hostname}') - echo $INGRESS_GW_HOSTNAME - export INGRESS_GW_ADDRESS=$(dig +short ${INGRESS_GW_HOSTNAME} | head -1) - echo $INGRESS_GW_ADDRESS - ``` - -3. Send a request to the httpbin app. Verify that you see a successful TLS handshake and that you get back a 200 HTTP response code from the httpbin app. - ```sh - curl -vi --resolve "https.example.com:443:${INGRESS_GW_ADDRESS}" https://https.example.com:443/status/200 - ``` - - Example output: - ```console - * Hostname https.example.com was found in DNS cache - * Trying 3.XX.XXX.XX:443... - * Connected to https.example.com (3.XX.XXX.XX) port 443 (#0) - * ALPN, offering h2 - * ALPN, offering http/1.1 - * successfully set certificate verify locations: - * CAfile: /etc/ssl/cert.pem - * CApath: none - * TLSv1.2 (OUT), TLS handshake, Client hello (1): - * TLSv1.2 (IN), TLS handshake, Server hello (2): - * TLSv1.2 (IN), TLS handshake, Certificate (11): - * TLSv1.2 (IN), TLS handshake, Server key exchange (12): - * TLSv1.2 (IN), TLS handshake, Server finished (14): - * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): - * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): - * TLSv1.2 (OUT), TLS handshake, Finished (20): - * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): - * TLSv1.2 (IN), TLS handshake, Finished (20): - * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 - * ALPN, server accepted to use h2 - * Server certificate: - * subject: CN=*; O=any domain - * start date: Jul 23 20:03:48 2024 GMT - * expire date: Jul 23 20:03:48 2025 GMT - * issuer: O=any domain; CN=* - * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. - * Using HTTP2, server supports multi-use - * Connection state changed (HTTP/2 confirmed) - * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 - * Using Stream ID: 1 (easy handle 0x14200fe00) - ... - < HTTP/2 200 - HTTP/2 200 - ``` - -{{% /tab %}} -{{< /tabs >}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the Ingress and Gateway resources. - ```sh - kubectl delete {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} custom-gw-params -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete gateway aws-cloud -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete httproute httpbin-elb -n httpbin - kubectl delete secret https -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -2. Delete the AWS IAM resources that you created. - ```sh - aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME} - eksctl delete iamserviceaccount --name=${IAM_SA} --cluster=${CLUSTER_NAME} - ``` - -3. Uninstall the Helm release for the `aws-load-balancer-controller`. - ```sh - helm uninstall aws-load-balancer-controller -n kube-system - ``` \ No newline at end of file diff --git a/assets/docs/pages/integrations/external-dns-cert-manager.md b/assets/docs/pages/integrations/external-dns-cert-manager.md deleted file mode 100644 index 195b4ec3d..000000000 --- a/assets/docs/pages/integrations/external-dns-cert-manager.md +++ /dev/null @@ -1,351 +0,0 @@ -[ExternalDNS](https://github.com/kubernetes-sigs/external-dns) and [cert-manager](https://github.com/cert-manager/cert-manager) are two well-known integrations within the Kubernetes ecosystem that can be used in conjunction to automate the creation of TLS certificates. - -* **ExternalDNS**: Instead of manually editing your domain in your DNS provider to add load balancer IP addresses, you can use ExternalDNS to dynamically set up and control DNS records for discovered Gateway and HTTPRoute resources. When you define a hostname in an HTTPRoute resource, ExternalDNS uses the external address that is assigned to the Gateway's load balancer service that serves this hostname, and uses this information to create a DNS record in the DNS provider that you configured. -* **cert-manager**: You can then use cert-manager to quickly and programmatically generate certificates for your domain, and store them in a Kubernetes secret. By adding this certificates secret to the HTTPRoute on the Gateway for your domain, you can secure it for HTTPS traffic. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up ExternalDNS - -1. Save your domain in an environment variable. Note that you must own the domain to enable ExternalDNS to create DNS records on your behalf. - ```sh - export DOMAIN= - -2. Create an HTTPRoute resource to expose httpbin on your domain. - ```yaml - kubectl apply -f- <" - EOF - ``` - -5. Wait for the DNS entry to be created. Note that depending on the DNS provider you use, this process can take some time to complete. To verify that the DNS record is created, use the `dig` command as shown in the following example. - ```sh - dig ${DOMAIN} - ``` - - Example output for a successfully created DNS record: - ```console - ;; ANSWER SECTION: - ${DOMAIN} 300 IN A 164.90.241.80 - ``` - -## Set up cert-manager - -cert-manager is a Kubernetes controller that helps you automate the process of obtaining and renewing certificates from various PKI providers, such as AWS Private CA, Google Cloud CA, or Vault. In this example, you install cert-manager by using Helm and configure it to obtain TLS certificates for your domain from Let's Encrypt. - -1. Install cert-manager. - 1. Add the Jetstack Helm repository. - ```sh - helm repo add jetstack https://charts.jetstack.io --force-update - ``` - 2. Install cert-manager in your cluster. - ```sh - helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace \ - --set "extraArgs={--feature-gates=ExperimentalGatewayAPISupport=true}" --set installCRDs=true - ``` - {{< callout type="info" >}}To allow cert-manager to use the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}, you must set `--feature-gates=ExperimentalGatewayAPISupport=true` in the cert-manager Helm installation.{{< /callout >}} - -2. Create an Issuer resource that represents the Certificate Authority (CA) that you want cert-manager to use to issue the TLS certificates for your domain. - ```yaml - kubectl apply -f- < - server: https://acme-staging-v02.api.letsencrypt.org/directory - privateKeySecretRef: - name: letsencrypt-http-issuer-account-key - solvers: - - http01: - gatewayHTTPRoute: - parentRefs: - - name: http - namespace: kgateway-system - kind: Gateway - EOF - ``` - - | Setting | Description | - | -- | -- | - | `acme` | The protocol to use for issuing certificates. In this example, you configure cert-manager to obtain a Let's Encrypt certificate by using the ACME (Automated Certificate Management Environment) protocol. | - | `email` | Provide an email address where you can receive Let's Encrypt notifications for certificate expiration and account recovery. | - | `server` | The Let's Encrypt ACME server used for issuing certificates. The value `https://acme-staging-v02.api.letsencrypt.org/directory` uses the Let's Encrypt staging environment to avoid hitting rate limits during testing. For production setups, use the `https://acme-v02.api.letsencrypt.org/directory` server instead. | - | `privateKeySecretRef.name` | Using your email address, cert-manager automatically generates and stores an ACME private account key in a Kubernetes secret of this name. cert-manager then uses this key to authenticate with Let's Encrypt. This example uses the name `letsencrypt-http-issuer-account-key` in the `kgateway-system` namespace. | - | `solvers.http01` | To automate domain validation and certificate issuance, you use the HTTP-01 challenge. The HTTP-01 challenge is designed to prove that you have control over your domain by requiring you to store a challenge token in your cluster so that Let's Encrypt can validate it. For more information about this challenge, see the [Let's Encrypt documentation](https://letsencrypt.org/docs/challenge-types/#http-01-challenge). | - | `gatewayHTTPRoute.parentRefs` | The reference to the Gateway resource to solve certificate challenges. This example uses the `http` Gateway that you created in the get started guide. | - -3. Verify that your TLS certificates are created successfully. Note that depending on the CA that you use, this process might take a while to complete. - ```sh - kubectl get issuer letsencrypt-http -n kgateway-system - ``` - - Example output for successfully issued TLS certificates: - ```console - Status: - Acme: - Conditions: - Last Transition Time: 2023-11-09T16:03:58Z - Message: The ACME account was registered with the ACME server - Observed Generation: 1 - Reason: ACMEAccountRegistered - Status: True - Type: Ready - ``` - -4. Verify that the TLS certificate was added to the secret that you configured in the cert-manager issuer resource. - ```sh - kubectl get secret letsencrypt-http-issuer-account-key -n kgateway-system -o yaml - ``` - -## Configure an HTTPS listener on your gateway - -1. Add the cert-manager annotation and an HTTPS listener to the `http` gateway that you set up as part of the [Get started guide]({{< link-hextra path="/quickstart/" >}}). - ```yaml - kubectl apply -f- < GET /status/200 HTTP/2 -> Host: ${DOMAIN} -> user-agent: curl/7.88.1 -> accept: */* -> -< HTTP/2 200 -HTTP/2 200 -< access-control-allow-credentials: true -access-control-allow-credentials: true -< access-control-allow-origin: * -access-control-allow-origin: * -< date: Thu, 09 Nov 2023 17:28:17 GMT -date: Thu, 09 Nov 2023 17:28:17 GMT -< content-length: 0 -content-length: 0 -< x-envoy-upstream-service-time: 2 -x-envoy-upstream-service-time: 2 -< server: envoy -server: envoy - -< -* Connection #0 to host ${DOMAIN} left intact -``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Remove the cert-manager annotation and HTTPS listener from the `http` Gateway. - ```yaml - kubectl apply -f- <}} as the ingress gateway for your ambient mesh. - -## About ambient mesh - -Solo.io and Google collaborated to develop {{< gloss "Ambient mesh" >}}ambient mesh{{< /gloss >}}, a new "sidecarless" architecture for the Istio service mesh. Ambient mesh uses node-level ztunnels to route and secure Layer 4 traffic between pods with mutual TLS (mTLS). Waypoint proxies enforce Layer 7 traffic policies whenever needed. To onboard apps into the ambient mesh, you simply label the namespace the app belongs to. Because no sidecars need to be injected in to your apps, ambient mesh significantly reduces the complexity of adopting a service mesh. - -To learn more about ambient, see the [ambient mesh documentation](https://ambientmesh.io/docs/about/). - -## About this guide - -In this guide, you learn how to use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway to route traffic to the httpbin app that is part of an ambient service mesh. - -This guide assumes that you run your ambient mesh in a single cluster and want to use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway to protect your ambient mesh services. - -{{< reuse-image src="img/ambient-ingress.svg" width="600px" caption="Ingress gateway integration for an ambient mesh" >}} -{{< reuse-image-dark srcDark="img/ambient-ingress.svg" width="600px" caption="Ingress gateway integration for an ambient mesh" >}} - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Step 1: Set up an ambient mesh - -{{< reuse "agw-docs/snippets/setup-ambient-mesh.md" >}} - -## Step 2: Set up the ingress gateway - -To set up {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway for your ambient mesh, you simply add all the namespaces that you want to secure to your ambient mesh, including the namespace that your gateway proxy is deployed to. - -1. Add the `httpbin` and optionally the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace to your ambient mesh. The label instructs istiod to configure a ztunnel socket on all the pods in that namespace so that traffic to these pods is secured via mutual TLS (mTLS). If you do not label the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace, the traffic from the gateway proxy to the app is not secured via mTLS. - ```sh - kubectl label ns {{< reuse "agw-docs/snippets/namespace.md" >}} istio.io/dataplane-mode=ambient - kubectl label ns httpbin istio.io/dataplane-mode=ambient - ``` - -2. Send a request to the httpbin app and verify that you get back a 200 HTTP response code. All traffic from the gateway is automatically intercepted by a ztunnel that is co-located on the same node as the gateway. The ztunnel collects Layer 4 metrics before it forwards the request to the ztunnel that is co-located on the same node as the httpbin app. The connection between ztunnels is secured via mutual TLS. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" - ``` - - Example output: - ```console - HTTP/1.1 200 OK - ... - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "929c334b-e611-4aba-9bc6-ad6b2450db26" - ] - } - } - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - 1. Port-forward the `http` pod on port 8080. - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - - 2. Send a request to the httpbin app and verify that you get back a 200 HTTP response code. - ```sh - curl -i localhost:8080/headers -H "host: www.example.com" - ``` - - Example output: - ``` - HTTP/1.1 200 OK - ... - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "929c334b-e611-4aba-9bc6-ad6b2450db26" - ] - } - } - ``` - {{% /tab %}} - {{< /tabs >}} - -3. Verify that traffic between the gateway proxy and the httpbin app is secured via mutual TLS. Because traffic in an ambient mesh is intercepted by the ztunnels that are co-located on the same node as the sending and receiving service, you can check the logs of the ztunnels. - 1. Find the `NODE` that the httpbin app runs on. - ```sh - kubectl get pods -n httpbin -o wide - ``` - - Example output: - ``` - NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES - httpbin-54cf575757-hdv8t 3/3 Running 0 22h 10.XX.X.XX gke-ambient-default-pool-bb9a8da5-bdf4 - ``` - 2. Find the ztunnel that runs on the same node as the httpbin app. - ```sh - kubectl get pods -n istio-system -o wide | grep ztunnel - ``` - 3. Check the logs of that ztunnel instance and verify that the source and destination workloads have a SPIFFE ID. - ```sh - kubectl logs -n istio-system - ``` - - Example output: - ``` - 2025-03-19T17:32:42.762545Z info http access request complete src.addr=10.0.71.117:42468 src.workload="http-9db6c8995-l54dw" src.namespace="{{< reuse "agw-docs/snippets/namespace.md" >}}" src.identity="spiffe://cluster.local/ns/{{< reuse "agw-docs/snippets/namespace.md" >}}/sa/http" dst.addr=10.0.65.144:15008 dst.hbone_addr=10.0.65.144:8080 dst.service="httpbin.httpbin.svc.cluster.local" dst.workload="httpbin-577649ddb-7nc8p" dst.namespace="httpbin" dst.identity="spiffe://cluster.local/ns/httpbin/sa/httpbin" direction="inbound" method=GET path="/headers" protocol=HTTP1 response_code=200 host="www.example.com:8080" user_agent="curl/8.7.1" request_id="4c5fc679-c5cd-4721-8735-51bcdbea6e0f" duration="0ms" - 2025-03-19T17:32:46.810472Z info access connection complete src.addr=10.0.71.117:42468 src.workload="http-9db6c8995-l54dw" src.namespace="{{< reuse "agw-docs/snippets/namespace.md" >}}" src.identity="spiffe://cluster.local/ns/{{< reuse "agw-docs/snippets/namespace.md" >}}/sa/http" dst.addr=10.0.65.144:15008 dst.hbone_addr=10.0.65.144:8080 dst.service="httpbin.httpbin.svc.cluster.local" dst.workload="httpbin-577649ddb-7nc8p" dst.namespace="httpbin" dst.identity="spiffe://cluster.local/ns/httpbin/sa/httpbin" direction="inbound" bytes_sent=1290 bytes_recv=550 duration="6742ms" - ``` - - -## Next - -Now that you set up {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway for your ambient mesh, you can further control and secure ingress traffic with [Policies](../../../../about/policies/). - - diff --git a/assets/docs/pages/integrations/istio/ambient/waypoint.md b/assets/docs/pages/integrations/istio/ambient/waypoint.md deleted file mode 100644 index ef2efe27c..000000000 --- a/assets/docs/pages/integrations/istio/ambient/waypoint.md +++ /dev/null @@ -1,871 +0,0 @@ - -{{< callout type="warning" >}} -The waypoint integration for Envoy-based gateway proxies is deprecated and is planned to be removed in version 2.2. If you want to use AI capabilities, use an [agentgateway proxy](../../../../../../../agentgateway/) instead. -{{< /callout >}} - - - -Enforce Layer 7 policies for the apps in your ambient mesh by using {{< reuse "/agw-docs/snippets/kgateway.md" >}} as a waypoint proxy. - -## About ambient mesh - -Solo.io and Google collaborated to develop ambient mesh, a new "sidecarless" architecture for the Istio service mesh. Ambient mesh uses node-level ztunnels to route and secure Layer 4 traffic between pods with mutual TLS (mTLS). Waypoint proxies enforce Layer 7 traffic policies whenever needed. To onboard apps into the ambient mesh, you simply label the namespace the app belongs to. Because no sidecars need to be injected in to your apps, ambient mesh significantly reduces the complexity of adopting a service mesh. - -To learn more about ambient, see the [ambient mesh documentation](https://ambientmesh.io/docs/about/). - -## About this guide - -In this guide, you learn how to set up {{< reuse "/agw-docs/snippets/kgateway.md" >}} as a waypoint proxy for multiple apps in your ambient mesh. To demonstrate the Layer 7 capabilities of the waypoint proxy, you deploy the three sample apps `client`, `httpbin2`, and `httpbin3` to your cluster. The `client` app sends in-mesh traffic to `httpbin2` and `httpbin3`. To apply Layer 7 policies, you create HTTPRoute resources for the `httpbin2` and `httpbin3` apps that define the policies that you want to apply to each app. Because the HTTPRoute is scoped to a particular service, when the `client` app sends a request to that service, only the policies that are defined for that service are enforced by the waypoint proxy. - -{{< callout type="info" >}} -You can create an HTTPRoute and scope it to the waypoint proxy by referencing the waypoint proxy in the `parentRef` section. This way, the policies that are defined in the HTTPRoute are automatically applied to all services in the waypoint proxy namespace. -{{< /callout >}} - -{{< reuse-image src="img/waypoint.svg" width="600px" caption="Waypoint proxy for Layer 7 policy application in an ambient mesh" >}} -{{< reuse-image-dark srcDark="img/waypoint.svg" width="600px" caption="Waypoint proxy for Layer 7 policy application in an ambient mesh" >}} - -## Set up an ambient mesh - -{{< reuse "agw-docs/snippets/setup-ambient-mesh.md" >}} - -## Deploy sample apps - -Install the httpbin2, httpbin3, and curl client sample apps into the httpbin namespace. You use these sample apps to demonstrate the Layer 7 capabilities of the waypoint proxy. - -1. Create the httpbin namespace. - ```sh - kubectl create ns httpbin - ``` - -2. Deploy the httpbin2, httpbin3, and client sample apps. - {{< tabs tabTotal="3" items="httpbin2,httpbin3,client" >}} - {{% tab tabName="httpbin2" %}} - ```yaml - kubectl apply -f - <}} - -4. Verify that all apps are deployed successfully. - ```sh - kubectl get pods -n httpbin - ``` - - Example output: - ``` - NAME READY STATUS RESTARTS AGE - client-87678cb44-dclfs 1/1 Running 0 87m - httpbin2-58dcc755ff-ngq2f 1/1 Running 0 92m - httpbin3-77bbdd9b6b-8d8hq 1/1 Running 0 70m - ``` - -5. Label the `httpbin` namespace to add the httpbin2, httpbin3, and client apps to the ambient mesh. - ```sh - kubectl label ns httpbin istio.io/dataplane-mode=ambient - ``` - -{{% version exclude-if="2.0.x" %}} - -## Enable the waypoint integration {#waypoint-integration} - -Enable the waypoint integration for Envoy-based kgateway proxies. - -{{< callout type="warning" >}} -Note that the waypoint integration is deprecated for kgateway proxies and is planned to be removed in version 2.2. -{{< /callout >}} - -1. Enable the waypoint integration in your kgateway Helm chart. - ```sh - helm get values {{< reuse "/agw-docs/snippets/kgateway.md" >}} -n {{< reuse "/agw-docs/snippets/namespace.md" >}} -o yaml > {{< reuse "/agw-docs/snippets/kgateway.md" >}}.yaml - - helm upgrade -i --namespace kgateway-system --version v{{< reuse "agw-docs/versions/patch-dev.md" >}} \ - kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway \ - --set controller.image.pullPolicy=Always \ - --set waypoint.enabled=true \ - --values {{< reuse "/agw-docs/snippets/kgateway.md" >}}.yaml - ``` - -2. Verify that you see the `{{< reuse "/agw-docs/snippets/waypoint-class.md" >}}` GatewayClass in your cluster. - ```sh - kubectl get gatewayclasses -A - ``` - - Example output: - ``` - NAME CONTROLLER ACCEPTED AGE - kgateway kgateway.dev/kgateway True 2d19h - kgateway-waypoint kgateway.dev/kgateway True 1s - ``` -{{% /version %}} - -## Create a waypoint proxy - -Use the `{{< reuse "/agw-docs/snippets/waypoint-class.md" >}}` GatewayClass to deploy {{< reuse "/agw-docs/snippets/kgateway.md" >}} as a waypoint proxy in your cluster. - -1. Create a waypoint proxy in the httpbin namespace. Note that creating a waypoint proxy does not automatically enforce Layer 7 policies for the apps in your cluster. To assign a waypoint, you must label your apps. You learn how to label your apps in a later step. - - ```yaml - kubectl apply -f - <}} - namespace: httpbin - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/waypoint-class.md" >}} - listeners: - - name: proxy - port: 15088 - protocol: istio.io/PROXY - EOF - ``` - -2. Wait for the waypoint proxy to deploy successfully. - - ```sh - kubectl -n httpbin rollout status deploy {{< reuse "/agw-docs/snippets/waypoint-class.md" >}} - ``` - - Example output: - ``` - deployment "{{< reuse "/agw-docs/snippets/waypoint-class.md" >}}" successfully rolled out - ``` - -3. Label the httpbin2 and httpbin3 apps to use the waypoint proxy that you created. - - ```sh - kubectl -n httpbin label svc httpbin2 istio.io/use-waypoint={{< reuse "/agw-docs/snippets/waypoint-class.md" >}} - kubectl -n httpbin label svc httpbin3 istio.io/use-waypoint={{< reuse "/agw-docs/snippets/waypoint-class.md" >}} - ``` - -4. Send a request from the client app to httpbin2 and httpbin3. Verify that the request succeeds. - - ```sh - kubectl -n httpbin exec deploy/client -- curl -s http://httpbin2:8000/get - kubectl -n httpbin exec deploy/client -- curl -s http://httpbin3:8000/get - ``` - - Example output for httpbin2: - ``` - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "httpbin2:8000" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "590a6a48-60f8-4ec0-92d1-fcb629b97e0d" - ] - }, - "method": "GET", - "origin": "10.XX.X.XX:34059", - "url": "http://httpbin2:8000/get" - } - ``` - -## Enforce L7 policies with the waypoint {#waypoint-policies} - -In this step, you explore how to apply different types of Layer 7 policies to your sample apps. These policies are enforced by the {{< reuse "/agw-docs/snippets/kgateway.md" >}} waypoint proxy that you created earlier. You can add other Layer 7 policies to the waypoint proxy. For more information, see the [traffic management](../../../../traffic-management), [security](../../../../security), and [resiliency](../../../../resiliency) guides. - -### Header control - -Use the Kubernetes Gateway API to define header manipulation rules that you apply to the httpbin apps, including adding, setting, and removing request headers. - -1. Create an HTTPRoute resource for the httpbin2 app with the following request header modifications rules: - * Add the `App: httpbin2` header to all requests. - * Set the `User-Agent` header to `custom`. If the User-Agent header is not present, it is added to the request. - * Remove the `X-Remove` header from the request. - - Note that the HTTPRoute specifies the httpbin2 service in the `parentRefs` section. This setting instructs the waypoint proxy to enforce these policies for the httpbin2 app only. - ```yaml - kubectl apply -f - <}}'s {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} to apply a transformation policy to the httpbin2 app. - -1. If you have not done so yet, create an HTTPRoute for the httpbin2 app. You use this HTTPRoute to apply your transformation policy in the next step. - ```yaml - kubectl apply -f - <}} that applies a transformation policy to the httpbin2 app. In this example, the base64-encoded value from the `x-base64-encoded` header is decoded and added to the `x-base64-decoded` header, starting from the 11th character. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin2 - transformation: - response: - set: - - name: x-base64-decoded - value: '{{ substring(base64_decode(request_header("x-base64-encoded")), 11) }}' - EOF - ``` - -3. Use the client app to send a request to the httpbin2 app and include a base64-encoded value of `transformation test` in the request `x-base64-encoded` header. Verify that you get back a 200 HTTP response code, and that the decoded value is added to the `x-base64-decoded` response header, starting from the 11th character. - ```sh - kubectl -n httpbin exec deploy/client -- curl -vi http://httpbin2:8000/headers \ - -H "x-base64-encoded: dHJhbnNmb3JtYXRpb24gdGVzdA==" - ``` - - Example output: - ```console {hl_lines=[8,25,26]} - < HTTP/1.1 200 OK - ... - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; charset=utf-8 - content-length: 544 - x-envoy-upstream-service-time: 0 - x-base64-decoded: ion test - server: envoy - - { - "headers": { - "Accept": [ - "*/*" - ], - "App": [ - "httpbin2" - ], - "Host": [ - "httpbin2:8000" - ], - "User-Agent": [ - "custom" - ], - "X-Base64-Encoded": [ - "dHJhbnNmb3JtYXRpb24gdGVzdA==" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Envoy-External-Address": [ - "10.0.74.217" - ], - "X-Forwarded-For": [ - "10.0.74.217" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "4b6444cc-b631-49c9-b2b4-f71ec479925f" - ] - } - } - ``` - -4. Optional: Remove the {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} and HTTPRoute that you created in this guide. - ```sh - kubectl delete {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin - kubectl delete httproute httpbin2 -n httpbin - ``` - -### Local rate limiting - -1. If you have not done so yet, create an HTTPRoute for the httpbin2 app. You use this HTTPRoute to apply your local rate limiting policy in the next step. - ```yaml - kubectl apply -f - <}} that applies a local rate limiting policy to the httpbin2 app. In this example, only one request is allowed within 30 seconds. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: ratelimit - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin2 - rateLimit: - local: - tokenBucket: - maxTokens: 1 - tokensPerFill: 1 - fillInterval: 30s - EOF - ``` - -3. Use the client app to send three requests to the httpbin2 app. Verify that you get back a 200 HTTP response code for the first request, and that the second and third request are denied with a 429 HTTP response code. - ```sh - for i in {1..3}; do kubectl -n httpbin exec deploy/client -- curl -vi http://httpbin2:8000/headers ; done - ``` - - Example output: - ``` - * Request completely sent off - HTTP/1.1 200 OK - < HTTP/1.1 200 OK - ... - * Request completely sent off - HTTP/1.1 429 Too Many Requests - content-length: 18 - content-type: text/plain - server: envoy - ... - local_rate_limited - ... - * Request completely sent off - < HTTP/1.1 429 Too Many Requests - < content-length: 18 - < content-type: text/plain - < server: envoy - ... - local_rate_limited% - ``` - -4. Optional: Remove the {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} and HTTPRoute. - ```sh - kubectl delete {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} ratelimit -n httpbin - kubectl delete httproute httpbin2 -n httpbin - ``` - -### Istio AuthorizationPolicy - -Apply an Istio AuthorizationPolicy to allow access from specific apps only. - -1. Send a `GET` request from the client to the httpbin2 app. Verify that your request succeeds. - ```sh - kubectl -n httpbin exec deploy/client -- curl -vi http://httpbin2:8000/headers - ``` - - Example output: - ```console - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; charset=utf-8 - content-length: 439 - x-envoy-upstream-service-time: 2 - server: envoy - - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "httpbin2:8000" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Envoy-External-Address": [ - "10.0.74.45" - .... - ``` - -2. Create an Istio AuthorizationPolicy that denies all `GET` requests to the httpbin2 app. - ```yaml - kubectl apply -f- <}} -n httpbin -kubectl delete serviceaccount httpbin2 -n httpbin -kubectl delete service httpbin2 -n httpbin -kubectl delete deployment httpbin2 -n httpbin -kubectl delete serviceaccount httpbin3 -n httpbin -kubectl delete service httpbin3 -n httpbin -kubectl delete deployment httpbin3 -n httpbin -kubectl delete serviceaccount client -n httpbin -kubectl delete service client -n httpbin -kubectl delete deployment client -n httpbin -kubectl delete {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin -kubectl delete authorizationpolicy httpbin-authz -n httpbin -``` - diff --git a/assets/docs/pages/integrations/istio/sidecar/ingress.md b/assets/docs/pages/integrations/istio/sidecar/ingress.md deleted file mode 100644 index c6ccea6dc..000000000 --- a/assets/docs/pages/integrations/istio/sidecar/ingress.md +++ /dev/null @@ -1,285 +0,0 @@ -Use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway to control and secure traffic that enters your {{< gloss "Service Mesh" >}}service mesh{{< /gloss >}}. - -A service mesh is a dedicated infrastructure layer that you add your apps to, which ensures secure service-to-service communication across cloud networks. With a service mesh, you can solve problems such as service identity, mutual TLS communication, consistent L7 network telemetry gathering, service resilience, secure traffic routing between services across clusters, and policy enforcement, such as to enforce quotas or rate limit requests. To learn more about the benefits of using a service mesh, see [What is Istio](https://istio.io/latest/docs/overview/what-is-istio/) in the Istio documentation. - -### About Istio - -The open source project Istio is the leading service mesh implementation that offers powerful features to secure, control, connect, and monitor cloud-native, distributed applications. Istio is designed for workloads that run in one or more Kubernetes clusters, but you can also extend your service mesh to include virtual machines and other endpoints that are hosted outside your cluster. The key benefits of Istio include: - -* Automatic load balancing for HTTP, gRPC, WebSocket, MongoDB, and TCP traffic -* Secure TLS encryption for service-to-service communication with identity-based authentication and authorization -* Advanced routing and traffic management policies, such as retries, failovers, and fault injection -* Fine-grained access control and quotas -* Automatic logs, metrics, and traces for traffic in the service mesh - -### About the sidecar Istio integration - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} comes with an Istio integration that allows you to configure your gateway proxy with an Istio sidecar. The Istio sidecar uses mutual TLS (mTLS) to prove its identity and to secure the connection between your gateway and the services in your Istio service mesh. In addition, you can control and secure the traffic that enters the mesh by applying all the advanced routing, traffic management, security, resiliency, and AI capabilities that {{< reuse "/agw-docs/snippets/kgateway.md" >}} offers. - -## About this guide - -In this guide, you learn how to use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an ingress gateway proxy for the workloads in your Istio {{< gloss "Service Mesh" >}}service mesh{{< /gloss >}}. You explore how to enable the Istio sidecar mesh integration in {{< reuse "/agw-docs/snippets/kgateway.md" >}}, set up your ingress gateway proxy with a sidecar, and send secure mutual TLS traffic to the Bookinfo app as illustrated in the following image. - -{{< reuse-image src="img/sidecar-ingress.svg" width="800px" >}} -{{< reuse-image-dark srcDark="img/sidecar-ingress-dark.svg" width="800px" >}} - - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Step 1: Set up an Istio service mesh {#istio} - -1. Follow the [Istio documentation](https://istio.io/latest/docs/setup/getting-started/) to install Istio in sidecar mode. -2. Deploy the [Bookinfo sample app](https://istio.io/latest/docs/examples/bookinfo/). -3. Verify that your Bookinfo apps are up and running. - ```sh - kubectl get pods - ``` - -## Step 2: Enable the Istio integration {#istio-integration} - -Upgrade your {{< reuse "/agw-docs/snippets/kgateway.md" >}} installation to enable the Istio integration. - -1. Get the Helm values for your current Helm installation. - ```sh - helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - ``` - -2. Add the following values to the Helm values file to enable the Istio integration in {{< reuse "/agw-docs/snippets/kgateway.md" >}}. - ```yaml - - controller: - extraEnv: - KGW_ENABLE_ISTIO_AUTO_MTLS: true - ``` - -3. Upgrade your Helm installation. This upgrade automatically triggers a restart of any existing gateway proxies to inject `istio-proxy` and `sds` containers. - - ```sh - helm upgrade -i --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} --version {{< reuse "/agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - ``` - - {{< callout type="warning" >}} - The `istio-proxy` container in the gateway proxy looks for a service that is named `istiod` in the `istio-system` namespace to obtain a valid certificate. Depending on how you installed Istio, you might have a revisioned istiod deployment, such as `istiod-main`, or custom names for the Istio meta cluster ID and meta mesh ID. If this is the case, the `istio-proxy` container cannot deploy successfully. Continue with [Revisioned istiod and custom Istio meta mesh settings](#custom-istio-settings) to configure the `istio-proxy` container to use your custom values. - {{< /callout >}} - -## Step 3: Update the Istio proxy settings {#custom-istio-settings} - -Create a GatewayParameters resource to configure the Istio SDS container to pull the image from the kgateway repository. The steps vary depending on the following scenarios: - -* Revisioned istiod deployment, such as `istiod-main`; **or** custom cluster or mesh IDs. -* Revisionless Istio without custom cluster or mesh IDs. - -{{< tabs tabTotal="2" items="Revisioned Istio or custom cluster and mesh IDs,Revisionless Istio without custom IDs" >}} -{{% tab tabName="Revisioned Istio or custom cluster and mesh IDs" %}} - -Create a GatewayParameters resource to configure the revisioned istiod service address and any custom values for the Istio meta cluster ID and meta mesh ID. - -1. Get the name of the istiod service. Depending on how you set up Istio, you might see a service name with a revision, such as `istiod-main`. - ```sh - kubectl get services -n istio-system - ``` - - Example output: - ``` - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - istiod-main ClusterIP 10.102.24.31 15010/TCP,15012/TCP,443/TCP,15014/TCP 3h49m - ``` - -2. Derive the Kubernetes service address for your istiod deployment. The service address uses the format `..svc:15012`. For example, if your service name is `istiod-main`, the full service address is `istiod-main.istio-system.svc:15012`. - -3. Create a GatewayParameters resource to configure the revisioned istiod service address and any custom values for the Istio meta cluster ID and meta mesh ID. **Note**: If you do not set custom values for the cluster ID and mesh ID, you can omit these values. Then, the default values of `Kubernetes` for the cluster ID and `cluster.local` for the mesh ID are used. - ```yaml - kubectl apply -f- <}} - spec: - kube: - istio: - istioProxyContainer: - istioDiscoveryAddress: # such as istiod-main.istio-system.svc:15012 - istioMetaClusterId: ## such as the cluster name - istioMetaMeshId: ## such as the cluster name - sdsContainer: - image: - registry: cr.kgateway.dev/kgateway-dev - repository: sds - tag: v{{< reuse "agw-docs/versions/n-patch.md" >}} - EOF - ``` -{{% /tab %}} -{{% tab tabName="Revisionless Istio without custom IDs" %}} -Create a GatewayParameters resource to configure the Istio SDS container to pull the image from the kgateway repository. -```yaml -kubectl apply -f- <}} -spec: - kube: - sdsContainer: - image: - registry: cr.kgateway.dev/kgateway-dev - repository: sds - tag: v{{< reuse "agw-docs/versions/n-patch.md" >}} -EOF -``` -{{% /tab %}} -{{< /tabs >}} - -## Step 4: Create a gateway proxy {#create-gateway-proxy} - -Create or update a Gateway that includes the Istio proxy. - -1. Change the `http` gateway from the getting started tutorial to apply the custom settings of the GatewayParameters resource. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - infrastructure: - parametersRef: - name: custom-gw-params - group: gateway.kgateway.dev - kind: GatewayParameters - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -2. Verify that the gateway proxy is now successfully deployed. - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l gateway.networking.k8s.io/gateway-name=http \ - -o jsonpath='{range .items[*]}Pod: {.metadata.name} | Status: {.status.phase}{"\n"}Containers:{"\n"}{range .spec.containers[*]}- {.name}{"\n"}{end}{"\n"}{end}' - ``` - - Example output: Note that pod is running and has three containers, including the `istio-proxy`. - - ``` - Pod: http-f7c7f4b78-pwgnt | Status: Running - Containers: - - kgateway-proxy - - sds - - istio-proxy - ``` - - If you do not see the three containers, try restarting the proxy to apply the latest Gateway settings. - -## Step 5: Verify the integration {#verify} - -1. Create an HTTPRoute to route requests from the gateway proxy to the productpage app. - ```yaml - kubectl apply -f- <}} - hostnames: - - istio-sidecar.example - rules: - - matches: - - path: - type: PathPrefix - value: /productpage - backendRefs: - - name: productpage - port: 9080 - EOF - ``` - -2. Send a request to the productpage app through the gateway. Verify that you get back a 200 HTTP response code. This response code proves that the gateway proxy can establish a mutual TLS connection to the productpage app. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -I http://$INGRESS_GW_ADDRESS:8080/productpage \ - -H "host: istio-sidecar.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -I http://localhost:8080/productpage \ - -H "host: istio-sidecar.example:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - content-type: text/html; charset=utf-8 - content-length: 4183 - server: envoy - x-envoy-upstream-service-time: 29 - x-envoy-decorator-operation: productpage.bookinfo.svc.cluster.local:9080/* - ``` - - -{{< callout type="info">}} -To exclude a service from using Istio mTLS or to configure your own TLS settings, you can create a static Backend resource for the service and add the `kgateway.dev/disable-istio-auto-mtls` annotation to the Backend. Then, you can apply custom TLS settings by using a BackendTLSPolicy or BackendConfigPolicy. -{{< /callout >}} - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the HTTPRoute and gateway-related resources. - ```sh - kubectl delete httproute bookinfo - kubectl delete gatewayparameters custom-gw-params -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -2. Restore the http Gateway from the getting started tutorial. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. Get the Helm values for your current Helm installation and remove the values that you added in this guide. - ```sh - helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - ``` - -4. Upgrade your Helm installation. - ```sh - helm upgrade -i --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} --version {{< reuse "/agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - ``` - -5. Follow the Istio documentation to [uninstall Istio](https://istio.io/latest/docs/setup/getting-started/#uninstall) and [remove the Bookinfo sample app](https://istio.io/latest/docs/examples/bookinfo/#cleanup). - diff --git a/assets/docs/pages/landing.md b/assets/docs/pages/landing.md deleted file mode 100644 index 337803c25..000000000 --- a/assets/docs/pages/landing.md +++ /dev/null @@ -1,133 +0,0 @@ -{{< reuse "agw-docs/snippets/about-agw.md" >}} - -{{< callout type="info" >}} -**New to agentgateway?** Get started in minutes with the [Quickstart guide]({{< link-hextra path="/quickstart/" >}})! -{{< /callout >}} - -{{< reuse-image src="img/architecture.svg" caption="Figure: agentgateway works across compute environments to provide connectivity to various agentic tools, including MCP servers, agents, and OpenAPI endpoints." >}} - -## Why agentgateway? - -Traditional API gateways and reverse proxies aren't built for MCP and A2A, and adapting them isn't straightforward. These systems are optimized for **stateless REST-style interactions**—one request in, pick a backend, one response out—with no session context or ongoing connection state. - -MCP and A2A are fundamentally different: - -| Traditional API Gateway | Agentgateway | -|------------------------|--------------| -| Stateless request/response | **Stateful JSON-RPC sessions** with long-lived connections | -| One request → one backend | **Session fan-out** across multiple MCP servers | -| Client-initiated only | **Bidirectional**: servers can push events (SSE) to clients | -| Simple routing by path/header | **Protocol-aware routing** that understands JSON-RPC message bodies | -| Static backend mapping | **Dynamic tool virtualization** on a per-client basis | - -### Challenges traditional gateways can't solve - -- **Multiplexing & fan-out**: A single client request like "list available tools" needs to fan out across multiple backend MCP servers, aggregate responses, and return a unified result. -- **Server-initiated events**: MCP servers can push real-time updates via Server-Sent Events (SSE) that must be properly routed back through the client session. -- **Protocol negotiation**: Graceful handling of protocol upgrades and fallbacks as MCP/A2A specs evolve. -- **Per-session authorization**: Different clients may have access to different tools, requiring dynamic adjustment of what gets exposed. -- **Tool poisoning protection**: Defense against direct tampering, shadowing, and rug-pull attacks on tools. - -### Built for performance - -Agentgateway is built in **Rust** because performance and memory safety are non-negotiable for stateful, long-lived connections and fan-out patterns. Every millisecond and megabyte counts when managing concurrent sessions across multiple backend servers. - -## Features - -Agentgateway is a unified data plane for managing agent connectivity, built in Rust for high performance and reliability. It supports agent protocols including MCP and A2A, and provides a unified interface for LLM consumption. - -### LLM Gateway - -Route traffic to major LLM providers through a **unified OpenAI-compatible API**. Seamlessly switch between providers without changing your application code. - -| Provider | Chat Completions | Streaming | -|----------|:----------------:|:---------:| -| OpenAI / Azure OpenAI | ✅ | ✅ | -| Anthropic | ✅ | ✅ | -| Google Gemini | ✅ | ✅ | -| Google Vertex AI | ✅ | ✅ | -| Amazon Bedrock | ✅ | ✅ | - -#### OpenAI-compatible providers - -Don't see your provider? Many LLMs expose OpenAI-compatible APIs. Agentgateway can route to **any provider** that supports the OpenAI API format, including: - -- **Cohere**, **Mistral**, **Groq**, **Together AI**, **Fireworks** -- **Ollama**, **LM Studio**, **vLLM**, **llama.cpp** (local models) -- Any custom or self-hosted endpoint with OpenAI-compatible `/v1/chat/completions` - -#### Self-hosted models & Inference routing - -Running your own models on GPU infrastructure? Agentgateway implements the [Kubernetes Inference Gateway](https://gateway-api-inference-extension.sigs.k8s.io/) extensions for intelligent routing to local LLM workloads. Route based on: - -- **GPU & KV cache utilization** — Send requests to the least-loaded model -- **Prompt criticality** — Prioritize high-priority requests -- **LoRA adapters** — Route to models with specific fine-tuned adapters -- **Work queue depth** — Avoid overloaded inference servers - -### MCP Gateway - -Connect LLMs to tools and external data sources using the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/). Agentgateway provides: - -- **Tool federation**: Aggregate multiple MCP servers behind a single endpoint -- **Protocol support**: stdio, HTTP/SSE, and Streamable HTTP transports -- **OpenAPI integration**: Expose existing REST APIs as MCP-native tools -- **Authentication & authorization**: Built-in MCP auth spec compliance with OAuth providers (Auth0, Keycloak) - -### A2A Gateway - -Enable secure communication between AI agents using the [Agent-to-Agent (A2A)](https://github.com/a2aproject/A2A) protocol. Agents can: - -- Discover each other's capabilities -- Negotiate interaction modalities (text, forms, media) -- Collaborate on long-running tasks -- Operate without exposing internal state or tools - -### Security & Observability - -- **Authentication**: JWT, API keys, basic auth, MCP auth spec -- **Authorization**: Fine-grained RBAC with [Cedar policy engine](https://www.cedarpolicy.com/) -- **Traffic policies**: Rate limiting, CORS, TLS, external authz -- **Observability**: Built-in [OpenTelemetry](https://opentelemetry.io/) metrics, logs, and distributed tracing - -### Platform Agnostic - -Run agentgateway anywhere—bare metal, VMs, containers, or Kubernetes. Conformant to the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/) with support for HTTPRoute, GRPCRoute, TCPRoute, and TLSRoute. - -## Next steps - -{{< conditional-text include-if="local" >}} -{{< cards >}} - {{< card link="quickstart" title="Quickstart" >}} - {{< card link="about" title="About" >}} - {{< card link="deployment" title="Deployment" >}} - {{< card link="configuration" title="Configuration" >}} - {{< card link="tutorials" title="Tutorials" >}} - {{< card link="llm" title="LLM consumption" >}} - {{< card link="inference" title="Inference routing" >}} - {{< card link="mcp" title="MCP connectivity" >}} - {{< card link="agent" title="Agent connectivity" >}} - {{< card link="integrations" title="Integrations" >}} - {{< card link="reference" title="Reference" >}} - {{< card link="faqs" title="FAQs" >}} -{{< /cards >}} -{{< /conditional-text >}} - -{{< conditional-text include-if="kubernetes" >}} -{{< cards >}} - {{< card link="quickstart" title="Get started" >}} - {{< card link="about" title="About" >}} - {{< card link="install" title="Installation" >}} - {{< card link="setup" title="Gateway setup" >}} - {{< card link="llm" title="LLM consumption" >}} - {{< card link="inference" title="Inference routing" >}} - {{< card link="mcp" title="MCP connectivity" >}} - {{< card link="agent" title="Agent connectivity" >}} - {{< card link="traffic-management" title="Traffic management" >}} - {{< card link="security" title="Security" >}} - {{< card link="configuration" title="Configuration" >}} - {{< card link="observability" title="Observability" >}} - {{< card link="operations" title="Operations" >}} - {{< card link="reference" title="Reference" >}} -{{< /cards >}} -{{< /conditional-text >}} diff --git a/assets/docs/pages/observability/control-plane-metrics.md b/assets/docs/pages/observability/control-plane-metrics.md deleted file mode 100644 index 744a31a33..000000000 --- a/assets/docs/pages/observability/control-plane-metrics.md +++ /dev/null @@ -1,44 +0,0 @@ -By default, the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane exposes metrics in Prometheus format. You can use these metrics to monitor the health and performance of your gateway environment. For more information about how metrics are implemented, refer to the [kgateway project developer docs](https://github.com/kgateway-dev/kgateway/tree/main/devel/architecture/metrics.md). - -## View control plane metrics {#control-plane-metrics} - -The following steps show you how to quickly view the metrics endpoint of the control plane deployment. To integrate the metrics into your observability stack, see the [OpenTelemetry guide]({{< link-hextra path="/observability/otel-stack/" >}}). - -1. Port-forward the control plane deployment on port 9092. - - ```sh - kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} port-forward deployment/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} 9092 - ``` - -2. Open your browser to the metrics endpoint: [http://localhost:9092/metrics](http://localhost:9092/metrics). - - Example output: - - ```console - # HELP kgateway_controller_reconciliations_total Total controller reconciliations - # TYPE kgateway_controller_reconciliations_total counter - kgateway_controller_reconciliations_total{controller="gateway",result="success"} 1 - kgateway_controller_reconciliations_total{controller="gatewayclass",result="success"} 2 - kgateway_controller_reconciliations_total{controller="gatewayclass-provisioner",result="success"} 2 - ``` - -## Control plane metrics reference {#reference} - -Review the following table to understand more about each metric. - -Helpful terms: - -* Controller: A Kubernetes controller that reconciles resources as part of the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane deployment. - -* Resource: A Kubernetes object that is managed by a controller of the control plane. - -* Snapshot: A complete, point-in-time representation of the current state of resources that the controller builds and serves to a gateway proxy via the Envoy extensible Discovery Service (XDS) API. - -* Sync: The metrics refer to two kinds of syncs: - - * Status sync metrics represent the time it takes for you as a user to view the status that is reported on the resource. - * Snapshot sync metrics roughly represent the time it takes for a resource change to become effective in the gateway proxies. - -* Transform: The process of the control plane converting high-level resources or intermediate representations (IR) into lower-level representations into the structure that the XDS API expects for a snapshot. - -{{< reuse "agw-docs/snippets/latest/metrics-control-plane.md" >}} diff --git a/assets/docs/pages/observability/otel-stack.md b/assets/docs/pages/observability/otel-stack.md deleted file mode 100644 index 40dc0362a..000000000 --- a/assets/docs/pages/observability/otel-stack.md +++ /dev/null @@ -1,418 +0,0 @@ -## Step 1: Install Grafana Loki and Tempo {#grafana} - -Grafana is a suite of open source tools that help you analyze, visualize, and monitor data in your cluster. For the OTel stack, you install the following Grafana components: - -* **Loki**: A log aggregation system that indexes metadata about your logs as a set of labels, not the actual log contents. This way, Loki is more cost-efficient and performant than traditional log aggregation systems. - {{< callout type="tip" >}} - Loki works best when you use structured logging in your applications, such as JSON format. - {{< /callout >}} -* **Tempo**: A distributed tracing system that stores trace data in object storage (like Amazon S3) and integrates seamlessly with Grafana for visualization. Distributed tracing helps you see how requests move through a microservices environment, which helps you identify performance bottlenecks, debug issues, and otherwise monitor your system's health to ensure SLA compliance. - -Steps to install: - -1. Deploy Grafana Loki to your cluster. - - ```yaml - helm upgrade --install loki loki \ - --repo https://grafana.github.io/helm-charts \ - --version {{< reuse "agw-docs/versions/otel-stack-loki.md" >}} \ - --namespace telemetry \ - --create-namespace \ - --values - <}} \ - --namespace telemetry \ - --create-namespace \ - --values - <}} control plane and data plane gateway proxies. Then, the OTel collector exposes these metrics in Prometheus format so that other tools in your observability stack, such as Grafana, can in turn scrape the OTel collector and visualize the data. - -By using an OTel collector to aggregate metrics, you avoid having to configure each application individually to send their metrics to each backend observability tool. This setup simplifies your setup, lets you more easily change backends, improves reliability and debuggability, and lets you optimize preprocessing activities such as filtering, transforming, or enriching the metrics before scraping. - -You can deploy three separate OTel collectors that are optimized for the three different types of telemetry data: metrics, logs, and traces. This way, you can scale and optimize each collector based on your telemetry needs. - -{{< callout type="warning" >}} -The example pipelines in all three OTel collectors set up the `debug` exporter. This exporter is useful for testing and validation purposes. However, for production scenarios, remove this exporter to avoid performance impacts. -{{< /callout >}} - -1. Deploy the metrics collector to handle numerical measurements and time-series data. Note that you can also use the `promexporter` endpoint with Prometheus to scrape metrics from the collector pod, if you prefer the `pull` model to the `push` model. - - ```yaml - helm upgrade --install opentelemetry-collector-metrics opentelemetry-collector \ - --repo https://open-telemetry.github.io/opentelemetry-helm-charts \ - --version {{< reuse "agw-docs/versions/otel-stack-collector.md" >}} \ - --set mode=deployment \ - --set image.repository="otel/opentelemetry-collector-contrib" \ - --set command.name="otelcol-contrib" \ - --namespace=telemetry \ - --create-namespace \ - -f -<}} \ - --set mode=deployment \ - --set image.repository="otel/opentelemetry-collector-contrib" \ - --set command.name="otelcol-contrib" \ - --namespace=telemetry \ - --create-namespace \ - -f -<}} \ - --set mode=deployment \ - --set image.repository="otel/opentelemetry-collector-contrib" \ - --set command.name="otelcol-contrib" \ - --namespace=telemetry \ - --create-namespace \ - -f -<}} \ - --namespace telemetry \ - --create-namespace \ - --values - <}} setup. - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} consists of the control plane and an {{< reuse "/agw-docs/snippets/data-plane.md" >}} data plane. If you experience issues in your environment, such as policies that are not applied or traffic that is not routed correctly, in a lot of cases, these errors can be observed at the proxy. - -## Debug the control plane {#control-plane} - -1. Enable port-forwarding on the control plane. - - ```sh - kubectl port-forward deploy/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} 9095 - ``` - -2. In your browser, open the admin server debugging interface: [http://localhost:9095/](http://localhost:9095/). - - {{< reuse-image src="img/admin-server-debug-ui.png" caption="Figure: Admin server debugging interface.">}} - {{< reuse-image-dark srcDark="img/admin-server-debug-ui.png" caption="Figure: Admin server debugging interface.">}} - -3. Select one of the endpoints to continue debugging. {{< reuse "agw-docs/snippets/review-table.md" >}} - - | Endpoint | Description | - | -- | -- | - | `/debug/pprof` | View the pprof profile of the control plane. A profile shows you the stack traces of the call sequences, such as Go routines, that led to particular events, such as memory allocation. The endpoint includes descriptions of each available profile.| - | `/logging` | Review the current logging levels of each component in the control plane. You can also interactively set the log level by component, such as to enable `DEBUG` logs. | - | `/snapshots/krt` | View the current krt snapshot, or the point-in-time view of the transformed Kubernetes resources and their sync status that the control plane processed. These resources are then used to generate gateway configuration that is sent to the gateway proxies for routing decisions. | - | `/snapshots/xds` | The xDS snapshot is used for Envoy-based kgateway proxies, not agentgateway proxies. | - -## Debug your gateway setup - -{{< reuse "agw-docs/snippets/debug-gateway.md" >}} - - - - diff --git a/assets/docs/pages/operations/uninstall.md b/assets/docs/pages/operations/uninstall.md deleted file mode 100644 index 9724dbd8a..000000000 --- a/assets/docs/pages/operations/uninstall.md +++ /dev/null @@ -1,174 +0,0 @@ -If you no longer need your {{< reuse "/agw-docs/snippets/kgateway.md" >}} environment, you can uninstall the control plane and all gateway proxies. You can also optionally remove related components such as Prometheus and sample apps. - -## Uninstall - -Remove the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and gateway proxies. - -{{< callout type="info" >}} -Did you use Argo CD to install {{< reuse "/agw-docs/snippets/kgateway.md" >}}? Skip to the [Argo CD steps](#argocd). -{{< /callout >}} - -1. Get all HTTP routes in your environment. - - ```sh - kubectl get httproutes -A - ``` - -2. Remove each HTTP route. - - ```sh - kubectl delete -n httproute - ``` - -3. Get all reference grants in your environment. - - ```sh - kubectl get referencegrants -A - ``` - -4. Remove each reference grant. - - ```sh - kubectl delete -n referencegrant - ``` - -5. Get all gateways in your environment that are configured by the `{{< reuse "/agw-docs/snippets/gatewayclass.md" >}}` gateway class. - - ```sh - kubectl get gateways -A | grep {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - ``` - -6. Remove each gateway. - - ```sh - kubectl delete -n gateway - ``` - -7. Uninstall the control plane. - - 1. Uninstall the {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} Helm release. - - ```sh - helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - 2. Delete the CRDs. - - ```sh - helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - 3. Remove the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace. - - ```sh - kubectl delete namespace {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - 4. Confirm that the CRDs are deleted. - - ```sh - kubectl get crds | grep {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} - ``` - -8. Remove the Kubernetes Gateway API CRDs. If you installed a different version or channel of the Kubernetes Gateway API, update the following command accordingly. - - ```sh - kubectl delete -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml - ``` - -## Uninstall with ArgoCD {#argocd} - -For ArgoCD installations, use the following steps to clean up your environment. - -{{< tabs tabTotal="2" items="Argo CD UI,Argo CD CLI" >}} -{{% tab tabName="Argo CD UI" %}} -1. Port-forward the Argo CD server on port 9999. - ```sh - kubectl port-forward svc/argocd-server -n argocd 9999:443 - ``` - -2. Open the [Argo CD UI](https://localhost:9999/applications). - -3. Log in with the `admin` username and `gateway` password. -4. Find the application that you want to delete and click **x**. -5. Select **Foreground** and click **Ok**. -6. Verify that the pods were removed from the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace. - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ```txt - No resources found in {{< reuse "agw-docs/snippets/namespace.md" >}} namespace. - ``` - -6. Remove the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace. - ```sh - kubectl delete namespace {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -7. Remove the `argocd` namespace. - ```sh - kubectl delete namespace argocd - ``` - -{{% /tab %}} -{{% tab tabName="Argo CD CLI" %}} -1. Port-forward the Argo CD server on port 9999. - ```sh - kubectl port-forward svc/argocd-server -n argocd 9999:443 - ``` - -2. Log in to the Argo CD UI. - ```sh - argocd login localhost:9999 --username admin --password gateway --insecure - ``` - -3. Delete the {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} application. - - ```sh - argocd app delete {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-helm --cascade --server localhost:9999 --insecure - ``` - - Example output: - ```txt - Are you sure you want to delete '{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-helm' and all its resources? [y/n] y - application '{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-helm' deleted - ``` - -4. Delete the {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} CRD application. - - ```sh - argocd app delete {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}}-helm --cascade --server localhost:9999 --insecure - ``` - - Example output: - ```txt - Are you sure you want to delete '{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}}-helm' and all its resources? [y/n] y - application '{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}}-helm' deleted - ``` - -5. Verify that the pods were removed from the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace. - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ```txt - No resources found in {{< reuse "agw-docs/snippets/namespace.md" >}} namespace. - ``` - -6. Remove the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace. - ```sh - kubectl delete namespace {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -7. Remove the `argocd` namespace. - ```sh - kubectl delete namespace argocd - ``` - -{{% /tab %}} -{{< /tabs >}} - - diff --git a/assets/docs/pages/operations/upgrade.md b/assets/docs/pages/operations/upgrade.md deleted file mode 100644 index 8a9259ddc..000000000 --- a/assets/docs/pages/operations/upgrade.md +++ /dev/null @@ -1,207 +0,0 @@ -You can use this guide to upgrade the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and data plane components, or to apply changes to the components' configuration settings. - - - - - - -{{< conditional-text include-if="envoy" >}} - - {{< tabs tabTotal="3" items="Kubernetes Gateway API, Kubernetes, Istio" >}} -{{% tab tabName="Kubernetes Gateway API" %}} -1. Decide on the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} version that you want to use. - - * For help, review the [Upgrade Notes in the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} docs for each version](https://gateway-api.sigs.k8s.io/guides/#v12-upgrade-notes). - * Check if you need to install the [experimental channel for the features that you want to use](../../reference/versions/#experimental-features). - -2. Install the custom resources of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} version that you want to upgrade to, such as the standard {{< reuse "agw-docs/versions/k8s-gw-version.md" >}} version. - - * Standard channel: - - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml - ``` - - * Experimental channel: Note that some CRDs are prefixed with `X` to indicate that the entire CRD is experimental and subject to change. - - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml - ``` - - Example output: - - ```txt - customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created - ``` - -3. Check the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} CRDs. Remove any outdated CRDs. - - ```sh - kubectl get crds -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.versions[*].name}{"\t"}{.metadata.annotations.gateway\.networking\.k8s\.io/bundle-version}{"\t"}{.metadata.annotations.gateway\.networking\.k8s\.io/channel}{"\n"}{end}' | grep gateway.networking.k8s.io - ``` - - Example output: - - ```txt - gatewayclasses.gateway.networking.k8s.io v1 v1beta1 v1.2.0 experimental - gateways.gateway.networking.k8s.io v1 v1beta1 v1.2.0 experimental - grpcroutes.gateway.networking.k8s.io v1 v1.2.0 experimental - httproutes.gateway.networking.k8s.io v1 v1beta1 v1.2.0 experimental - ``` -{{% /tab %}} -{{% tab tabName="Kubernetes" %}} -For Kubernetes upgrades, consult your cloud infrastructure provider. -{{% /tab %}} -{{% tab tabName="Istio" %}} -For Istio upgrades, consult the docs based on the way that you installed Istio. Example providers: - -* [Upstream Istio](https://istio.io/latest/docs/setup/upgrade/) -* [Gloo Operator](https://docs.solo.io/gloo-mesh-enterprise/latest/istio/operator/upgrade/) -* [Gloo Mesh Helm](https://docs.solo.io/gloo-mesh-enterprise/latest/istio/manual/upgrade/) - -{{% /tab %}} - {{< /tabs >}} - -{{< /conditional-text >}} - - - - -## Upgrade {#upgrade-steps} - -1. Set the version you want to upgrade to in an environment variable, such as the latest patch version (`{{< reuse "agw-docs/versions/n-patch.md" >}}`) . - - ```sh - export NEW_VERSION={{< reuse "agw-docs/versions/n-patch.md" >}} - ``` - -2. Apply the new CRDs for the control and data plane by using Helm. - - 1. **Optional**: To check the CRDs locally, download the CRDs to a `helm` directory. - - ```sh - helm template --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} --output-dir ./helm - ``` - - 2. Upgrade the CRDs in your cluster: - - ```sh - helm upgrade -i --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} - ``` - -3. Make any changes to your Helm values. - - 1. Get the Helm values file for your current version. - - ```sh - helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > values.yaml - open values.yaml - ``` - - 2. Compare your current Helm chart values with the version that you want to upgrade to. - - * **Show all values**: - - ```sh - helm show values oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} - ``` - - * **Get a file with all values**: You can get a `{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml` file for the upgrade version by pulling and inspecting the Helm chart locally. - - ```sh - helm pull oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} - tar -xvf {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-{{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}.tgz - open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml - ``` - - 3. Make any changes that you want by editing your `values.yaml` Helm values file or preparing the `--set` flags. For development v{{< reuse "agw-docs/versions/patch-dev.md" >}} builds, include the `controller.image.pullPolicy=Always` setting or refer to the exact image digest to avoid using cached images. - -4. Upgrade the {{< reuse "agw-docs/snippets/kgateway.md" >}} control plane Helm installation. - * Make sure to include your Helm values when you upgrade either as a configuration file or with `--set` flags. Otherwise, any previous custom values that you set might be overwritten. - * When using the development build v{{< reuse "agw-docs/versions/patch-dev.md" >}}, add the `--set controller.image.pullPolicy=Always` option to ensure you get the latest image. Alternatively, you can specify the exact image digest. - * To use experimental Gateway API features, include the experimental feature gate, `--set controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true`. - - ```sh - helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \ - -f values.yaml \ - --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} - ``` - -5. Verify that the control plane runs the upgraded version. - - ```sh - kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} get pod -l app.kubernetes.io/name={{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -o jsonpath='{.items[0].spec.containers[0].image}' - ``` - - Example output: - ``` - cr.{{< reuse "agw-docs/snippets/kgateway.md" >}}.dev/controller:{{< reuse "agw-docs/versions/n-patch.md" >}} - ``` - -6. Confirm that the control plane is up and running. - - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - diff --git a/assets/docs/pages/quickstart.md b/assets/docs/pages/quickstart.md deleted file mode 100644 index 00c279afc..000000000 --- a/assets/docs/pages/quickstart.md +++ /dev/null @@ -1,29 +0,0 @@ -Get started with {{< reuse "/agw-docs/snippets/kgateway.md" >}}. {{< reuse "agw-docs/snippets/kgateway-about.md" >}} - -## Before you begin - -These quick start steps assume that you have a Kubernetes cluster, `kubectl`, and `helm` already set up. For quick testing, you can use [Kind](https://kind.sigs.k8s.io/). - -```sh -kind create cluster -``` - -## Install - -The following steps get you started with a basic installation. For detailed instructions, see the [installation guides]({{< link-hextra path="/install" >}}). - -{{< reuse "agw-docs/snippets/get-started.md" >}} - -Good job! You now have the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane running in your cluster. - -## Next steps - -{{< icon "kgateway" >}} [Set up an API gateway with an httpbin sample app]({{< link-hextra path="/install/sample-app/" >}}). This guide uses the Envoy-based {{< reuse "/agw-docs/snippets/kgateway.md" >}} proxy to set up an API gateway. Then, deploy a sample httpbin app, configure a basic HTTP listener on the API gateway, and route traffic to httpbin by using an HTTPRoute resource. - -## Cleanup - -No longer need {{< reuse "/agw-docs/snippets/kgateway.md" >}}? Uninstall with the following command: - -```sh -helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` diff --git a/assets/docs/pages/reference/add-docs.md b/assets/docs/pages/reference/add-docs.md deleted file mode 100644 index c47009509..000000000 --- a/assets/docs/pages/reference/add-docs.md +++ /dev/null @@ -1,257 +0,0 @@ -To contribute new documentation to kgateway, follow these steps: - -- Identify the audience and intended use for the content. -- Choose the type of content you wish to contribute. -- Decide on a name, location, and other front matter for your content -- Write your contribution following the kgateway contribution guidelines. -- Submit your contribution as a PR from your fork to the `kgateway-dev/kgateway.dev` GitHub repository. -- Follow the review process until your contribution is merged. - -{{< callout type="info" >}} -Looking to contribute code to kgateway? See the [contributing guide in the Community repo](https://github.com/kgateway-dev/community/blob/main/CONTRIBUTING.md). -{{< /callout >}} - -## Audience and intended use {#audience} - -The best documentation starts by knowing the intended users, their knowledge, and what you expect them to do with the information. Otherwise, you cannot determine the appropriate scope and depth of information to provide, its ideal structure, or the necessary supporting information. The following examples show this principle in action: - -- The user needs to perform a specific task: Provide the set of steps that are required to accomplish the task. - -- The user must understand a concept before they can perform a task: Before the task, tell them about the prerequisite information or provide a link to it. - -- The user needs to make a decision: Provide the conceptual information necessary to know when to make the decision, the available options, and when to choose one option instead of the other. - -- The user needs to understand complex feature relationships: Provide a diagram showing the relationships, rather than writing multiple pages of content that is tedious to read and understand. - -After you identified your audience and the information that they need, select a suitable [content type](#content-type). - - -## Content types {#content-types} -When you understand the audience and the intended use for the content that you want to add, you can choose the content type that best addresses the needs of the audience. The following table shows the supported content types, their intended audiences, and the goals each type strives to achieve: - -|Content type | Goals | Audiences | -| -- | -- | -- | -|Concepts | Concepts explain key principles of kgateway, its functionality, features, and underlying technologies. For example, you might want to describe the external authentication flow in kgateway and how the components interact with each other. Concepts do not include sequences of steps. Instead, links might be provided to corresponding guides that explain how to set up and use the feature that you described in your concept. | New users or users that are unfamiliar with the project and the feature it provides. | -| Guides | Guides provide the steps or procedure to accomplish a certain task. For example, you might want to write a guide for how to set up external authentication in kgateway. Guides give only minimal information about how the feature works, but can include links to related concepts. | Users that want to try out kgateway. | -| Setup pages | Setup pages focus on steps for how to install, configure, and set up kgateway. | New or existing uses who want to install kgateway. -| Reference pages| Reference pages provide detailed information about certain kgateway components, its CLI, Helm values, and API. Most reference content is automatically generated from the code. | Users with advanced and deep technical knowledge of the project. | -| FAQs | FAQs provide quick answers to common questions about the kgateway project. Generally, the FAQs are not very technical in nature. Answers can link to existing guides, concepts, or other content types for users to learn more. | users with specific questions who are looking for brief answers and resources to learn more. | -| Troubleshooting | Troubleshooting topics provide either general debugging guides or error-specific help. For general debugging, share a process that helps users find, analyze, and resolve the cause of an error. For error-specific topics, provide details on what is happening with example messages, why it's happening, and how to fix the issue. | Users who encounter an error and need to debug. | - - -## File names {#file-names} - -All documentation in the kgateway project is written in markdown and built by using the static site generator Hugo. In Hugo, the name of the file or folder becomes part of the link to your page. Becaues, of that, it is important to carefully choose the name for the file or folder that you want to add. If the file name consists of multiple words, separate them by hyphens. For example, to add a topic about external authentication, your file name might be `ext-auth.md`. All file names must be lowercase. Keep file and folder names as short as possible to ensure easy cross-linking between topics. - - -## Front matter {#front-matter} - -Each file must start with a front matter that includes the title and weight of the file. Pick a title for your topic that has the keywords you want search engines to find. The weight configures the placement of the page in relation to other pages in the same directory, and therefore determines the order in which files are displayed in the left-hand navigation. - -In the following example, the topic shows up as `External authentication` in the left-hand navigation. - -``` ---- -title: External authentication -weight: 20 ---- -``` - -If you want to add a folder or "twistie" to the left-hand navigation of the docs that has multipe sub-topics, the folder must have at least one `_index.md` file. This file has the title of your twistie and can be used to provide general overview information about the section that you want to add. Note that you must add additional pages to your folder for the twistie to show up in the left-hand navigation. If your folder contains only an `_index.md` file, it shows up as a regular page. The following example shows a sample folder structure: - -``` -|-- security -|----- _index.md // provides conceptional security information -|----- access-logging.md // guide for how to set up access logging -|----- cors.md // guide for how to set up CORS -|----- csrf.md // guide for how to set up CSRF -``` - - -## Hugo shortcodes {#shortcodes} - -As mentioned earlier, the documentation in the kgateway project is built by using the static site generator Hugo. Hugo uses reusable templates, commonly referred to as shortcodes, to display, style, and render site elements, such as tables, videos, or cards and to manage the content for these elements more easily. Supported shortcodes can be found in the [kgateway project repo](https://github.com/kgateway-dev/kgateway.dev/tree/main/layouts/shortcodes) as well as the [Hextra Hugo theme](https://github.com/imfing/hextra/tree/main/exampleSite/content/docs/guide/shortcodes). - -Review common shortcodes that you find throughout the documentation: - -### link-hextra - -Use the link-hextra shortcode to link to a topic within the documentation in a way that is compatible with the versioning strategy. - -```markdown -[AI Backend API docs]({{}}) -``` - -### conditional-text - -Use the conditional-text shortcode to conditionally display content based on whether the page is in the `content/docs/envoy` or `content/docs/agentgateway` section. This is particularly useful when creating reusable content in the `assets/agw-docs` directory that needs to differ between Envoy-based kgateway and agentgateway documentation. The shortcode automatically detects the current section from the page URL and shows or hides content accordingly. - -The following example shows how to use conditional-text in an assets file that can be reused in both sections: - -Content in `assets/agw-docs/snippets/example-install.md`: -```markdown -{{}} -Install kgateway using the Envoy-based proxy configuration. -{{}} -{{}} -Install kgateway using the agentgateway configuration. -{{}} -``` - -When this snippet is reused via `{{}}`: -- In pages under `docs/envoy/`, only the first paragraph is displayed. -- In pages under `docs/agentgateway/`, only the second paragraph is displayed. - -Supported parameters: -- `include-if`: Shows content only when the current section matches the specified value (e.g., `"envoy"`, `"agentgateway"`, or `"envoy,agentgateway"` for multiple sections) -- `exclude-if`: Shows content only when the current section does not match the specified value - -### reuse -You can use the reuse shortcode to reuse content in multiple places while maintaining a single source of truth. A common use case for this shortcode is a reference to the latest version, product names, or short paragraphs. The source of the reused content is stored as a markdown file in the `assets/agw-docs` directory. - -The following example shows the example syntax for using this shortcode: -```markdown -The guide includes steps to install {{}} in three ways. -``` - -The content of `product-name.md` is as follows: -``` -kgateway -``` - -The resulting content in the web page will be rendered as: -```markdown -The guide includes steps to install kgateway in three ways. -``` -### reuse-image and reuse-image-dark {#reuse-image} - -Similar to the reuse shortcode, the reuse-image and reuse-image-dark shortcodes are used to display images in the documentation. Images are stored in the `assets/img` folder. - -{{< callout type="warning" >}} -You must use both shortcodes together to display an image. This way, the image is displayed in both light and dark mode. If you do not have a different image file, still include both shortcodes with the same `src` image file. -{{< /callout >}} - -The following example shows the example syntax for using this shortcode: - -```markdown -{{}} -{{}} -``` - -To support different screen sizes, make sure to use images of type `.svg` only. - - -### cards - -Use the cards shortcode to display a card in the documentation that links to a specific topic within or outside the documentation. You can read more about this shortcode [here](https://imfing.github.io/hextra/docs/guide/shortcodes/cards/). - -Example card: - -{{< cards >}} -{{< card link="../../../quickstart" title="Get started" >}} -{{< /cards >}} - -Shortcode syntax -```markdown -{{}} -{{}} -{{}} -``` - - -### callout - -A box that displays important information to the user. You can read more about this shortcode [here](https://imfing.github.io/hextra/docs/guide/shortcodes/callout/). - -Example callout: - -{{< callout type="info" >}} -This is a sample callout of type info. -{{< /callout >}} - -Shortcode syntax: -```markdown -{{}} -This is a sample callout of type info. -{{}} -``` - -### version - -Use the version shortcode to conditionally display content based on the documentation version being viewed. - -Example: -```markdown - -Content to show only for the specified 2.1.x version. - - -``` - -Supported parameters: -- `include-if`: Shows content only when the current version matches the specified version -- `exclude-if`: Shows content only when the current version does not match the specified version - -Available versions: Check the `hugo.yaml` file's `versions` section in the [kgateway.dev repository](https://github.com/kgateway-dev/kgateway.dev/blob/main/hugo.yaml#L129) for the current versions. - -### gloss - -Use the gloss shortcode to add inline glossary tooltips to terms in your documentation. When users hover over or click a glossary term, a tooltip displays the term's definition from the glossary data file. - -The shortcode takes a glossary key as the first argument and optionally accepts inner content for the displayed text. If no inner content is provided, the key itself is used as the display text. - -Example: - -```markdown -The {{}}API Gateway{{}} manages traffic routing. - -You can also use it without inner content: {{}} -``` - -The glossary definitions are stored in `data/glossary.yaml`. Each entry should have a `short` field (displayed in the tooltip) and optionally a link field for a "Learn more" link. - -## Redirects {#redirects} - -If you want to redirect a page to a new location, you can add a redirect rule to the [`static/_redirects` file in the `kgateway.dev` repository](https://github.com/kgateway-dev/kgateway.dev/blob/main/static/_redirects). - -The format is as follows. For more information, see the [Cloudflare documentation](https://developers.cloudflare.com/pages/configuration/redirects/). - -``` - -``` - -Example: - -```yaml -/docs/mcp /docs/main/agentgateway 301 -``` - -## Create a PR in GitHub {#pr} - -The kgateway documentation follows the standard GitHub collaboration flow for pull requests (PRs). This well-established collaboration model helps open source projects manage the following types of contributions: - -- Add new files to the repository. -- Edit existing files. -- Review the added or modified files. -- Manage multiple release or development branches. - -The contribution guidelines assume you can complete the following tasks: - -- Fork the [kgateway docs repository](https://github.com/kgateway-dev/kgateway.dev/). -- Create a branch for your changes. -- Add commits to that branch. -- Open a PR to share your contribution. - -## Review {#review} - -The documentation maintainers of the kgateway project will review your pull request to ensure the PR follows the documentation contribution guidelines. Once reviewed and approved by the maintainers, your PR is merged into the documentation codebase and your changes will show up on the documentation site. - -## Generated docs {#generated-docs} - -The kgateway project automatically generates the following documentation from the code. - -* [API reference]({{< link-hextra path="/reference/api/" >}}) -* [Helm reference]({{< link-hextra path="/reference/helm/" >}}) -* [Control plane metrics](../../../observability/control-plane-metrics/) - -To learn more about how to generate these docs, see the [GitHub Workflows README](https://github.com/kgateway-dev/kgateway.dev/tree/main/.github/workflows/README.md). diff --git a/assets/docs/pages/reference/contribution/preview.md b/assets/docs/pages/reference/contribution/preview.md deleted file mode 100644 index 642bd3f34..000000000 --- a/assets/docs/pages/reference/contribution/preview.md +++ /dev/null @@ -1,31 +0,0 @@ -The kgateway documentation is built by using the static site generator Hugo. As you write your content, you can locally preview your changes. - -## Before you begin - -1. Download and install the [`hugo` CLI](https://github.com/gohugoio/hugo/releases/tag/v0.135.0) version 0.135.0. Make sure to download the `extended` version to ensure all features are available that are required to build the site. - -2. Make sure that `hugo` is installed. - ```sh - hugo version - ``` - - Example output: - ``` - hugo v0.135.0-f30603c47f5205e30ef83c70419f57d7eb7175ab+extended darwin/arm64 BuildDate=2024-09-27T13:17:08Z VendorInfo=gohugoio - ``` - -3. Install the Node.js dependencies. If you do not have Node.js and `npm` installed on your machine, follow the instructions [here](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install them. - ```sh - npm install - ``` - -4. Install the version of [Golang](https://go.dev/doc/install) used in `go.mod` and make sure `go` is in your `$PATH`. - -## Build the site locally - -1. Build the site locally. - ```sh - hugo server -D - ``` - -2. Open the site. The local preview is available at [localhost:1313](localhost:1313). diff --git a/assets/docs/pages/reference/contribution/styleguide.md b/assets/docs/pages/reference/contribution/styleguide.md deleted file mode 100644 index 8eac9e2ff..000000000 --- a/assets/docs/pages/reference/contribution/styleguide.md +++ /dev/null @@ -1,60 +0,0 @@ -All documentation contributions in kgateway must follow general standards to ensure content is clear, concise, and understandable. - -## Language - -All documentation content must be written in English. Currently, kgateway does not support other languages. - -## Sentence case - -Use sentence case for any content that you add. Sentence case means to capitalize the first word in a sentence and end with a punctuation mark like a period. Do not capitalize words, unless it is a product name, API, or other word that commonly is capatilized. - -| Do ✅ | Don't ❌ | -| -- | -- | -| Use the HTTPS protocol to send traffic. | Use the https protcol to send traffic. -| Configure external authentication. | Configure External Authentication. | - -## Title case for titles - -Use title case for the value of `title:` in the front matter of your markdown page. Title case capitalizes the first letter in any word. - -| Do ✅ | Don't ❌ | -| -- | -- | -| Local rate limiting | Local Rate Limiting | -| Shadowing | shadowing | - -## Simple, present tense - -Use simple, present tense throughout the content that you want to add. Avoid past and future tense, unless it is required to convery the correct information. - -| Do ✅ | Don't ❌ | -| -- | -- | -| Verify that the pod runs. | Verify that the pod is running. | -| When you click this button, the UI opens. | When you click this button, the UI will open. | -| To create the CORS policy, follow this example. | In order to create the CORS policy, look at the example below and follow its instructions. | - -## Active voice - -Make sure to use active voice where the subject of the sentence performs the action that is described by the verb. - -| Do ✅ | Don't ❌ | -| -- | -- | -| You can enhance the security of your gateway with CORS policies. | Security of your gateway can be enhanced with CORS policies. | -| During an update, the management plane cannot update Envoy filters. | During an update, there are Envoy filters that it can't update | - -## "I" and "we" - -Avoid "I" and "we" in your content contribution. Instead, phrase sentences in the second-person or use the term user. - -| Do ✅ | Don't ❌ | -| -- | -- | -| In this topic, set up traffic shadowing.| In this topic, we will set up a traffic shadowing. | -| With kgateway, you can set up advanced traffic routing. | We offer advanced traffic routing.| - -## Future statements - -Avoid making promises or giving hints about the future releases and features. If you want want to talk about a feature that is still under development, mark it as experimental or beta and use proper callout shortcodes to draw the user's attention to that information. - -| Do ✅ | Don't ❌ | -| -- | -- | -| `` | We plan to deliver a new routing feature in the next release. | - diff --git a/assets/docs/pages/reference/glossary.md b/assets/docs/pages/reference/glossary.md deleted file mode 100644 index 7073976f7..000000000 --- a/assets/docs/pages/reference/glossary.md +++ /dev/null @@ -1,199 +0,0 @@ -Welcome to the kgateway glossary! This page breaks down the key terms for API gateways, AI, service mesh, Kubernetes, and other cloud-native words you'll find while using kgateway. Think of it as your quick reference hub whenever something feels unfamiliar. - -## How to use this glossary - -To get a clear picture of how kgateway works, you might find it helpful to explore related key terms. - -- **Just starting?** Begin with API Gateway → Backends → Routes → TrafficPolicy. -- **Focusing on AI?** Explore Agentgateway → A2A → LLM Gateway → MCP. -- **Working with service mesh?** Study ambient mesh → data plane → control plane → security. - -In this glossary, some terms come directly from the Kubernetes, Gateway API, or cloud-native open source ecosystem. These terms are marked with a chain-link icon (🔗) and link to the docs for the relevant project. - -Throughout the docs, terms that are defined in this glossary are underlined. When you hover over the term, the definition pops up for quick reference. - -### Still not finding what you need? - -If a term is missing: - -1. Try the search bar. -2. Check examples in the tutorials. -3. Visit the [API reference]({{< link-hextra path="/reference/api/" >}}). -4. Remember that some terms come from general Kubernetes or cloud-native concepts. - -*This glossary grows alongside kgateway. If you notice a missing term, consider contributing to help others!* - -## A–C - -### A2A -**Agent-to-Agent Protocol (A2A)** - -A secure, policy-driven communication method for AI agents running in an ambient mesh. It enables lightweight, sidecar-free interactions between agents. - -🔗 *See official documentation*: https://a2a-protocol.org/latest/ - -### Agentgateway -An open-source data plane optimized for agentic AI workloads. Kgateway uses agentgateway to route and manage traffic for LLMs, inference services, and AI-native applications. - -**Learn more**: [Agentgateway docs]({{< link-hextra path="/" >}}) - -### Agents -Autonomous AI components that make decisions, communicate with services, and interact with other agents (with or without sidecars). In Kgateway, agents participate in the mesh and communicate over A2A or Envoy-based traffic. - -### Ambient Mesh -A service mesh architecture that removes the need for sidecars. Instead of injecting proxies into every pod, ambient mesh uses waypoint proxies and ztunnels to simplify operations and reduce overhead. - -🔗 *See official documentation*: https://ambientmesh.io/ - -### API Gateway -The central entry point for controlling, securing, and routing API traffic. - -In kgateway, two types of proxies can act as API Gateways: - -- The **Envoy-based Kgateway proxy** (traditional API and service mesh traffic) -- **Agentgateway** (AI/LLM-specific traffic) - -{{< reuse "agw-docs/snippets/control-plane-note.md" >}} - -### Backends -Destination services or endpoints that kgateway routes traffic to, such as Kubernetes Services, Lambdas, external hosts, or custom backends. These backends are connected to routes for forwarding traffic. - -**Learn more**: [Backend guides]({{< link-hextra path="/traffic-management/destination-types/backends/" >}}) - -### Cluster (Kubernetes) -A collection of Kubernetes nodes (control plane + workers) that run your workloads and host kgateway. - -### Cluster (Envoy) -A logical group of upstream endpoints used by Envoy for load balancing. The Envoy-based kgateway data plane automatically generates Envoy clusters based on your Backends and route configuration. - -### Control Plane -The system that configures and manages the data plane. -In kgateway, the control plane distributes routing rules, policies, and extension configuration to the supported data plane proxies: the Envoy-based kgateway proxy and the agentgateway proxy. - -{{< reuse "agw-docs/snippets/control-plane-note.md" >}} - -### CRDs (Custom Resource Definitions) -Extend the Kubernetes API with custom resource types. - -🔗 *See official documentation*: https://kubernetes.io/docs/reference/glossary/?all=true#term-custom-resource-definition - -## D–F - -### Data Plane -The layer that actually processes live traffic. Kgateway supports the following data plane proxies: - -- Envoy-based Kgateway proxies -- Agentgateway (for AI workloads) - -{{< reuse "agw-docs/snippets/control-plane-note.md" >}} - -### Delegation -A way to share routing responsibility across teams or namespaces. A parent route delegates part of its routing logic to child routes, allowing flexible ownership. - -### DirectResponse -A policy that allows the gateway to immediately return a response without forwarding traffic to a backend. Useful for maintenance pages, blocking traffic, or custom messages. - -### Egress -Outbound traffic leaving the mesh or cluster. Egress gateways often apply policies such as access control, filtering, or auditing. - -### Envoy -A high-performance L7 proxy used as the primary data plane for API and service mesh workloads when you create a Gateway from the `kgateway` GatewayClass. - -### External Authorization -An Envoy extension that offloads authorization decisions to an external service. Kgateway can integrate with these systems to enforce access control. - -## G–L - -### Gateway -A Gateway API resource that represents the instantiation of a gateway implementation. - -🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.Gateway - -### GatewayClass -Defines a class of Gateways with a shared configuration or implementation. Depending on how you install kgateway, you may have one or more GatewayClass resources created for you. - -🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.GatewayClass - -### Gateway Extension -A kgateway resource that integrates extended services such as external authorization, rate limits, and processors into the Gateway data plane configuration. - -**Learn more**: [GatewayExtension API docs]({{< link-hextra path="/reference/api/#gatewayextension" >}}) - -### GatewayParameters -Configures template, deployment, and runtime settings for a Gateway instance (including Envoy proxy configuration). - -**Learn more**: [Gateway setup guides]({{< link-hextra path="/setup/default/" >}}) - -### GRPCRoute -A Gateway API resource for configuring gRPC routing rules. - -🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.GRPCRoute - -### HTTPRoute -A Gateway API resource for configuring HTTP/HTTPS routing rules. - -🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.HTTPRoute - -### Inference Extension Project -Mechanisms for running inference or AI processing in traffic flows—typically implemented as Envoy filters or external processors. - -🔗 *See official documentation*: https://gateway-api-inference-extension.sigs.k8s.io/ - -### Lambda -Serverless compute functions in Amazon Web Services (AWS) that kgateway can route traffic to via Backends. - -### Large Language Model (LLM) -AI models trained on massive datasets to generate human-like text. Kgateway manages LLM traffic by using the agentgateway data plane. - -### LLM Gateway / AI Gateway -A traffic-management pattern specialized for LLM, agent, MCP, and AI inference traffic. Agentgateway acts as the data plane for this pattern. - -## M–O - -### MCP (Model Context Protocol) -A protocol for exchanging model context, metadata, and tool information between LLM gateways, tools, and agents. - -### Observability (Logging, Monitoring, Tracing) -Systems that help you understand the behavior of your network traffic. You can integrate an OpenTelemetry-based observability solution into kgateway to get telemetry data for your traffic, including access logs, metrics, and distributed traces. - -## P–R - -### Proxy -A data plane process (Envoy or agentgateway) that receives, processes, and forwards traffic based on kgateway configuration. - -**Learn more**: [Architecture docs]({{< link-hextra path="/about/architecture/" >}}) - -### Rate Limiting -Controls how many requests can reach your services over time. Often implemented via Gateway Extensions using Envoy rate-limit services. - -### ReferenceGrant -A Gateway API resource that controls cross-namespace references. - -🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.ReferenceGrant - -### Resiliency -Techniques like retries, timeouts, and circuit breakers that make applications more reliable when failures occur. - -## S–Z - -### Security -Authentication, authorization, and encryption settings that protect your traffic and data. - -### Service Mesh -A network layer for service-to-service communication. Kgateway integrates with Istio and ambient mesh to support mesh-based traffic patterns. - -### TCPRoute -A Gateway API resource for configuring TCP routing rules. - -🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.TCPRoute - -### Traffic Management -Features that shape, route, or modify traffic, such as load balancing, matching, filtering, and transformations. - -### TrafficPolicy -A kgateway resource that defines advanced traffic management settings, retries, timeouts, mirroring, security policies, and more. - -**Learn more**: [TrafficPolicy concept docs]({{< link-hextra path="/about/policies/trafficpolicy/" >}}) - -### Translation -The kgateway control plane process that converts Gateway API resources and CRDs into xDS configuration for enforcement in the Envoy-based kgateway or agentgateway data planes. diff --git a/assets/docs/pages/reference/helm/2.2.x/agentgateway-crds.md b/assets/docs/pages/reference/helm/2.2.x/agentgateway-crds.md deleted file mode 100644 index 11db01ee7..000000000 --- a/assets/docs/pages/reference/helm/2.2.x/agentgateway-crds.md +++ /dev/null @@ -1,5 +0,0 @@ - - -{{< callout type="info" >}} -No configurable values are currently available for this chart. -{{< /callout >}} \ No newline at end of file diff --git a/assets/docs/pages/reference/helm/2.2.x/agentgateway.md b/assets/docs/pages/reference/helm/2.2.x/agentgateway.md deleted file mode 100644 index 75c5fd356..000000000 --- a/assets/docs/pages/reference/helm/2.2.x/agentgateway.md +++ /dev/null @@ -1,43 +0,0 @@ - -## Values - -| Key | Type | Description | Default | -|-----|------|-------------|---------| -| affinity | object | Set affinity rules for pod scheduling, such as 'nodeAffinity:'. | `{}` | -| controller | object | Configure the agentgateway control plane deployment. | `{"extraEnv":{},"image":{"pullPolicy":"","registry":"","repository":"controller","tag":""},"logLevel":"info","replicaCount":1,"service":{"ports":{"agwGrpc":9978,"health":9093,"metrics":9092},"type":"ClusterIP"},"strategy":{},"xds":{"tls":{"enabled":false}}}` | -| controller.extraEnv | object | Add extra environment variables to the controller container. | `{}` | -| controller.image | object | Configure the controller container image. | `{"pullPolicy":"","registry":"","repository":"controller","tag":""}` | -| controller.image.pullPolicy | string | Set the image pull policy for the controller. | `""` | -| controller.image.registry | string | Set the image registry for the controller. | `""` | -| controller.image.repository | string | Set the image repository for the controller. | `"controller"` | -| controller.image.tag | string | Set the image tag for the controller. | `""` | -| controller.logLevel | string | Set the log level for the controller. | `"info"` | -| controller.replicaCount | int | Set the number of controller pod replicas. | `1` | -| controller.service | object | Configure the controller service. | `{"ports":{"agwGrpc":9978,"health":9093,"metrics":9092},"type":"ClusterIP"}` | -| controller.service.ports | object | Set the service ports for gRPC and health endpoints. | `{"agwGrpc":9978,"health":9093,"metrics":9092}` | -| controller.service.type | string | Set the service type for the controller. | `"ClusterIP"` | -| controller.strategy | object | Change the rollout strategy from the Kubernetes default of a RollingUpdate with 25% maxUnavailable, 25% maxSurge. E.g., to recreate pods, minimizing resources for the rollout but causing downtime: strategy: type: Recreate E.g., to roll out as a RollingUpdate but with non-default parameters: strategy: type: RollingUpdate rollingUpdate: maxSurge: 100% | `{}` | -| controller.xds | object | Configure TLS settings for the xDS gRPC servers. | `{"tls":{"enabled":false}}` | -| controller.xds.tls.enabled | bool | Enable TLS encryption for xDS communication. When enabled, the agent gateway xDS server (port 9978) will use TLS. When TLS is enabled, you must create a Secret named 'agentgateway-xds-cert' in the agentgateway installation namespace. The Secret must be of type 'kubernetes.io/tls' with 'tls.crt', 'tls.key', and 'ca.crt' data fields present. | `false` | -| deploymentAnnotations | object | Add annotations to the agentgateway deployment. | `{}` | -| discoveryNamespaceSelectors | list | List of namespace selectors (OR'ed): each entry can use 'matchLabels' or 'matchExpressions' (AND'ed within each entry if used together). Agentgateway includes the selected namespaces in config discovery. For more information, see the docs https://kgateway.dev/docs/latest/install/advanced/#namespace-discovery. | `[]` | -| fullnameOverride | string | Override the full name of resources created by the Helm chart, which is 'agentgateway'. If you set 'fullnameOverride: "foo", the full name of the resources that the Helm release creates become 'foo', such as the deployment, service, and service account for the agentgateway control plane in the agentgateway-system namespace. | `""` | -| gatewayClassParametersRefs | object | Map of GatewayClass names to GatewayParameters references that will be set on the default GatewayClasses managed by kgateway. Each entry must define both the name and namespace of the GatewayParameters resource. The default GatewayClasses managed by kgateway are: - agentgateway Example: gatewayClassParametersRefs: agentgateway: name: shared-gwp namespace: kgateway-system | `{}` | -| image | object | Configure the default container image for the components that Helm deploys. You can override these settings for each particular component in that component's section, such as 'controller.image' for the agentgateway control plane. If you use your own private registry, make sure to include the imagePullSecrets. | `{"pullPolicy":"IfNotPresent","registry":"cr.agentgateway.dev","tag":""}` | -| image.pullPolicy | string | Set the default image pull policy. | `"IfNotPresent"` | -| image.registry | string | Set the default image registry. | `"cr.agentgateway.dev"` | -| image.tag | string | Set the default image tag. | `""` | -| imagePullSecrets | list | Set a list of image pull secrets for Kubernetes to use when pulling container images from your own private registry instead of the default agentgateway registry. | `[]` | -| inferenceExtension | object | Configure the integration with the Gateway API Inference Extension project, which lets you use agentgateway to route to AI inference workloads like LLMs that run locally in your Kubernetes cluster. Documentation for Inference Extension can be found here: https://kgateway.dev/docs/latest/agentgateway/inference/ | `{"enabled":false}` | -| inferenceExtension.enabled | bool | Enable Inference Extension support in the agentgateway controller. | `false` | -| nameOverride | string | Add a name to the default Helm base release, which is 'agentgateway'. If you set 'nameOverride: "foo", the name of the resources that the Helm release creates become 'agentgateway-foo', such as the deployment, service, and service account for the agentgateway control plane in the agentgateway-system namespace. | `""` | -| nodeSelector | object | Set node selector labels for pod scheduling, such as 'kubernetes.io/arch: amd64'. | `{}` | -| podAnnotations | object | Add annotations to the agentgateway pods. | `{"prometheus.io/scrape":"true"}` | -| podSecurityContext | object | Set the pod-level security context. For example, 'fsGroup: 2000' sets the filesystem group to 2000. | `{}` | -| resources | object | Configure resource requests and limits for the container, such as 'limits.cpu: 100m' or 'requests.memory: 128Mi'. | `{}` | -| securityContext | object | Set the container-level security context, such as 'runAsNonRoot: true'. | `{}` | -| serviceAccount | object | Configure the service account for the deployment. | `{"annotations":{},"create":true,"name":""}` | -| serviceAccount.annotations | object | Add annotations to the service account. | `{}` | -| serviceAccount.create | bool | Specify whether a service account should be created. | `true` | -| serviceAccount.name | string | Set the name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `""` | -| tolerations | list | Set tolerations for pod scheduling, such as 'key: "nvidia.com/gpu"'. | `[]` | diff --git a/assets/docs/pages/reference/helm/2.2.x/kgateway-crds.md b/assets/docs/pages/reference/helm/2.2.x/kgateway-crds.md deleted file mode 100644 index 11db01ee7..000000000 --- a/assets/docs/pages/reference/helm/2.2.x/kgateway-crds.md +++ /dev/null @@ -1,5 +0,0 @@ - - -{{< callout type="info" >}} -No configurable values are currently available for this chart. -{{< /callout >}} \ No newline at end of file diff --git a/assets/docs/pages/reference/helm/2.2.x/kgateway.md b/assets/docs/pages/reference/helm/2.2.x/kgateway.md deleted file mode 100644 index 865128ff5..000000000 --- a/assets/docs/pages/reference/helm/2.2.x/kgateway.md +++ /dev/null @@ -1,47 +0,0 @@ - -## Values - -| Key | Type | Description | Default | -|-----|------|-------------|---------| -| affinity | object | Set affinity rules for pod scheduling, such as 'nodeAffinity:'. | `{}` | -| controller | object | Configure the kgateway control plane deployment. | `{"extraEnv":{},"image":{"pullPolicy":"","registry":"","repository":"kgateway","tag":""},"logLevel":"info","replicaCount":1,"service":{"ports":{"grpc":9977,"health":9093,"metrics":9092},"type":"ClusterIP"},"strategy":{},"xds":{"tls":{"enabled":false}}}` | -| controller.extraEnv | object | Add extra environment variables to the controller container. | `{}` | -| controller.image | object | Configure the controller container image. | `{"pullPolicy":"","registry":"","repository":"kgateway","tag":""}` | -| controller.image.pullPolicy | string | Set the image pull policy for the controller. | `""` | -| controller.image.registry | string | Set the image registry for the controller. | `""` | -| controller.image.repository | string | Set the image repository for the controller. | `"kgateway"` | -| controller.image.tag | string | Set the image tag for the controller. | `""` | -| controller.logLevel | string | Set the log level for the controller. | `"info"` | -| controller.replicaCount | int | Set the number of controller pod replicas. | `1` | -| controller.service | object | Configure the controller service. | `{"ports":{"grpc":9977,"health":9093,"metrics":9092},"type":"ClusterIP"}` | -| controller.service.ports | object | Set the service ports for gRPC and health endpoints. | `{"grpc":9977,"health":9093,"metrics":9092}` | -| controller.service.type | string | Set the service type for the controller. | `"ClusterIP"` | -| controller.strategy | object | Change the rollout strategy from the Kubernetes default of a RollingUpdate with 25% maxUnavailable, 25% maxSurge. E.g., to recreate pods, minimizing resources for the rollout but causing downtime: strategy: type: Recreate E.g., to roll out as a RollingUpdate but with non-default parameters: strategy: type: RollingUpdate rollingUpdate: maxSurge: 100% | `{}` | -| controller.xds | object | Configure TLS settings for the xDS gRPC servers. | `{"tls":{"enabled":false}}` | -| controller.xds.tls.enabled | bool | Enable TLS encryption for xDS communication. When enabled, both the main xDS server (port 9977) and agent gateway xDS server (port 9978) will use TLS. When TLS is enabled, you must create a Secret named 'kgateway-xds-cert' in the kgateway installation namespace. The Secret must be of type 'kubernetes.io/tls' with 'tls.crt', 'tls.key', and 'ca.crt' data fields present. | `false` | -| deploymentAnnotations | object | Add annotations to the kgateway deployment. | `{}` | -| discoveryNamespaceSelectors | list | List of namespace selectors (OR'ed): each entry can use 'matchLabels' or 'matchExpressions' (AND'ed within each entry if used together). Kgateway includes the selected namespaces in config discovery. For more information, see the docs https://kgateway.dev/docs/latest/install/advanced/#namespace-discovery. | `[]` | -| fullnameOverride | string | Override the full name of resources created by the Helm chart, which is 'kgateway'. If you set 'fullnameOverride: "foo", the full name of the resources that the Helm release creates become 'foo', such as the deployment, service, and service account for the kgateway control plane in the kgateway-system namespace. | `""` | -| gatewayClassParametersRefs | object | Map of GatewayClass names to GatewayParameters references that will be set on the default GatewayClasses managed by kgateway. Each entry must define both the name and namespace of the GatewayParameters resource. The default GatewayClasses managed by kgateway are: - kgateway - kgateway-waypoint Example: gatewayClassParametersRefs: kgateway: name: shared-gwp namespace: kgateway-system | `{}` | -| image | object | Configure the default container image for the components that Helm deploys. You can override these settings for each particular component in that component's section, such as 'controller.image' for the kgateway control plane. If you use your own private registry, make sure to include the imagePullSecrets. | `{"pullPolicy":"IfNotPresent","registry":"cr.kgateway.dev/kgateway-dev","tag":""}` | -| image.pullPolicy | string | Set the default image pull policy. | `"IfNotPresent"` | -| image.registry | string | Set the default image registry. | `"cr.kgateway.dev/kgateway-dev"` | -| image.tag | string | Set the default image tag. | `""` | -| imagePullSecrets | list | Set a list of image pull secrets for Kubernetes to use when pulling container images from your own private registry instead of the default kgateway registry. | `[]` | -| inferenceExtension | object | Configure the integration with the Gateway API Inference Extension project, which lets you use kgateway to route to AI inference workloads like LLMs that run locally in your Kubernetes cluster. Documentation for Inference Extension can be found here: https://kgateway.dev/docs/latest/agentgateway/inference/ | `{"enabled":false}` | -| inferenceExtension.enabled | bool | Enable Inference Extension. If enabled, agentgateway.enabled should also be set to true. Enabling inference extension without agentgateway is deprecated in v2.1 and will not be supported in v2.2. | `false` | -| nameOverride | string | Add a name to the default Helm base release, which is 'kgateway'. If you set 'nameOverride: "foo", the name of the resources that the Helm release creates become 'kgateway-foo', such as the deployment, service, and service account for the kgateway control plane in the kgateway-system namespace. | `""` | -| nodeSelector | object | Set node selector labels for pod scheduling, such as 'kubernetes.io/arch: amd64'. | `{}` | -| podAnnotations | object | Add annotations to the kgateway pods. | `{"prometheus.io/scrape":"true"}` | -| podSecurityContext | object | Set the pod-level security context. For example, 'fsGroup: 2000' sets the filesystem group to 2000. | `{}` | -| policyMerge | object | Policy merging settings. Currently, TrafficPolicy's extAuth, extProc, and transformation policies support deep merging. E.g., to enable deep merging of extProc policy in TrafficPolicy: policyMerge: trafficPolicy: extProc: DeepMerge | `{}` | -| resources | object | Configure resource requests and limits for the container, such as 'limits.cpu: 100m' or 'requests.memory: 128Mi'. | `{}` | -| securityContext | object | Set the container-level security context, such as 'runAsNonRoot: true'. | `{}` | -| serviceAccount | object | Configure the service account for the deployment. | `{"annotations":{},"create":true,"name":""}` | -| serviceAccount.annotations | object | Add annotations to the service account. | `{}` | -| serviceAccount.create | bool | Specify whether a service account should be created. | `true` | -| serviceAccount.name | string | Set the name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `""` | -| tolerations | list | Set tolerations for pod scheduling, such as 'key: "nvidia.com/gpu"'. | `[]` | -| validation | object | Configure validation behavior for route and policy safety checks in the control plane. This setting determines how invalid configuration is handled to prevent security bypasses and to maintain multi-tenant isolation. | `{"level":"standard"}` | -| validation.level | string | Validation level. Accepted values: "standard" or "strict" (case-insensitive). Standard replaces invalid routes with a direct 500 response and continues applying valid configuration. Strict adds xDS preflight validation and blocks snapshots that would NACK in Envoy. Default is "standard". | `"standard"` | -| waypoint | object | Enable the waypoint integration. This enables kgateway to translate istio waypoints and use kgateway as a waypoint in an Istio Ambient service mesh setup. | `{"enabled":false}` | diff --git a/assets/docs/pages/reference/ports.md b/assets/docs/pages/reference/ports.md deleted file mode 100644 index 33d6d6894..000000000 --- a/assets/docs/pages/reference/ports.md +++ /dev/null @@ -1,63 +0,0 @@ -Review the ports that are used by kgateway. - -Kgateway deploys containers that listen on certain ports for incoming traffic. In the following sections, you can review the pods and services that make up kgateway, and the ports that these pods and services listen on. - - - - -## Installation - -The {{< reuse "agw-docs/snippets/kgateway.md" >}} installation process uses a Helm chart to create the necessary custom resource definitions (CRDs), deployments, services, pods, etc. The services and pods listen on specific ports to enable communication between the components that make up {{< reuse "agw-docs/snippets/kgateway.md" >}}. - -## Components - -A standard installation of {{< reuse "agw-docs/snippets/kgateway.md" >}} includes the following components: - -* **{{< reuse "agw-docs/snippets/kgateway-capital.md" >}} control plane** - * Creates an Envoy configuration from multiple custom resources. - * Serves Envoy configurations using xDS. - * Validates Proxy configurations for the gateway proxy. -* **{{< reuse "agw-docs/snippets/kgateway-capital.md" >}} data plane (gateway proxy)** - * Receives and loads configuration from kgateway xDS. - * Proxies incoming traffic. - -## Pods and ports - -The components are instantiated by using pods and services. The following table lists the deployed pods and ports in use by each pod. - - -### Control plane ports - -| Pod | Port | Usage | -|-----|------|-------| -| {{< reuse "agw-docs/snippets/pod-name.md" >}} | 9976 | REST xDS | -| {{< reuse "agw-docs/snippets/pod-name.md" >}} | 9977 | xDS Server | - -### Gateway proxy ports - -{{< reuse "agw-docs/snippets/reserved-ports.md" >}} - - - - - diff --git a/assets/docs/pages/reference/versions.md b/assets/docs/pages/reference/versions.md deleted file mode 100644 index 5aa53aa62..000000000 --- a/assets/docs/pages/reference/versions.md +++ /dev/null @@ -1,72 +0,0 @@ -Review the following information about supported release versions for agentgateway. Agentgateway on Kubernetes runs with the [kgateway project](https://github.com/kgateway-dev/kgateway) control plane. - -## Supported versions - -| Kgateway | Release date | Kubernetes | Gateway API`*` | Envoy | Helm | Istio`†` | -|----------|--------------|------------|----------------|-------|------|----------| -| 2.2.x | 09 Feb 2026 | 1.31 - 1.35 | 1.4.x | Proxy 1.35, API v3 | >= 3.12 | 1.23 - 1.27 | -| 2.1.x | 10 Oct 2025 | 1.31 - 1.34 | 1.4.x | Proxy 1.35, API v3 | >= 3.12 | 1.23 - 1.27 | -| 2.0.x | 01 Apr 2025 | 1.27 - 1.31 | 1.2.x | Proxy 1.33, API v3 | >= 3.12 | 1.18 - 1.23 | - - - -`*` Gateway API versions: The agentgateway project is conformant to the Kubernetes Gateway API specification. For more details, see the [Gateway API docs](https://gateway-api.sigs.k8s.io/implementations/#agent-gateway-with-kgateway) and agentgateway conformance report per version, such as Gateway API [v1.4.0](https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports/v1.4.0/agentgateway-agentgateway). - -`†` Istio versions: Istio must run on a compatible version of Kubernetes. For example, Istio 1.27 is tested, but not supported, on Kubernetes 1.28. For more information, see the [Istio docs](https://istio.io/latest/docs/releases/supported-releases/). - - - -## Release cadence {#cadence} - -Stable builds for agentgateway on Kubernetes are released as minor versions approximately every three months. A stable branch for a minor version, such as {{< reuse "agw-docs/versions/short.md" >}}, is tagged from `main`, and stable builds are supported from that branch. - -## Release development {#release} - -New features for agentgateway are developed on `main` and available as development builds. Stable branches are created off of `main` for each minor version, such as `v2.0.x`. - -### Release process {#release-process} - -Development of a quality stable release on `main` typically follows this process: - -1. New feature development is suspended on `main`. -2. Release candidates are created, such as `{{< reuse "agw-docs/versions/short.md" >}}.0-rc1`, `{{< reuse "agw-docs/versions/short.md" >}}.0-rc2`, and so on. -3. A full suite of tests is performed for each release candidate. Testing includes all documented workflows, a test matrix of all supported platforms, and more. -4. Documentation for that release is prepared, vetted, and staged. -5. The stable minor version is released as part of a stable branch, such as `v2.0.x`. -6. Feature development on `main` is resumed. - -### Feature development on main branch {#release-main} - -Feature development is performed on the `main` branch. Upon a merge to `main`, a development build is automatically released. The current development release is `{{< reuse "agw-docs/versions/patch-dev.md" >}}`. - -{{< callout type="warning" >}} -Development releases are unstable, subject to change, and not recommended for production usage. -{{< /callout >}} - -### Backports to stable branches {#release-backport} - -New features are not developed on or backported to stable branches, such as `v2.0.x`. However, critical patches, bug fixes, and documentation fixes are backported as needed. - -## Experimental features in Gateway API {#experimental-features} - -{{< reuse "agw-docs/snippets/k8sgwapi-exp.md" >}} diff --git a/assets/docs/pages/reference/vulnerabilities.md b/assets/docs/pages/reference/vulnerabilities.md deleted file mode 100644 index b878f4e1d..000000000 --- a/assets/docs/pages/reference/vulnerabilities.md +++ /dev/null @@ -1,90 +0,0 @@ -Review how the kgateway project handles the lifecycle of Common Vulnerability and Exposures (CVEs). - -## Reports - -The kgateway project appreciates the efforts of our users in helping us to discover and resolve security vulnerabilities. The following sources are used to determine product exposure to CVEs: - -* The kgateway team scans kgateway components to detect vulnerabilities. -* The kgateway team participates in early disclosure and security workgroups of multiple backend communities. -* Users may share output from their own security scanning tools for analysis and response from the kgateway team. - -### 📨 Where to report - -To report a security vulnerability, email the private Google group `kgateway-vulnerability-reports@googlegroups.com`. - -### ✅ When to send a report - -Send a report when: - -* You discover that a kgateway component has a potential security vulnerability. -* You are unsure whether or how a vulnerability affects kgateway. - -### 🔔 Check before sending - -If in doubt, send a private message about potential vulnerabilities such as: - -* Any crash, especially in Envoy. -* Any potential Denial of Service (DoS) attack. - -### ❌ When NOT to send a report - -Do not send a report for vulnerabilities that are not part of the kgateway project, such as: - -* You want help configuring kgateway components for security purposes. -* You want help applying security related updates to your kgateway configuration or environment. -* Your issue is not related to security vulnerabilities. -* Your issue is related to base image dependencies, such as Envoy. - -## Evaluation - -The kgateway team evaluates vulnerability reports for: - -* Severity level, which can affect the priority of the fix -* Impact of the vulnerability on kgateway code as opposed to backend code -* Potential dependencies on third-party or backend code that might delay the remediation process - -The kgateway team strives to keep private any vulnerability information with us as part of the remediation process. We only share information on a need-to-know basis to address the issue. - -## Remediation - -Remediation of a CVE involves introducing a fix to the affected code and releasing the associated component. This development process might happen in private GitHub repositories to keep information secure and prevent broader exploitation of the vulnerability. - -## Disclosures - -The kgateway team discloses remediated vulnerabilities publicly. Additionally, you can join an early disclosure group to help address vulnerabilities earlier in the remediation process. - -### Public disclosure - -On the day for the remediation to be disclosed, the kgateway team takes steps that might include the following: - -* Merge changes from any private repositories into the public codebase -* Share security scan results for product images -* Publish a release and any corresponding documentation for mitigating the vulnerability -* Announce the remediated vulnerability in a public channel such as email or Slack - -### Early disclosure - -You can join a distribution list to get early disclosures of security vulnerability. This way, you can take action earlier in the process to help remediate the vulnerability and mitigate its effects in your environments. - -To request membership in the early disclosure group, email the private Google group `kgateway-vulnerability-reports@googlegroups.com`. In your request, indicate how you meet the following membership criteria. - -#### Membership criteria - -1. Contribute significantly to the kgateway project, such as by being a maintainer, release manager, or active feature developer. -2. Use kgateway in a way that justifies early disclosure of security vulnerabilities, such as redistributing kgateway or providing kgateway to many users outside your own organization. -3. Monitor the email that you provide for the early disclosure distribution list. -4. Participate in and attend meetings of the security working group. -5. Keep any information from the distribution list private and on a need-to-know basis. Information is only for purposes of remediating the vulnerability. If you share information beyond the scope of this policy, you must notify the distribution list, including details of what information was shared when and to whom, so the kgateway team can assess how to proceed. - -#### Membership removal - -You must actively meet the membership criteria to remain part of the early disclosure distribution list. If your organization stops meeting one or more of these criteria, you can be removed from the distribution list. - -#### Other membership notes - -Membership in the [Envoy security group](https://github.com/envoyproxy/envoy/blob/main/SECURITY.md#security-reporting-process) is a separate process. Because kgateway integrates closely with the Envoy project, you might also consider joining the Envoy early disclosure group. Even if not, you are still expected to abide by their embargo policy when a kgateway vulnerability relates to the Envoy project. - -## Updates and questions - -The kgateway team reserves the right to change this process. The kgateway team's security processes are reviewed regularly to ensure compliance with industry standards and the current security landscape. For questions or additional details, email the private Google group `kgateway-vulnerability-reports@googlegroups.com`. - diff --git a/assets/docs/pages/resiliency/circuit-breakers.md b/assets/docs/pages/resiliency/circuit-breakers.md deleted file mode 100644 index 6f43a656e..000000000 --- a/assets/docs/pages/resiliency/circuit-breakers.md +++ /dev/null @@ -1,81 +0,0 @@ -Set up protective limits on your gateway proxy to prevent your proxy from overwhelming slow or unhealthy upstream services. - -## About circuit breakers - -With circuit breakers, you can cap resources, such as the number of active connections, pending requests, concurrent requests, and retries, allowing Envoy to fail fast instead of letting queues grow unbounded. By shedding excess load early, circuit breakers help contain cascading failures, reduce latency under stress, and give upstream services time to recover, making them a key building block for resilient, self-protecting service meshes and gateways. - -For more information, see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/circuit_breaking). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - - -## Setup - -1. Create a BackendConfigPolicy that configures limits for the number of requests, connections, and retries for the httpbin app. - ```yaml - kubectl apply -f- <}} - -```sh -kubectl delete backendconfigpolicy httpbin-circuit-breakers -n httpbin -``` - diff --git a/assets/docs/pages/resiliency/connection.md b/assets/docs/pages/resiliency/connection.md deleted file mode 100644 index eef177c2d..000000000 --- a/assets/docs/pages/resiliency/connection.md +++ /dev/null @@ -1,186 +0,0 @@ -Configure and manage HTTP connections to an upstream service. - -## Supported HTTP connection settings - -You can use a BackendConfigPolicy to apply HTTP connection settings to a service in your cluster. These settings include general settings, such as connection timeouts or the maximum number of connections that an upstream service can receive. You can also configure settings for HTTP/2 and HTTP/1 requests. - -* [General connection settings](#general-settings) -* [HTTP protocol options](#http) -* [Additional HTTP 1.0 protocol options](#http1) - -### General connection settings {#general-settings} - -Configure the timeout and read/write buffer limits for a connection. - -```yaml -kind: BackendConfigPolicy -apiVersion: gateway.kgateway.dev/v1alpha1 -metadata: - name: httpbin-policy - namespace: gwtest -spec: - targetRefs: - - name: httpbin - group: "" - kind: Service - connectTimeout: 5s - perConnectionBufferLimitBytes: 1024 -``` - -| Setting | Description | -| -- | -- | -| `connectTimeout` | The timeout for new network connections to an upstream service. | -| `perConnectionBufferLimitBytes` | Set the size of the read and write buffer per connection. By default, the gateway has a maximum of 1MiB for the read and write buffer for each connection. For large requests that must be buffered and that exceed the default buffer limit, the gateway proxy either disconnects the connection to the downstream service if headers were already sent, or returns a 500 HTTP response code. To make sure that large requests can be sent and received, you can specify the maximum number of bytes that you want to allow to be buffered between the gateway and the downstream service. | - -### HTTP protocol options {#http} - -You can use a BackendConfigPolicy to configure additional connection options when handling upstream HTTP requests. Note that these options are applied to HTTP/1 and HTTP/2 requests. - -```yaml -kind: BackendConfigPolicy -apiVersion: gateway.kgateway.dev/v1alpha1 -metadata: - name: httpbin-policy - namespace: gwtest -spec: - targetRefs: - - name: httpbin - group: "" - kind: Service - commonHttpProtocolOptions: - idleTimeout: 10s - maxHeadersCount: 15 - maxStreamDuration: 30s - maxRequestsPerConnection: 100 -``` - -| Setting | Description | -| -- | -- | -| `idleTimeout` | The idle timeout for connections. The idle timeout is defined as the period in which there are no active requests. When the idle timeout is reached, the connection is closed. Note that request-based timeouts mean that HTTP/2 PINGs do not keep the connection alive. If not specified, the idle timeout defaults to 1 hour. To disable idle timeouts, explicitly set this field to 0. **Warning**: Disabling the timeout has a highly likelihood of yielding connection leaks, such as due to lost TCP FIN packets.| -| `maxHeadersCount` | The maximum number of headers that can be sent in a connection. If not specified, the number defaults to 100. Requests that exceed this limit receive a 431 response for HTTP/1 and cause a stream reset for HTTP/2. | -| `maxStreamDuration` | The total duration to keep alive an HTTP request/response stream. If the time limit is reached, the stream is reset independent of any other timeouts. If not specified, this value is not set. | -| `maxRequestsPerConnection` | The maximum number of requests that can be sent per connection. | - - -#### Additional HTTP 1.0 protocol options {#http1} - -The BackendConfigPolicy allows you to apply additional configuration to HTTP/1 connections. - -```yaml -kind: BackendConfigPolicy -apiVersion: gateway.kgateway.dev/v1alpha1 -metadata: - name: httpbin-policy - namespace: gwtest -spec: - targetRefs: - - name: httpbin - group: "" - kind: Service - http1ProtocolOptions: - enableTrailers: true - overrideStreamErrorOnInvalidHttpMessage: true - preserveHttp1HeaderCase: true -``` - -| Setting | Description | -| -- | -- | -| `enableTrailers` | Enables trailers for HTTP/1 requests. Trailers are headers that are sent after the request body is sent. By default, the HTTP/1 codec drops proxied trailers. | -| `overrideStreamErrorOnInvalidHttpMessage` | When set to false, the proxy terminates HTTP/1.1 connections when an invalid HTTP message is received, such as malformatted headers. When set to true, the proxy leaves the HTTP/1.1 connection open where possible. | -| `headerFormat` | By default, the proxy normalizes header keys to lowercase. Set to `PreserveCaseHeaderKeyFormat` to preserve the original casing after the request is proxied. Set to `properCaseHeaderKeyFormat` to capitalize the first character and any character following a special character if it's an alpha character. For example, `content-type` becomes `Content-Type`, and `foo$b#$are` becomes `Foo$B#$Are`. | - - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Configure backend connections - -1. Create a BackendConfigPolicy that applies connection configuration to the httpbin app. - ```yaml - kubectl apply -f- <}} 19000 - ``` - -3. Get the configuration of your gateway proxy as a config dump. - ```sh - curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json - ``` - -4. Open the config dump and find the `kube_httpbin_httpbin_8000` cluster. Verify that you see all the connection settings that you enabled in your BackendConfigPolicy. - - Example output - ```console - ... - "connect_timeout": "5s", - "per_connection_buffer_limit_bytes": 1024, - "metadata": {}, - "upstream_connection_options": { - }, - "typed_extension_protocol_options": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "common_http_protocol_options": { - "idle_timeout": "10s", - "max_headers_count": 15, - "max_stream_duration": "30s", - "headers_with_underscores_action": "REJECT_REQUEST", - "max_requests_per_connection": 100 - }, - "explicit_http_config": { - "http_protocol_options": { - "header_key_format": { - "stateful_formatter": { - "name": "envoy.http.stateful_header_formatters.preserve_case", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig" - } - } - }, - "enable_trailers": true, - "override_stream_error_on_invalid_http_message": true - } - } - } - } - ... - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete backendconfigpolicy httpbin-connection -n httpbin -``` - - - - - diff --git a/assets/docs/pages/resiliency/mirroring.md b/assets/docs/pages/resiliency/mirroring.md deleted file mode 100644 index ddcb35fc7..000000000 --- a/assets/docs/pages/resiliency/mirroring.md +++ /dev/null @@ -1,186 +0,0 @@ -Copy live production traffic to a shadow environment or service so that you can try out, analyze, and monitor new software changes before deploying them to production. - -## About traffic mirroring - -When releasing changes to a service, you want to finely control how those changes get exposed to users. This [progressive delivery](https://redmonk.com/jgovernor/2018/08/06/towards-progressive-delivery/) approach to releasing software allows you to reduce the blast radius, especially when changes introduce unintended behaviors. Traffic mirroring, also referred to as traffic shadowing, is one way to observe the impact of new software releases and test out new changes before you roll them out to production. Other approaches to slowly introduce new software include canary releases, A/B testing, or blue-green deployments. - -When you turn on traffic shadowing for an app, kgateway makes a copy of all incoming requests. Kgateway still proxies the request to the backing destination along the request path. It also sends a copy of the request asynchronously to another shadow destination. When a response or failure happens, copies are not generated. This way, you can test how traffic is handled by a new release or version of your app with zero production impact. You can also compare the shadowed results against the expected results. You can use this information to decide how to proceed with a canary release. - - - -To observe and analyze shadowed traffic, you can use a tool like [Open Diffy](https://github.com/opendiffy/diffy). This tool create diff-compares on the responses. You can use this data to verify that the response is correct and to detect API forward/backward compatibility problems. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up mirroring - -1. Edit the httpbin service that you deployed earlier to add the `version: v1` selector label. This label ensures that traffic to the v1 version is always routed to this instances of the httpbin app. - ```sh - kubectl patch service httpbin -n httpbin --type='json' -p='[{"op": "add", "path": "/spec/selector/version", "value": "v1"}]' - ``` - -2. Deploy another version (`v2`) of httpbin. You use this app to receive the mirrored traffic from httpbin `v1`. - ```yaml - kubectl apply -f- <}} - hostnames: - - mirror.example - rules: - - matches: - - path: - type: PathPrefix - value: / - filters: - - type: RequestMirror - requestMirror: - backendRef: - kind: Service - name: httpbin2 - port: 8000 - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -5. Send a few requests to the httpbin app on the `mirror.example` domain. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - for i in {1..5}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/headers \ - -H "host: mirror.example:8080"; done - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - for i in {1..5}; do curl -vi localhost:8080/headers \ - -H "host: mirror.example"; done - ``` - {{% /tab %}} - {{< /tabs >}} - -6. Get the logs of the httpbin app and verify that you see the requests that you sent. - ```sh - kubectl logs -l version=v1 -n httpbin - ``` - - Example output: - ``` - time="2025-03-14T19:43:01.1546" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.05 user_agent="curl/8.7.1" client_ip=10.0.8.23 - time="2025-03-14T19:43:02.3565" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.06 user_agent="curl/8.7.1" client_ip=10.0.8.23 - time="2025-03-14T19:43:03.0178" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.08 user_agent="curl/8.7.1" client_ip=10.0.6.27 - time="2025-03-14T19:43:03.3874" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.06 user_agent="curl/8.7.1" client_ip=10.0.8.23 - time="2025-03-14T19:43:03.6862" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.07 user_agent="curl/8.7.1" client_ip=10.0.6.27 - ``` - -7. Get the logs of the httpbin2 app and verify that you see the same requests. - ```sh - kubectl logs -l version=v2 -n httpbin - ``` - - Example output: - ``` - time="2025-03-14T19:43:01.1548" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.17 user_agent="curl/8.7.1" client_ip=10.0.8.23 - time="2025-03-14T19:43:02.3565" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.06 user_agent="curl/8.7.1" client_ip=10.0.8.23 - time="2025-03-14T19:43:03.0173" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.15 user_agent="curl/8.7.1" client_ip=10.0.6.27 - time="2025-03-14T19:43:03.3869" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.16 user_agent="curl/8.7.1" client_ip=10.0.8.23 - time="2025-03-14T19:43:03.6858" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.05 user_agent="curl/8.7.1" client_ip=10.0.6.27 - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete service httpbin2 -n httpbin -kubectl delete deployment httpbin2 -n httpbin -kubectl delete httproute httpbin-mirror -n httpbin -``` - - diff --git a/assets/docs/pages/resiliency/outlier-detection.md b/assets/docs/pages/resiliency/outlier-detection.md deleted file mode 100644 index c421e4b04..000000000 --- a/assets/docs/pages/resiliency/outlier-detection.md +++ /dev/null @@ -1,243 +0,0 @@ -Configure passive health checks and remove unhealthy hosts from the load balancing pool with an outlier detection policy. - -## About outlier detection - -Outlier detection is an important part of building resilient apps. An outlier detection policy sets up several conditions, such as retries and ejection percentages, that {{< reuse "agw-docs/snippets/kgateway.md" >}} uses to determine if a service is unhealthy. In case an unhealthy service is detected, the outlier detection policy defines how the service is removed from the pool of healthy destinations to send traffic to. Your apps then have time to recover before they are added back to the load-balancing pool and checked again for consecutive errors. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up outlier detection - -1. Scale the httpbin app to 2 replicas. - ```sh - kubectl scale deploy/httpbin -n httpbin --replicas=2 - ``` - -2. Verify that you see two replicas of the httpbin app. - ```sh - kubectl get pods -n httpbin - ``` - - Example output: - ```console - NAME READY STATUS RESTARTS AGE - httpbin-577649ddb-lsgp8 2/2 Running 0 31d - httpbin-577649ddb-q9b92 2/2 Running 0 3s - ``` - -3. Send a few requests to the httpbin app. Because both httpbin replicas are exposed under the same service, requests are automatically load balanced between all healthy replicas. - {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}} - {{% tab tabName="Cloud Provider Load Balancer" %}} - ```sh - for i in {1..5}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" ; done - ``` - {{% /tab %}} - {{% tab tabName="Port forward for local testing" %}} - ```sh - for i in {1..5}; do curl -vi localhost:8080/status/200 -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output for one request: - ```console - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - < - .... - ``` - -4. Review the logs for both replicas. Verify that you see log entries for the 5 requests spread across both replicas. For example, one replica might have 2 log entries and the other one 3. - ```sh - kubectl logs -l app=httpbin -n httpbin -f --prefix - ``` - - Example output for one request: - ```console - time="2025-09-15T21:11:52.8514" status=200 method="GET" uri="/status/200" - size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.X.X.XX - ``` - -5. Create a BackendConfigPolicy with your outlier detection policy. The following example ejects an unhealthy upstream host for one hour if the host returns one 5XX HTTP response code. Note that the maximum number of ejected hosts is set to 80%. Because of that, only one replica of httpbin can be ejected at any given time. If two replicas were ejected, that would exceed the 80% maximum threshold (because the two replicas equal 100%). - ```yaml - kubectl apply -f- <}} - {{% tab tabName="Cloud Provider Load Balancer" %}} - ```sh - for i in {1..5}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" ; done - ``` - {{% /tab %}} - {{% tab tabName="Port forward for local testing" %}} - ```sh - for i in {1..5}; do curl -vi localhost:8080/status/200 -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{< /tabs >}} - -7. Force one httpbin replica to return a 503 HTTP response code. This response code triggers the outlier detection policy and automatically removes this httpbin replica from the load balancing pool for 1 hour. - {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}} - {{% tab tabName="Cloud Provider Load Balancer" %}} - ```sh - curl -vik http://$INGRESS_GW_ADDRESS:8080/status/503 -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/503 -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console - * Request completely sent off - < HTTP/1.1 503 Service Unavailable - HTTP/1.1 503 Service Unavailable - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - ... - ``` - -8. Send a few more requests to the httpbin app. In the logs for both replicas, verify that all requests now only go to the instance that is still considered healthy. - {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}} - {{% tab tabName="Cloud Provider Load Balancer" %}} - ```sh - for i in {1..5}; do curl http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" ; done - ``` - {{% /tab %}} - {{% tab tabName="Port forward for local testing" %}} - ```sh - for i in {1..5}; do curl -vi localhost:8080/status/200 -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{< /tabs >}} - - Example log output of the healthy instance: - ```console - time="2025-09-15T21:19:02.0808" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.X.X.XX - time="2025-09-15T21:19:02.2452" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.X.X.XX - time="2025-09-15T21:19:02.4053" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.X.X.XX - time="2025-09-15T21:19:02.6067" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.01 user_agent="curl/8.7.1" client_ip=10.X.X.XX - time="2025-09-15T21:19:02.7604" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.01 user_agent="curl/8.7.1" client_ip=10.X.X.XX - ``` - - Example log output of the unhealthy instance: - ```console - time="2025-09-15T21:17:25.4035" status=503 method="GET" uri="/status/503" size_bytes=0 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.X.X.XX - ``` - -9. Force the second httpbin replica to return a 503 HTTP response code. Note that the outlier detection only allows 80% of all upstream hosts to be ejected at a given time. Since both replicas would equal 100%, the outlier detection does not remove the host from the load balancing pool. The instance is still considered healthy and can receive requests. In your log output for the healthy instance, verify that you see the log entry for the 503 request. - {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}} - {{% tab tabName="Cloud Provider Load Balancer" %}} - ```sh - curl -vik http://$INGRESS_GW_ADDRESS:8080/status/503 -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/503 -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example log output of the healthy instance: - ```console - time="2025-09-15T21:20:27.1117" status=503 method="GET" uri="/status/503" size_bytes=0 duration_ms=0.02 user_agent="curl/8.7.1" client_ip=10.X.X.XX - ``` - -10. Send a few more requests to the httpbin app. In the logs for both replicas, verify that all requests are still routed to the same instance as the instance was not removed from the load balancing pool. - {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}} - {{% tab tabName="Cloud Provider Load Balancer" %}} - ```sh - for i in {1..5}; do curl http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" ; done - ``` - {{% /tab %}} - {{% tab tabName="Port forward for local testing" %}} - ```sh - for i in {1..5}; do curl -vi localhost:8080/status/200 -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{< /tabs >}} - - Example log output for the healthy instance: - ```console - # Previous log output - time="2025-09-15T21:20:27.1117" status=503 method="GET" uri="/status/503" size_bytes=0 duration_ms=0.02 user_agent="curl/8.7.1" client_ip=10.0.9.76 - # New log output - time="2025-09-15T21:25:11.4236" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.02 user_agent="curl/8.7.1" client_ip=10.0.15.215 - time="2025-09-15T21:25:11.5833" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.0.9.76 - time="2025-09-15T21:25:11.7473" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.0.9.76 - time="2025-09-15T21:25:11.9098" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.01 user_agent="curl/8.7.1" client_ip=10.0.15.215 - time="2025-09-15T21:25:12.0824" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.01 user_agent="curl/8.7.1" client_ip=10.0.9.76 - -11. Port-forward the Gateway pod on port 19000. - ```sh - kubectl port-forward deploy/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000 - ``` - -12. Open the [stats Prometheus](http://localhost:19000/stats/prometheus) endpoint and look for the following metrics. - * `envoy_cluster_outlier_detection_ejections_consecutive_5xx`: The number of times a host qualified for ejection. In this example, the number is 2, because both hosts qualified for ejection. - * `envoy_cluster_outlier_detection_ejections_enforced_consecutive_5xx`: The number of times an ejection was forced. In this example, the number is 1, because the second host instance could not be ejected as it did not meet the maximum percentage setting in your outlier policy. - - Example output: - ```console - envoy_cluster_outlier_detection_ejections_consecutive_5xx{envoy_cluster_name="kube_httpbin_httpbin_8000"} 2 - envoy_cluster_outlier_detection_ejections_enforced_consecutive_5xx{envoy_cluster_name="kube_httpbin_httpbin_8000"} 1 - ``` - -## Cleanup - -1. Scale down the httpbin app to 1 replica. - ```sh - kubectl scale deploy/httpbin -n httpbin --replicas=1 - ``` - -2. Remove the BackendConfigPolicy. - ```sh - kubectl delete backendconfigpolicy httpbin-policy -n httpbin - ``` - - - - - diff --git a/assets/docs/pages/resiliency/retry/about.md b/assets/docs/pages/resiliency/retry/about.md deleted file mode 100644 index c48cd31ab..000000000 --- a/assets/docs/pages/resiliency/retry/about.md +++ /dev/null @@ -1,16 +0,0 @@ -A retry is the number of times a request is retried if it fails. This setting can be useful to avoid your apps from failing if they are temporarily unavailable. With retries, calls are retried a certain number of times before they are considered failed. Retries can enhance your app's availability by making sure that calls don't fail permanently because of transient problems, such as a temporarily overloaded service or network. - -## Configuration options - -You can configure retries by using a Kubernetes Gateway API-native configuration or a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} as shown in the following table - - -| Type of timeout| Description | Configured via | Attach to | -| -- | -- | -- | --- | -| [Request retries]({{< link-hextra path="/resiliency/retry/retry/" >}}) | Specify the number of times and duration for the gateway to try a connection to an unresponsive backend service. |
  • HTTPRoute
  • {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
|
  • HTTPRoute
  • HTTPRoute rule
  • Gateway listener ({{< reuse "agw-docs/snippets/trafficpolicy.md" >}} only)
| -| [Per-try timeout]({{< link-hextra path="/resiliency/retry/per-try-timeout/" >}}) | Set a shorter timeout for retries than the overall request timeout. |
  • HTTPRoute
  • {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
|
  • HTTPRoute
  • HTTPRoute rule
  • Gateway listener ({{< reuse "agw-docs/snippets/trafficpolicy.md" >}} only)
| - - - - - diff --git a/assets/docs/pages/resiliency/retry/per-try-timeout.md b/assets/docs/pages/resiliency/retry/per-try-timeout.md deleted file mode 100644 index a61d1d81a..000000000 --- a/assets/docs/pages/resiliency/retry/per-try-timeout.md +++ /dev/null @@ -1,286 +0,0 @@ -Set separate timeouts for retries. - -## About per-try timeouts - -The per-retry timeout allows you to set a timeout for retried requests. If the timeout expires, Envoy cancels the retry attempt and immediately retries on another upstream host. - -By default, Envoy has a default overall request timeout of 15 seconds. A request timeout represents the time Envoy waits for the entire request to complete, including retries. Without a per-try timeout, retries might take longer than the overall request timeout, and therefore might not be executed as the request times out before the retry attempts can be performed. You can configure a larger [request timeout]({{< link-hextra path="/resiliency/timeouts/request/" >}}) to account for this case. However, you can also define timeouts for each retry so that you can protect against slow retry attempts from consuming the entire request timeout. - - -Note that if you configured a global request timeout, the per-try timeout must be less than the global request timeout. - -Per-try timeouts can be configured on an HTTPRoute directly. To enable per-try timeouts on a Gateway listener level, use a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} instead. - -{{< callout type="warning" >}} -{{< reuse "agw-docs/versions/warn-experimental.md" >}} -{{< /callout >}} - -{{< callout >}} -{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}} -{{< /callout >}} - - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up per-retry timeouts - -1. Install the experimental Kubernetes Gateway API CRDs. - - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml - ``` - -2. Configure the per-retry timeout. You can apply the timeout to an HTTPRoute, or Gateway listener. - {{< tabs tabTotal="3" items="HTTPRoute (Kubernetes GW API),HTTPRoute (TrafficPolicy),Gateway listener" >}} - {{% tab tabName="HTTPRoute (Kubernetes GW API)" %}} - Use the `timeouts.backendRequest` field to configure the per-try timeout. Note that you must set a retry policy also to configure a per-try timeout. - ```yaml - kubectl apply -f- <}} - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - retry: - attempts: 3 - backoff: 1s - timeouts: - backendRequest: 5s - EOF - ``` - {{% /tab %}} - {{% tab tabName="HTTPRoute (EnterpriseKgatewayTrafficPolicy)" %}} - 1. Create an HTTPRoute to route requests along the `retry.example` domain to the httpbin app. Note that you add a name `timeout` to your HTTPRoute rule so that you can configure the per-try timeout for that rule later. - ```yaml - kubectl apply -f- <}} - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - name: timeout - EOF - ``` - 2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to configure the per-try timeout. In this example, the per-try timeout is set to 5 seconds and assigned to the `timeout` HTTPRoute rule. Note that you must set a retry policy also to apply a per-try timeout. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: retry - namespace: httpbin - spec: - targetRefs: - - kind: HTTPRoute - group: gateway.networking.k8s.io - name: retry - sectionName: timeout - retry: - attempts: 3 - perTryTimeout: 5s - statusCodes: - - 517 - EOF - ``` - - {{% /tab %}} - {{% tab tabName="Gateway listener" %}} - 1. Create an HTTPRoute to route requests along the `retry.example` domain to the httpbin app. - ```yaml - kubectl apply -f- <}} - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - EOF - ``` - 2. Create {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to configure the per-try timeout. In this example, the per-try timeout is set to 5 seconds and assigned to the `http` Gateway listener that you set up as part of the [before you begin](#before-you-begin) section. Note that you must set a retry policy also to apply a per-try timeout. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: retry - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - kind: Gateway - group: gateway.networking.k8s.io - name: http - sectionName: http - retry: - attempts: 2 - perTryTimeout: 5s - statusCodes: - - 517 - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Send a request to the httpbin app along the `retry.example` domain. Verify that the `X-Envoy-Expected-Rq-Timeout-Ms` header is set to the 5 second timeout that you configured. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: retry.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/anything -H "host: retry.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[14,15]} - ... - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "retry.example" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "5000" - ], - "X-Envoy-External-Address": [ - "127.0.0.1" - ], - "X-Forwarded-For": [ - "10.244.0.55" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "9178dc39-297f-438a-8bd9-4e8203c06b59" - ] - }, - ``` - -3. Verify that the gateway proxy is configured with the per-try timeout. - 1. Port-forward the gateway proxy on port 19000. - - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000 - ``` - - 2. Get the configuration of your gateway proxy as a config dump. - - ```sh - curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json - ``` - - 3. Open the config dump and find the route configuration for the `kube_default_reviews_9080` Envoy cluster on the `listener~8080~retry_example` virtual host. Verify that the retry policy is set as you configured it. - - Example `jq` command: - ```sh - jq '.configs[] | select(."@type" == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump") | .dynamic_route_configs[].route_config.virtual_hosts[] | select(.routes[].route.cluster == "kube_httpbin_httpbin_8000")' gateway-config.json - ``` - - Example output: - ```console {hl_lines=[12]} - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "kube_httpbin_httpbin_8000", - "timeout": "5s", - "retry_policy": { - "retry_on": "cancelled,connect-failure,refused-stream,retriable-headers,retriable-status-codes,unavailable", - "num_retries": 3, - "per_try_timeout": "5s", - "retry_back_off": { - "base_interval": "1s" - } - }, - "cluster_not_found_response_code": "INTERNAL_SERVER_ERROR" - }, - "name": "listener~8080~retry_example-route-0-httproute-retry-httpbin-0-0-matcher-0" - } - ] - ``` - - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} retry -n httpbin -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} retry -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute retry -n httpbin -``` - - - - - diff --git a/assets/docs/pages/resiliency/retry/retry.md b/assets/docs/pages/resiliency/retry/retry.md deleted file mode 100644 index c8f561b25..000000000 --- a/assets/docs/pages/resiliency/retry/retry.md +++ /dev/null @@ -1,496 +0,0 @@ -Specify the number of times and duration for the gateway to try a connection to an unresponsive backend service. -You might commonly use retries alongside [Timeouts]({{< link-hextra path="/resiliency/timeouts/">}}) to ensure that your apps are available even if they are temporarily unavailable. - -{{< callout type="warning" >}} -{{< reuse "agw-docs/versions/warn-experimental.md" >}} -{{< /callout >}} - -## About request retries - -A request retry is the number of times a request is retried if it fails. This setting can be useful to avoid your apps from failing if they are temporarily unavailable. With retries, calls are retried a certain number of times before they are considered failed. Retries can enhance your app's availability by making sure that calls don't fail permanently because of transient problems, such as a temporarily overloaded service or network. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-x-channel.md" >}} - -## Step 1: Set up your environment for retries - -To use retries, you need to install the experimental channel. You can also set up two things that help you test retries: a sample app that can simulate a failure and an access log policy that tracks whether the request was retried. - -1. Install the experimental Kubernetes Gateway API CRDs. - - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml - ``` - -2. Install a sample app that you can simulate a failure for, such as adding a `sleep` command to the [Bookinfo reviews app](https://istio.io/latest/docs/examples/bookinfo/). - - ```sh - kubectl apply -f- <}}) and the [Envoy access logs response flags docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#response-flags). - - ```yaml - kubectl apply -f- <}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - accessLog: - - fileSink: - path: /dev/stdout - jsonFormat: - start_time: "%START_TIME%" - method: "%REQ(:METHOD)%" - path: "%REQ(:PATH)%" - response_code: "%RESPONSE_CODE%" - response_flags: "%RESPONSE_FLAGS%" - upstream_host: "%UPSTREAM_HOST%" - upstream_cluster: "%UPSTREAM_CLUSTER%" - EOF - ``` - -## Step 2: Set up request retries {#setup-retries} - -Set up retries to the reviews app. - -1. Create an HTTPRoute resource to specify your retry rules. You can apply the retry policy on an HTTPRoute, HTTPRoute rule, or Gateway listener. - {{< tabs tabTotal="3" items="HTTPRoute (Kubernetes GW API),HTTPRoute and rule (TrafficPolicy),Gateway listener" >}} - {{% tab tabName="HTTPRoute (Kubernetes GW API)" %}} - ```yaml - kubectl apply -f- <}} - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - group: "" - kind: Service - name: reviews - port: 9080 - retry: - attempts: 3 - backoff: 1s - timeouts: - request: "20s" - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - | Field | Description | - |-------|-------------| - | `hostnames` | The hostnames to match the request, such as `retry.example`. | - | `parentRefs` | The gateway to which the request is sent. In this example, you select the `http` gateway that you set up before you began. | - | `rules` | The rules to apply to requests. | - | `matches` | The path to match the request. In this example, you match any requests to the reviews app with `/`. | - | `path` | The path to match the request. In this example, you match the request to the `/reviews/1` path. | - | `backendRefs` | The backend service to which the request is sent. In this example, you select the `reviews` service that you set up in the previous step. | - | `retry.attempts` | The number of times to retry the request. In this example, you retry the request 3 times. | - | `retry.backoff` | The duration to wait before retrying the request. In this example, you wait 1 second before retrying the request. | - | `timeouts` | The duration to wait before the request times out. This value is higher than the backoff value so that the request can be retried before it times out. In this example, you set the timeout to 20 seconds. | - {{% /tab %}} - {{% tab tabName="HTTPRoute (EnterpriseKgatewayTrafficPolicy)" %}} - 1. Create an HTTPRoute that routes requests along the `retry.example` domain to the reviews app. Note that you add a name `timeout` to your HTTPRoute rule so that you can later attach the retry policy to that rule. - ```yaml - kubectl apply -f- <}} - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - group: "" - kind: Service - name: reviews - port: 9080 - name: timeout - EOF - ``` - 2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that applies a retry policy to the `timeout` HTTPRoute rule. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: retry - namespace: default - spec: - targetRefs: - - kind: HTTPRoute - group: gateway.networking.k8s.io - name: retry - sectionName: timeout - retry: - attempts: 3 - backoffBaseInterval: 1s - retryOn: - - 5xx - - unavailable - timeouts: - request: 20s - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - | Field | Description | - |-------|-------------| - | `targetRefs.sectionName` | Select the HTTPRoute rule that you want to apply the policy to. | - | `retry.attempts` | The number of times to retry the request. In this example, you retry the request 3 times. | - | `retry.backoffBaseInterval` | The duration to wait before retrying the request. In this example, you wait 1 second before retrying the request. | - | `retry.retryOn` | The condition that must be met for the gateway proxy to retry the request. In this example, the request is retried if a 5xx HTTP response code is returned or if the upstream service is unavailable. | - | `timeouts.request` | The duration to wait before the request times out. This value is higher than the backoff value so that the request can be retried before it times out. In this example, you set the timeout to 20 seconds. | - - {{% /tab %}} - {{% tab tabName="Gateway listener" %}} - 1. Create an HTTPRoute that routes requests along the `retry.example` domain to the reviews app. - ```yaml - kubectl apply -f- <}} - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - group: "" - kind: Service - name: reviews - port: 9080 - EOF - ``` - 2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that applies a retry policy to the `http` Gateway listener. You set up this Gateway in the [before you begin](#before-you-begin) section. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: retry - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - kind: Gateway - group: gateway.networking.k8s.io - name: http - sectionName: http - retry: - attempts: 3 - backoffBaseInterval: 1s - retryOn: - - 5xx - - unavailable - EOF - ``` - - | Field | Description | - |-------|-------------| - | `targetRefs.sectionName` | Select the Gateway listener that you want to apply the policy to. | - | `retry.attempts` | The number of times to retry the request. In this example, you retry the request 3 times. | - | `retry.backoffBaseInterval` | The duration to wait before retrying the request. In this example, you wait 1 second before retrying the request. | - | `retry.retryOn` | The condition that must be met for the gateway proxy to retry the request. In this example, the request is retried if a 5xx HTTP response code is returned or if the upstream service is unavailable. | - | `timeouts.request` | The duration to wait before the request times out. This value is higher than the backoff value so that the request can be retried before it times out. In this example, you set the timeout to 20 seconds. | - {{% /tab %}} - {{< /tabs >}} - -2. Verify that the gateway proxy is configured to retry the request. - - 1. Port-forward the gateway proxy on port 19000. - - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000 - ``` - - 2. Get the configuration of your gateway proxy as a config dump. - - ```sh - curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json - ``` - - 3. Open the config dump and find the route configuration for the `kube_default_reviews_9080` Envoy cluster on the `listener~8080~retry_example` virtual host. Verify that the retry policy is set as you configured it. - - Example `jq` command: - - ```sh - jq '.configs[] | select(."@type" == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump") | .dynamic_route_configs[].route_config.virtual_hosts[] | select(.routes[].route.cluster == "kube_default_reviews_9080")' gateway-config.json - ``` - - Example output: - ```json - { - "name": "listener~8080~retry_example", - "domains": [ - "retry.example" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "kube_default_reviews_9080", - "timeout": "20s", - "retry_policy": { - "retry_on": "gateway-error,connect-failure,reset", - "num_retries": 3, - "per_try_timeout": "1s", - "retriable_status_codes": [ - 404 - ], - "retry_back_off": { - "base_interval": "0.025s" - } - }, - "cluster_not_found_response_code": "INTERNAL_SERVER_ERROR" - }, - "name": "listener~8080~retry_example-route-0-httproute-retry-default-0-0-matcher-0" - } - ] - } - ... - ``` - -3. Send a request to the reviews app. Verify that the request succeeds. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/reviews/1 -H "host: retry.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/reviews/1 -H "host: retry.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output for a successful response: - - ``` - HTTP/1.1 200 OK - ... - {"id": "1","podname": "reviews-v1-598b896c9d-l7d8l","clustername": "null","reviews": [{ "reviewer": "Reviewer1", "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!"},{ "reviewer": "Reviewer2", "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare."}]} - ``` - -4. Check the gateway's access logs to verify that the request was not retried. - - ```sh - kubectl logs -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l gateway.networking.k8s.io/gateway-name=http | tail -1 | jq - ``` - - Example output: Note that the `response_flags` field is `-`, which means that the request was not retried. - - ```json - { - "method": "GET", - "path": "/reviews/1", - "response_code": 200, - "response_flags": "-", - "start_time": "2025-06-16T17:24:04.268Z", - "upstream_cluster": "kube_default_reviews_9080", - "upstream_host": "10.244.0.24:9080" - } - ``` - -## Step 3: Trigger a retry {#trigger-retry} - -Simulate a failure for the reviews app so that you can verify that the request is retried. - -1. Send the reviews app to sleep, to simulate an app failure. - - ```sh - kubectl -n default patch deploy reviews-v1 --patch '{"spec":{"template":{"spec":{"containers":[{"name":"reviews","command":["sleep","20h"]}]}}}}' - ``` - -2. Send another request to the reviews app. This time, the request fails. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/reviews/1 -H "host: retry.example:80" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/reviews/1 -H "host: retry.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ``` - HTTP/1.1 503 Service Unavailable - ... - upstream connect error or disconnect/reset before headers. retried and the latest reset reason: remote connection failure, transport failure reason: delayed connect error: Connection refused - ``` - -3. Check the gateway's access logs to verify that the request was retried. - - ```sh - kubectl logs -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l gateway.networking.k8s.io/gateway-name=http | tail -1 | jq - ``` - - Example output: Note that the `response_flags` field now has values as follows: - - * `URX` means `UpstreamRetryLimitExceeded`, which verifies that the request was retried. - * `UF` means `UpstreamOverflow`, which verifies that the request failed. - - ```json - { - "method": "GET", - "path": "/reviews/1", - "response_code": 503, - "response_flags": "URX,UF", - "start_time": "2025-06-16T17:26:07.287Z", - "upstream_cluster": "kube_default_reviews_9080", - "upstream_host": "10.244.0.25:9080" - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the HTTPRoute resource. - - ```sh - kubectl delete httproute retry -n default - ``` - -2. Delete the reviews app. - - ```sh - kubectl delete deploy reviews-v1 -n default - kubectl delete svc reviews -n default - kubectl delete sa bookinfo-reviews -n default - ``` - -3. Delete the access log policy. - - ```sh - kubectl delete httplistenerpolicy access-logs -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -4. Delete the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. - ```sh - kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} retry - kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} retry -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - - - - diff --git a/assets/docs/pages/resiliency/tcp-keepalive.md b/assets/docs/pages/resiliency/tcp-keepalive.md deleted file mode 100644 index 285f99b1f..000000000 --- a/assets/docs/pages/resiliency/tcp-keepalive.md +++ /dev/null @@ -1,78 +0,0 @@ -Manage idle and stale connections with TCP keepalive. - -## About TCP keepalive - -With keepalive, the kernel sends probe packets with only an acknowledgement flag (ACK) to the TCP socket of the destination after the connection was idle for a specific amount of time. This way, the connection does not have to be re-established repeatedly, which could otherwise lead to latency spikes. If the destination returns the packet with an acknowledgement flag (ACK), the connection is determined to be alive. If not, the probe can fail a certain number of times before the connection is considered stale. {{< reuse "agw-docs/snippets/kgateway-capital.md" >}} can then close the stale connection, which can help avoid longer timeouts and retries on broken or stale connections. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up TCP keepalive - -1. Create a BackendConfigPolicy that applies TCP keepalive settings to the httpbin service. - ```yaml - kubectl apply -f- <}} 19000 - ``` - -3. Get the configuration of your gateway proxy as a config dump. - ```sh - curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json - ``` - -4. Open the config dump and find the `kube_httpbin_httpbin_8000` cluster. Verify that you see all the connection settings that you enabled in your BackendConfigPolicy. - - Example output - ```console {hl_lines=[5,6,7,8]} - ... - "connect_timeout": "5s", - "metadata": {}, - "upstream_connection_options": { - "tcp_keepalive": { - "keepalive_probes": 3, - "keepalive_time": 30, - "keepalive_interval": 5 - } - } - }, - ... - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete backendconfigpolicy httpbin-keepalive -n httpbin -``` - - - - - diff --git a/assets/docs/pages/resiliency/timeouts/about.md b/assets/docs/pages/resiliency/timeouts/about.md deleted file mode 100644 index 9d230174d..000000000 --- a/assets/docs/pages/resiliency/timeouts/about.md +++ /dev/null @@ -1,19 +0,0 @@ -A timeout is the amount of time ([duration](https://protobuf.dev/reference/protobuf/google.protobuf/#duration)) that the gateway waits for replies from a backend service before the service is considered unavailable. This setting can be useful to avoid your apps from hanging or to fail if no response is returned in a specific timeframe. With timeouts, calls either succeed or fail within a predictable timeframe. - -The time an app needs to process a request can vary a lot. For this reason, applying the same timeout across services can cause a variety of issues. For example, a timeout that is too long can result in excessive latency from waiting for replies from failing services. On the other hand, a timeout that is too short can result in calls failing unnecessarily while waiting for an operation that needs responses from multiple services. - -## Configuration options - -You can configure different types of timeouts by using a Kubernetes Gateway API-native configuration, HTTPListenerPolicy, or a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} as shown in the following table. - -| Type of timeout| Description | Configured via | Attach to | -| -- | -- | -- | --- | -| [Request timeout]({{< link-hextra path="/resiliency/timeouts/request/" >}}) | Request timeouts configure the time Envoy allows for the entire request stream to be received from the client. |
  • HTTPRoute
  • {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
|
  • HTTPRoute
  • HTTPRoute rule
| -| [Idle timeout]({{< link-hextra path="/resiliency/timeouts/idle/" >}}) | An idle timeout is the time when Envoy terminates the connection to a downstream or upstream service if there no active streams.| HTTPListenerPolicy | Gateway | -| [Idle stream timeout]({{< link-hextra path="/resiliency/timeouts/idle-stream/" >}}) | An idle stream timeout is the time Envoy allows a stream to exist without activity before it is terminated. | {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} |
  • HTTPRoute
  • HTTPRoute rule
| -| [Per-try timeout]({{< link-hextra path="/resiliency/retry/per-try-timeout" >}}) | Set a shorter timeout for retries than the overall request timeout. |
  • HTTPRoute
  • {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
|
  • HTTPRoute
  • HTTPRoute rule
  • Gateway listener ({{< reuse "agw-docs/snippets/trafficpolicy.md" >}} only)
| - - - - - diff --git a/assets/docs/pages/resiliency/timeouts/idle-stream.md b/assets/docs/pages/resiliency/timeouts/idle-stream.md deleted file mode 100644 index f1bfc24ee..000000000 --- a/assets/docs/pages/resiliency/timeouts/idle-stream.md +++ /dev/null @@ -1,91 +0,0 @@ -Customize the default idle stream timeout of 5 minutes (300s). - -## About idle stream timeouts - -By default, Envoy closes all idle request and response streams after 5 minutes if no data is sent or received and returns a 408 Request Timeout HTTP response code. Idle stream timeouts are different from request timeouts. Request timeouts configure the time Envoy allows for the entire request stream to be received from the client. An idle stream timeout on the other hand is the time Envoy allows a stream to exist without activity before it is terminated. Idle stream timeouts are recommended to protect against clients that stall or that open the stream and never send any data. - -You can change the default idle stream timeout setting with a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. While idle streams are a concept in the HTTP/2 and HTTP/3 protocols, Envoy also maps an HTTP/1 request to a stream. Because of that, you can apply idle stream timeouts to HTTP/1 traffic too. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up idle stream timeouts - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your idle stream timeout settings. If you have an HTTPRoute with multiple HTTPRoute rules, you can use the `targetRefs.sectionName` to apply the timeout to a specific HTTPRoute rule. In this example, you apply the policy to the httpbin HTTPRoute. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: timeout - namespace: httpbin - spec: - targetRefs: - - kind: HTTPRoute - group: gateway.networking.k8s.io - name: httpbin - timeouts: - streamIdle: 600s - EOF - ``` - -2. Verify that the gateway proxy is configured with the idle stream timeout. - 1. Port-forward the gateway proxy on port 19000. - - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000 - ``` - - 2. Get the configuration of your gateway proxy as a config dump. - - ```sh - curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json - ``` - - 3. Open the config dump and find the route configuration for the `kube_httpbin_httpbin_8000` Envoy cluster on the `listener~8080~www_example_com` virtual host. Verify that the timeout policy is set as you configured it. - - Example `jq` command: - ```sh - jq '.configs[] | select(."@type" == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump") | .dynamic_route_configs[].route_config.virtual_hosts[] | select(.routes[].route.cluster == "kube_httpbin_httpbin_8000")' gateway-config.json - ``` - - Example output: - ```console{hl_lines=[9]} - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "kube_httpbin_httpbin_8000", - "cluster_not_found_response_code": "INTERNAL_SERVER_ERROR", - "idle_timeout": "600s" - }, - "metadata": { - "filter_metadata": { - "merge.TrafficPolicy.gateway.kgateway.dev": { - "timeouts": [ - "gateway.kgateway.dev/TrafficPolicy/httpbin/timeout" - ] - } - } - }, - "name": "listener~8080~www_example_com-route-0-httproute-httpbin-httpbin-0-0-matcher-0" - } - ], - ``` - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} timeout -n httpbin -``` - - - - - diff --git a/assets/docs/pages/resiliency/timeouts/idle.md b/assets/docs/pages/resiliency/timeouts/idle.md deleted file mode 100644 index e83893a9a..000000000 --- a/assets/docs/pages/resiliency/timeouts/idle.md +++ /dev/null @@ -1,96 +0,0 @@ -Customize the default idle timeout of 1 hour (3600s). - -## About idle timeouts - -By default, Envoy terminates the connection to a downstream or upstream service after one hour if there are no active streams. You can customize this idle timeout with an HTTPListenerPolicy. The policy updates the [`common_http_protocol_options` setting in Envoy](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/upstreams/http/v3/http_protocol_options.proto). - -Note that the idle timeout configures the timeout for the entire connection from a downstream service to the gateway proxy, and to the upstream service. If you want to set a timeout for a single stream, configure the [idle stream timeout]({{< link-hextra path="/resiliency/timeouts/idle-stream/" >}}) instead. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up idle timeouts - -1. Create an HTTPListenerPolicy with your idle timeout configuration. In this example, you apply an idle timeout of 30 seconds. - - ```yaml - kubectl apply -f- <}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - idleTimeout: "30s" - EOF - ``` - -2. Verify that the gateway proxy is configured with the idle timeout. - 1. Port-forward the gateway proxy on port 19000. - - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000 - ``` - - 2. Get the configuration of your gateway proxy as a config dump. - - ```sh - curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json - ``` - - 3. Open the config dump and find the `http_connection_manager` configuration. Verify that the timeout policy is set as you configured it. - - Example `jq` command: - ```sh - jq '.configs[] - | select(."@type" == "type.googleapis.com/envoy.admin.v3.ListenersConfigDump") - | .dynamic_listeners[].active_state.listener.filter_chains[].filters[] - | select(.name == "envoy.filters.network.http_connection_manager")' gateway-config.json - ``` - - Example output: - ```console{hl_lines=[25]} - { - "name": "envoy.filters.network.http_connection_manager", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "stat_prefix": "http", - "rds": { - "config_source": { - "ads": {}, - "resource_api_version": "V3" - }, - "route_config_name": "listener~8080" - }, - "http_filters": [ - { - "name": "envoy.filters.http.router", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "use_remote_address": true, - "normalize_path": true, - "merge_slashes": true, - "common_http_protocol_options": { - "idle_timeout": "30s" - } - } - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httplistenerpolicy idle-time -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` - - diff --git a/assets/docs/pages/resiliency/timeouts/request.md b/assets/docs/pages/resiliency/timeouts/request.md deleted file mode 100644 index 1567d21a9..000000000 --- a/assets/docs/pages/resiliency/timeouts/request.md +++ /dev/null @@ -1,211 +0,0 @@ -Change the default route-level timeout of 15 seconds with an HTTPRoute or {{< reuse "agw-docs/snippets/kgateway.md" >}} {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. To ensure that your apps are available even if they are temporarily unavailable, you can use timeouts alongside [Retries]({{< link-hextra path="/resiliency/retry/" >}}). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up timeouts {#timeouts} - -Specify timeouts for a specific route. - -1. Configure a timeout for a specific route by using the Kubernetes Gateway API-native configuration in an HTTPRoute or by using {{< reuse "agw-docs/snippets/kgateway.md" >}}'s {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. In the following example, you set a timeout of 20 seconds for httpbin's `/headers` path. However, no timeout is set along the `/anything` path. - {{< tabs tabTotal="2" items="Option 1: HTTPRoute (Kubernetes GW API),Option 2: TrafficPolicy" >}} - {{% tab tabName="Option 1: HTTPRoute (Kubernetes GW API)" %}} - ```yaml - kubectl apply -n httpbin -f- <}} - rules: - - matches: - - path: - type: PathPrefix - value: /headers - backendRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - timeouts: - request: "20s" - - matches: - - path: - type: PathPrefix - value: /anything - backendRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - EOF - ``` - {{% /tab %}} - {{% tab tabName="Option 2: EnterpriseKgatewayTrafficPolicy" %}} - 1. Install the experimental channel of the Kubernetes Gateway API to use this feature. - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml - ``` - - 2. Create the HTTPRoute with two routes, `/headers` and `/anything`, and add an HTTPRoute rule name to each path. You use the rule name later to apply the timeout to a particular route. - ```yaml - kubectl apply -n httpbin -f- <}} - rules: - - matches: - - path: - type: PathPrefix - value: /headers - backendRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - name: timeout - - matches: - - path: - type: PathPrefix - value: /anything - backendRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - name: no-timeout - EOF - ``` - - 3. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your timeout settings and use the `targetRefs.sectionName` to apply the timeout to a specific HTTPRoute rule. In this example, you apply the policy to the `timeout` rule that points to the `/headers` path in your HTTPRoute resource. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: timeout - namespace: httpbin - spec: - targetRefs: - - kind: HTTPRoute - group: gateway.networking.k8s.io - name: httpbin-timeout - sectionName: timeout - timeouts: - request: 20s - EOF - ``` - - {{% /tab %}} - {{< /tabs >}} - -2. Send a request to the httpbin app along the `/headers` path that you configured a custom timeout for. Verify that the request succeeds and that you see a `X-Envoy-Expected-Rq-Timeout-Ms` header with the custom timeout of 20 seconds (20000). - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: timeout.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: timeout.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output for a successful response: - ```console {hl_lines=[12,13]} - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com:8080" - ], - "User-Agent": [ - "curl/7.77.0" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "20000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "0ae53bc3-2644-44f2-8603-158d2ccf9f78" - ] - } - } - ``` - -3. Send a request to the httpbin app along the `anything` path that does not have a custom timeout. Verify that the request succeeds and that you see a `X-Envoy-Expected-Rq-Timeout-Ms` header with the default timeout of 15 seconds (15000). - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: timeout.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/anything -H "host: timeout.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output for a successful response: - ```console {hl_lines=[12,13]} - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com:8080" - ], - "User-Agent": [ - "curl/7.77.0" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "0ae53bc3-2644-44f2-8603-158d2ccf9f78" - ] - } - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-timeout -n httpbin -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} timeout -n httpbin -``` - - - - - diff --git a/assets/docs/pages/security/access-logging.md b/assets/docs/pages/security/access-logging.md deleted file mode 100644 index c8e6cbf1b..000000000 --- a/assets/docs/pages/security/access-logging.md +++ /dev/null @@ -1,387 +0,0 @@ -Capture an access log for all the requests that enter the gateway. - -{{< callout >}} -{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}} -{{< /callout >}} - -## About access logging - -Access logs, sometimes referred to as audit logs, represent all traffic requests that pass through the gateway proxy. The access log entries can be customized to include data from the request, the routing destination, and the response. - -Access logs can be written to a file, the `stdout` stream of the gateway proxy container, or exported to a gRPC server for custom handling. The access logs capture information from requests that the Envoy HttpConnectionManager in your gateway proxy handles. - -### Envoy data that can be logged - -Envoy exposes a lot of data that can be used when customizing access logs. The following data properties are available for both TCP and HTTP access logging: - -* The downstream (client) address, connection information, TLS configuration, and timing -* The backend (service) address, connection information, TLS configuration, timing, and Envoy routing information -* Relevant Envoy configuration, such as rate of sampling (if used) -* Filter-specific context that is published to Envoy's dynamic metadata during the filter chain - -### Additional HTTP properties - -When Envoy is used as an HTTP proxy, additional HTTP information is available for access logging, including: - -* Request data, including the method, path, scheme, port, user agent, headers, body, and more -* Response data, including the response code, headers, body, and trailers, as well as a string representation of the response code -* Protocol version - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Access logs to `stdout` {#access-log-stdout-filesink} - -You can set up access logs to write to a standard (stdout/stderr) stream. The following example writes access logs to a stdout in the pod of the selected `http` gateway. - -1. Create an HTTPListenerPolicy resource to define your access logging rules. The following example writes access logs to the `stdout` stream of the gateway proxy container by using a custom string format that is defined in the `jsonFormat` field. - - ```yaml - kubectl apply -f- <}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - accessLog: - - fileSink: - path: /dev/stdout - jsonFormat: - start_time: "%START_TIME%" - method: "%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%" - path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" - protocol: "%PROTOCOL%" - response_code: "%RESPONSE_CODE%" - response_flags: "%RESPONSE_FLAGS%" - bytes_received: "%BYTES_RECEIVED%" - bytes_sent: "%BYTES_SENT%" - total_duration: "%DURATION%" - resp_backend_service_time: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%" - req_x_forwarded_for: "%REQ(X-FORWARDED-FOR)%" - user_agent: "%REQ(USER-AGENT)%" - request_id: "%REQ(X-REQUEST-ID)%" - authority: "%REQ(:AUTHORITY)%" - backendHost: "%UPSTREAM_HOST%" - backendCluster: "%UPSTREAM_CLUSTER%" - EOF - ``` - - | Setting | Description | - | ------- | ----------- | - | `targetRefs`| Select the Gateway to enable access logging for. The example selects the `http` gateway that you created from the sample app guide. | - | `accessLog` | Configure the details for access logging. You can use multiple `fileSink` configurations for multiple outputs. The example sets up a `fileSink` for standard logging (stdout) in JSON format at `/dev/stdout`. You can also send the access logs to a `grpcService` instead of `fileSink`. | - | `path` | The path in the gateway proxy to write access logs to, such as `/dev/stdout`. | - | `jsonFormat` | The structured JSON format to write logs in. For more information about the JSON format dictionaries and command operators you can use, see the [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#format-dictionaries). To format as a string, use the `stringFormat` setting instead. If you omit or leave this setting blank, the [Envoy default format string](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#default-format-string) is used. | - | `stringFormat` | The string format to write logs in. For more information about the string format and command operators you can use, see the [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings). To format as JSON, use the `jsonFormat` setting instead. If you omit or leave this setting blank, the [Envoy default format string](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#default-format-string) is used. | - -2. Send a request to the httpbin app on the `www.example.com` domain. Verify that your request succeeds and that you get back a 200 HTTP response code. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/status/200 -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - date: Fri, 07 Jun 2024 21:10:03 GMT - x-envoy-upstream-service-time: 2 - server: envoy - transfer-encoding: chunked - ``` - -3. Get the logs for the gateway pod and verify that you see a stdout JSON entry for each request that you sent to the httpbin app. - - ```sh - kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} logs deployments/http | tail -1 | jq - ``` - - Example output: - ```json - { - "authority": "www.example.com:8080", - "bytes_received": 0, - "bytes_sent": 0, - "method": "GET", - "path": "/status/200", - "protocol": "HTTP/1.1", - "req_x_forwarded_for": null, - "request_id": "a6758866-0f26-4c95-95d9-4032c365c498", - "resp_backend_service_time": "0", - "response_code": 200, - "response_flags": "-", - "start_time": "2024-08-19T20:57:57.511Z", - "total_duration": 1, - "backendCluster": "kube-svc:httpbin-httpbin-8000_httpbin", - "backendHost": "10.36.0.14:8080", - "user_agent": "curl/7.77.0" - } - ``` - - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete HTTPListenerPolicy access-logs -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` - - - - diff --git a/assets/docs/pages/security/backend-tls.md b/assets/docs/pages/security/backend-tls.md deleted file mode 100644 index 9445ed96d..000000000 --- a/assets/docs/pages/security/backend-tls.md +++ /dev/null @@ -1,453 +0,0 @@ -Originate a one-way TLS connection from the Gateway to a backend. - -{{< callout type="warning" >}} -{{< reuse "agw-docs/versions/warn-experimental.md" >}} -{{< /callout >}} - -## About one-way TLS - -When you configure a TLS listener on your Gateway, the Gateway typically terminates incoming TLS traffic and forwards the unencrypted traffic to the backend service. However, you might have a service that only accepts TLS connections, or you want to forward traffic a secured Backend service that is external to the cluster. - -You can use the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} BackendTLSPolicy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/) to configure TLS origination from the Gateway to a service in the cluster. This policy supports simple, one-way TLS use cases. - -However, to additionally set up different hostnames on the Backend that you want to route to via SNI, or to originate TLS connections to an external backend, use the {{< reuse "agw-docs/snippets/kgateway.md" >}} BackendConfigPolicy instead. - -## About this guide - -In this guide, you learn how to use the BackendTLSPolicy and BackendConfigPolicy resources originate one-way TLS connections for the following services: -* [**In-cluster service**](#in-cluster-service): An NGINX server that is configured with a self-signed TLS certificate and deployed to the same cluster as the Gateway. You use a BackendTLSPolicy to originate TLS connections to NGINX. -* [**External service**](#external-service): The `httpbin.org` hostname, which represents an external service that you want to originate a TLS connection to. You use a BackendConfigPolicy resource to originate TLS connections to that hostname. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-x-channel.md" >}} - -## In-cluster service - -Deploy an NGINX server in your cluster that is configured for TLS traffic. Then, instruct the gateway proxy to terminate TLS traffic at the gateway and originate a new TLS connection from the gateway proxy to the NGINX server. - -{{< callout >}} -{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}} -{{< /callout >}} - -### Deploy the sample app - -The following example uses an NGINX server with a self-signed TLS certificate. For the configuration, see the [test directory in the kgateway GitHub repository](https://github.com/kgateway-dev/kgateway/tree/{{< reuse "agw-docs/versions/github-branch.md" >}}/test/kubernetes/e2e/features/backendtls/inputs). - - -1. Deploy the NGINX server with a self-signed TLS certificate. - - ```shell - kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/backendtls/testdata/nginx.yaml - ``` - -2. Verify that the NGINX server is running. - - ```shell - kubectl get pods -l app.kubernetes.io/name=nginx - ``` - - Example output: - - ``` - NAME READY STATUS RESTARTS AGE - nginx 1/1 Running 0 9s - ``` - -### Create a TLS policy {#create-backend-tls-policy} - -Create a TLS policy for the NGINX workload. You can use the Gateway API BackendTLSPolicy for simple, one-way TLS connections. For more advanced TLS connections or simply to reduce the number of resources if you use other backend connections, create a BackendConfigPolicy instead. - -{{< tabs tabTotal="2" items="BackendConfigPolicy,BackendTLSPolicy" >}} -{{% tab tabName="BackendConfigPolicy" %}} - -1. Create a Kubernetes Secret that has the public CA certificate for the NGINX server. - - ```yaml - kubectl apply -f- <}} For more information, see the [BackendConfigPolicy API docs](../../reference/api/#backendconfigpolicy). - - | Setting | Description | - |---------|-------------| - | `targetRefs` | The service that you want the Gateway to originate a TLS connection to, such as the NGINX server.

**Agentgateway proxies**: Even if you use a Backend for selector-based destinations, you still need to target the backing Service and the `sectionName` of the port that you want the policy to apply to. | - | `tls.sni` | The Server Name Indication (SNI) hostname that matches the NGINX server certificate. The SNI is used during the TLS handshake to specify which certificate the server should present. | - | `tls.secretRef` | The Kubernetes Secret that has the public CA certificate for the NGINX server. | - -{{% /tab %}} - -{{% tab tabName="BackendTLSPolicy" %}} - -1. Create a Kubernetes ConfigMap that has the public CA certificate for the NGINX server. - - ```shell - kubectl apply -f- <}} - EOF - ``` - -2. Create the TLS policy. Note that to use the BackendTLSPolicy, you must have the experimental channel of the Kubernetes Gateway API version 1.4 or later. - ```yaml - kubectl apply -f - <}} For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} docs](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/). - - | Setting | Description | - |---------|-------------| - | `targetRefs` | The service that you want the Gateway to originate a TLS connection to, such as the NGINX server.

**Agentgateway proxies**: Even if you use a Backend for selector-based destinations, you still need to target the backing Service and the `sectionName` of the port that you want the policy to apply to. | - | `validation.hostname` | The hostname that matches the NGINX server certificate. | - | `validation.caCertificateRefs` | The ConfigMap that has the public CA certificate for the NGINX server. | -{{% /tab %}} - -{{< /tabs >}} - -### Create an HTTPRoute {#create-http-route} - -Create an HTTPRoute that routes traffic to the NGINX server on the `example.com` hostname and HTTPS port 8443. Note that the parent Gateway is the sample `http` Gateway resource that you created [before you began](#before-you-begin). - -```yaml -kubectl apply -f - <}} - hostnames: - - "example.com" - rules: - - backendRefs: - - name: nginx - port: 8443 -EOF -``` - -### Verify the TLS connection {#verify-tls-connection} - -Now that your TLS backend and routing resources are configured, verify the TLS connection. - -1. Send a request to the NGINX server and verify that you get back a 200 HTTP response code. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/ -H "host: example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi http://localhost:8080/ -H "host: example.com:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Host localhost:8080 was resolved. - * IPv6: ::1 - * IPv4: 127.0.0.1 - * Trying [::1]:8080... - * Connected to localhost (::1) port 8080 - > GET / HTTP/1.1 - > Host: example.com:8080 - > User-Agent: curl/8.7.1 - > Accept: */* - > - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ``` - -2. Enable port-forwarding on the Gateway. - - ```sh - kubectl port-forward deploy/http -n kgateway-system 19000 - ``` - -3. In your browser, open the Envoy stats page at [http://127.0.0.1:19000/stats](http://127.0.0.1:19000/stats). - -4. Search for the following stats that indicate the TLS connection is working. The count increases each time that the Gateway sends a request to the NGINX server. - - * `cluster.kube_default_nginx_8443.ssl.versions.TLSv1.2`: The number of TLSv1.2 connections from the Envoy gateway proxy to the NGINX server. - * `cluster.kube_default_nginx_8443.ssl.handshake`: The number of successful TLS handshakes between the Envoy gateway proxy and the NGINX server. - -## External service - -Set up a Backend resource that represents your external service. Then, use a BackendTLSPolicy to instruct the gateway proxy to originate a TLS connection from the gateway proxy to the external service. - -1. Create a Backend resource that represents your external service. In this example, you use a static Backend that routes traffic to the `httpbin.org` site. Make sure to include the HTTPS port 443 so that traffic is routed to this port. - ```yaml - kubectl apply -f- <}} - {{% tab tabName="BackendConfigPolicy" %}} - - {{< reuse "agw-docs/snippets/proxy-kgateway.md" >}} - ```yaml - kubectl apply -f- <}} - -3. Create an HTTPRoute that rewrites traffic on the `httpbin-external.example` domain to the `httpbin.org` hostname and routes traffic to your Backend. - ```yaml - kubectl apply -f- <}} - hostnames: - - "httpbin-external.example" - rules: - - matches: - - path: - type: PathPrefix - value: /anything - backendRefs: - - name: httpbin-org - kind: Backend - group: gateway.kgateway.dev - filters: - - type: URLRewrite - urlRewrite: - hostname: httpbin.org - EOF - ``` - -4. Send a request to the `httpbin-external.example` domain. Verify that the host is rewritten to `https://httpbin.org/anything` and that you get back a 200 HTTP response code. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2">}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: httpbin-external.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi http://localhost:8080/anything -H "host: httpbin-external.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[1,2,20]} - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - { - "args": {}, - "data": "", - "files": {}, - "form": {}, - "headers": { - "Accept": "*/*", - "Host": "httpbin.org", - "User-Agent": "curl/8.7.1", - "X-Amzn-Trace-Id": "Root=1-6881126a-03bfc90450805b9703e66e78", - "X-Envoy-Expected-Rq-Timeout-Ms": "15000", - "X-Envoy-External-Address": "10.0.15.215" - }, - "json": null, - "method": "GET", - "origin": "10.0.X.XXX, 3.XXX.XXX.XXX", - "url": "https://httpbin.org/anything" - } - ``` - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -### In-cluster service - -{{< tabs tabTotal="2" items="BackendConfigPolicy,BackendTLSPolicy" >}} -{{% tab tabName="BackendConfigPolicy" %}} -1. Delete the NGINX server. - - ```yaml - kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/backendtls/testdata/nginx.yaml - ``` - -2. Delete the routing resources that you created for the NGINX server. - - ```sh - kubectl delete backendconfigpolicy,secret,httproute -A -l app=nginx - ``` -{{% /tab %}} -{{% tab tabName="BackendTLSPolicy" %}} -1. Delete the NGINX server. - - ```yaml - kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/backendtls/testdata/nginx.yaml - ``` - -2. Delete the routing resources that you created for the NGINX server. - - ```sh - kubectl delete backendtlspolicy,configmap,httproute -A -l app=nginx - ``` - -3. If you want to re-create a BackendTLSPolicy after deleting one, restart the control plane. - - **Note**: Due to a [known issue](https://github.com/kgateway-dev/kgateway/issues/11146), if you don't restart the control plane, you might notice requests that fail with a `HTTP/1.1 400 Bad Request` error after creating the new BackendTLSPolicy. - - ```sh - kubectl rollout restart -n kgateway-system deployment/{{< reuse "agw-docs/snippets/pod-name.md" >}} - ``` -{{% /tab %}} -{{< /tabs >}} - - -### External service - -Delete the resources that you created. - -{{< tabs tabTotal="2" items="BackendConfigPolicy,BackendTLSPolicy" >}} -{{% tab tabName="BackendConfigPolicy" %}} -```sh -kubectl delete httproute httpbin-org -kubectl delete backendconfigpolicy httpbin-org -kubectl delete backend httpbin-org -``` -{{% /tab %}} -{{% tab tabName="BackendTLSPolicy" %}} -```sh -kubectl delete httproute httpbin-org -kubectl delete backendtlspolicy httpbin-org -kubectl delete backend httpbin-org -``` -{{% /tab %}} -{{< /tabs >}} - - - diff --git a/assets/docs/pages/security/cors.md b/assets/docs/pages/security/cors.md deleted file mode 100644 index e5f24a4c1..000000000 --- a/assets/docs/pages/security/cors.md +++ /dev/null @@ -1,273 +0,0 @@ -Enforce client-site access controls with cross-origin resource sharing (CORS). - -{{< callout type="warning" >}} -{{< reuse "agw-docs/versions/warn-experimental.md" >}} -{{< /callout >}} - -## About CORS - -Cross-Origin Resource Sharing (CORS) is a security feature that is implemented by web browsers and that controls how web pages in one domain can request and interact with resources that are hosted on a different domain. By default, web browsers only allow requests to resources that are hosted on the same domain as the web page that served the original request. Access to web pages or resources that are hosted on a different domain is restricted to prevent potential security vulnerabilities, such as cross-site request forgery (CRSF). - -When CORS is enabled in a web browser and a request for a different domain comes in, the web browser checks whether this request is allowed or not. To do that, it typically sends a preflight request (HTTP `OPTIONS` method) to the server or service that serves the requested resource. The service returns the methods that are permitted to send the actual cross-origin request, such as GET, POST, etc. If the request to the different domain is allowed, the response includes CORS-specific headers that instruct the web browser how to make the cross-origin request. For example, the CORS headers typically include the origin that is allowed to access the resource, and the credentials or headers that must be included in the cross-origin request. - -Note that the preflight request is optional. Web browsers can also be configured to send the cross-origin directly. However, access to the request resource is granted only if CORS headers were returned in the response. If no headers are returned during the preflight request, the web browser denies access to the resource in the other domain. - -CORS policies are typically implemented to limit access to server resources for JavaScripts that are embedded in a web page, such as: - -* A JavaScript on a web page at `example.com` tries to access a different domain, such as `api.com`. -* A JavaScript on a web page at `example.com` tries to access a different subdomain, such as `api.example.com`. -* A JavaScript on a web page at `example.com` tries to access a different port, such as `example.com:3001`. -* A JavaScript on a web page at `https://example.com` tries to access the resources by using a different protocol, such as `http://example.com`. - - - -### Configuration options {#options} - -You can configure the CORS policy at two levels: - -* **HTTPRoute**: For the native way in Kubernetes Gateway API, configure a CORS policy in the HTTPRoute. You can choose to apply the CORS policy to all the routes that are defined in the HTTPRoute, or to a selection of `backendRefs`. This route-level policy takes precedence over any {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} CORS that you might configure. For more information, see the [Kubernetes Gateway API docs](https://gateway-api.sigs.k8s.io/reference/spec/#httpcorsfilter) and [CORS design docs](https://gateway-api.sigs.k8s.io/geps/gep-1767/). -* **{{< reuse "agw-docs/snippets/trafficpolicy.md" >}}**: For more flexibility to reuse the CORS policy across HTTPRoutes, specific routes and Gateways, configure a CORS policy in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. You can attach a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to a Gateway, all HTTPRoutes via `targetRefs`, or an individual route via `extensionRef`. To attach to a `backendRef`, use a CORS policy in the HTTPRoute instead. For more information about attachment and merging rules, see the [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}} concept docs](../../about/policies/trafficpolicy/). - - - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-x-channel.md" >}} - -## Set up CORS policies - -Create a CORS policy for the httpbin app in an HTTPRoute or {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. - -{{% version exclude-if="2.0.x" %}} - -### CORS in HTTPRoute - -Create an HTTPRoute resource for the httpbin app that applies a CORS filter. The following example allows requests from the `https://example.com/` origin. - -```yaml -kubectl apply -f- <}} - hostnames: - - cors.example - rules: - - filters: - - type: CORS - cors: - allowCredentials: true - allowHeaders: - - Origin - allowMethods: - - GET - - POST - - OPTIONS - allowOrigins: - - "https://example.com" - exposeHeaders: - - Origin - - X-HTTPRoute-Header - maxAge: 86400 - backendRefs: - - name: httpbin - port: 8000 -EOF -``` - -### CORS in {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource for the httpbin app that applies a CORS filter. The following example allows requests from the `https://example.com/` origin. - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: httpbin-cors - namespace: httpbin - spec: - cors: - allowCredentials: true - allowHeaders: - - "Origin" - - "Authorization" - - "Content-Type" - allowMethods: - - "GET" - - "POST" - - "OPTIONS" - allowOrigins: - - "https://example.com" - exposeHeaders: - - "Origin" - - "X-TrafficPolicy-Header" - maxAge: 86400 - EOF - ``` - -2. Attach the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to a route or Gateway. The following example creates an HTTPRoute for the httpbin app that has the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} attached via the `extensionRef` filter. For more information about attachment and merging rules, see the [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}} concept docs]({{< link-hextra path="/about/policies/trafficpolicy/" >}}). - - ```yaml - kubectl apply -f- <}} - hostnames: - - cors.example - rules: - - filters: - - type: ExtensionRef - extensionRef: - group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - name: httpbin-cors - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -{{% /version %}} - - -## Test CORS policies - -Now that you have CORS policies applied via an HTTPRoute or {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, you can test the policies. - -1. Send a request to the httpbin app on the `cors.example` domain and use `https://example.com/` as the origin. Verify that your request succeeds and that you get back the configured CORS headers. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -I -X OPTIONS http://$INGRESS_GW_ADDRESS:8080/get -H "host: cors.example:8080" \ - -H "Origin: https://example.com/" \ - -H "Access-Control-Request-Method: POST" \ - -H "Access-Control-Request-Headers: Origin" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -I -X OPTIONS localhost:8080/headers -H "host: cors.example:8080" \ - -H "Origin: https://example.com/" \ - -H "Access-Control-Request-Method: POST" \ - -H "Access-Control-Request-Headers: Origin" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: Notice that the `access-control-*` values reflect your CORS policy and change depending on the resources that you created. - * If you created an HTTPRoute with a CORS filter, you see the `Origin` and `X-HTTPRoute-Header` headers. - * If you created a TrafficPolicy with a CORS filter, you see the `Origin` and `X-TrafficPolicy-Header` headers. - - **CORS in HTTPRoute** - - ```console {hl_lines=[7,8,9]} - HTTP/1.1 200 OK - x-correlation-id: aaaaaaaa - date: Tue, 24 Jun 2025 13:19:53 GMT - content-length: 0 - - HTTP/1.1 200 OK - access-control-allow-origin: https://example.com/ - access-control-allow-credentials: true - access-control-allow-methods: GET, POST, OPTIONS - access-control-allow-headers: Origin, Authorization, Content-Type - access-control-max-age: 86400 - access-control-expose-headers: Origin, X-HTTPRoute-Header - date: Tue, 24 Jun 2025 13:19:53 GMT - server: envoy - content-length: 0 - ... - ``` - - **CORS in {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}** - ```console {hl_lines=[7,8,9]} - HTTP/1.1 200 OK - x-correlation-id: aaaaaaaa - date: Tue, 24 Jun 2025 13:19:53 GMT - content-length: 0 - - HTTP/1.1 200 OK - access-control-allow-origin: https://example.com/ - access-control-allow-credentials: true - access-control-allow-methods: GET, POST, OPTIONS - access-control-allow-headers: Origin, Authorization, Content-Type - access-control-max-age: 86400 - access-control-expose-headers: Origin, X-TrafficPolicy-Header - date: Tue, 24 Jun 2025 13:19:53 GMT - server: envoy - content-length: 0 - ``` - - - -2. Send another request to the httpbin app. This time, you use `notallowed.com` as your origin. Although the request succeeds, you do not get back your configured CORS settings such as max age, allowed orgin, or allowed methods, because `notallowed.com` is not configured as a supported origin. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -I -X OPTIONS http://$INGRESS_GW_ADDRESS:8080/get -H "host: cors.example:8080" \ - -H "Origin: https://notallowed.com/" \ - -H "Access-Control-Request-Method: POST" \ - -H "Access-Control-Request-Headers: Origin" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -I -X OPTIONS localhost:8080/headers -H "host: cors.example:8080" \ - -H "Origin: https://notallowed.com/" \ - -H "Access-Control-Request-Method: POST" \ - -H "Access-Control-Request-Headers: Origin" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console - HTTP/1.1 200 OK - x-correlation-id: aaaaaaaa - date: Tue, 24 Jun 2025 13:21:20 GMT - content-length: 0 - - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-headers: Origin - access-control-allow-methods: GET, POST, HEAD, PUT, DELETE, PATCH, OPTIONS - access-control-allow-origin: https://notallowed.com/ - access-control-max-age: 3600 - date: Tue, 24 Jun 2025 13:21:20 GMT - content-length: 0 - x-envoy-upstream-service-time: 1 - server: envoy - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - - -**CORS in HTTPRoute** -```sh -kubectl delete httproute httpbin-cors -n httpbin -``` - -**CORS in {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}** -```sh -kubectl delete httproute httpbin-cors -n httpbin -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} httpbin-cors -n httpbin -``` - - - diff --git a/assets/docs/pages/security/csrf.md b/assets/docs/pages/security/csrf.md deleted file mode 100644 index 58ae0c7c6..000000000 --- a/assets/docs/pages/security/csrf.md +++ /dev/null @@ -1,166 +0,0 @@ -Apply a CSRF filter to the gateway to help prevent cross-site request forgery attacks. - -## About CSRF - -According to [OWASP](https://owasp.org/www-community/attacks/csrf), CSRF is defined as follows: - -> Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker's choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application. - -To help prevent CSRF attacks, you can enable the CSRF filter on your gateway or a specific route. For each route that you apply the CSRF policy to, the filter checks to make sure that a request's origin matches its destination. If the origin and destination do not match, a 403 Forbidden error code is returned. - -{{< callout type="info" >}} -Note that because CSRF attacks specifically target state-changing requests, the filter only acts on HTTP requests that have a state-changing method such as `POST` or `PUT`. -{{< /callout >}} - -{{< callout type="info" >}} -To learn more about CSRF, you can try out the [CSRF sandbox](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/csrf) in Envoy. -{{< /callout >}} - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up CSRF - -Use a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to define your CSRF rules. - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to define your CSRF rules. The following example allows request from only the `allowThisOne.example.com` origin. - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: csrf - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - csrf: - percentageEnabled: 100 - additionalOrigins: - - exact: allowThisOne.example.com - ignoreCase: false - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} For more information, see the [API docs]({{< link-hextra path="/reference/api/#csrfpolicy" >}}). - - | Field | Description | - |-------|-------------| - | `targetRefs` | The policy targets the `httpbin` HTTPRoute resource that you created before you began. | - | `percentageEnabled` | The percentage of requests for which the CSRF policy is enabled. A value of `100` means that all requests are enforced by the CSRF rules. | - | `additionalOrigins` | Additional origins that the CSRF policy allows, besides the destination origin. Possible values include `exact`, `prefix`, `suffix`, `contains`, `safeRegex`, and an `ignoreCase` boolean. At least one of `exact`, `prefix`, `suffix`, `contains`, or `safeRegex` must be set. The example allows requests from the `allowThisOne.example.com` exact origin. | - -2. Send a request to the httpbin app on the `www.example.com` domain. Verify that you get back a 403 HTTP response code because no origin is set in your request. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi -X POST http://$INGRESS_GW_ADDRESS:8080/post -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi -X POST localhost:8080/post -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```console - HTTP/1.1 403 Forbidden - ... - Invalid origin - ``` - -3. Send another request to the httpbin app. This time, you include the `allowThisOne.example.com` origin header. Verify that you get back a 200 HTTP response code, because the origin matches the origin that you specified in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi -X POST http://$INGRESS_GW_ADDRESS:8080/post -H "host: www.example.com:8080" -H "origin: allowThisOne.example.com" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi -X POST localhost:8080/post -H "host: www.example.com" -H "origin: allowThisOne.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console - HTTP/1.1 200 OK - ... - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Content-Length": [ - "0" - ], - "Host": [ - "csrf.example:8080" - ], - "Origin": [ - "allowThisOne.example.com" - ], - "User-Agent": [ - "curl/7.77.0" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "b1b53950-f7b3-47e6-8b7b-45a44196f1c4" - ] - }, - "origin": "10.X.X.XX:33896", - "url": "http://csrf.example:8080/post", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -## Monitor CSRF metrics - -1. Port-forward the gateway proxy. - ```sh - kubectl port-forward -n {{< reuse "agw-docs/snippets/namespace.md" >}} deploy/http 19000 - ``` - -2. Open the [`/stats`](http://localhost:19000/stats) endpoint. - -3. Find the statistics for `csrf`. - - Example output: - - ```console - http.http.csrf.missing_source_origin: 1 - http.http.csrf.request_invalid: 0 - http.http.csrf.request_valid: 1 - ... - ``` - - * `missing_source_origin`: The number of requests that were sent without an origin. The number is `1` because you sent the first request without an origin. - * `request_invalid`: The number of requests that were sent with an origin that did not match the destination origin. The number is `0` because you did not send an invalid request. - * `request_valid`: The number of requests that were sent with an origin that matched the destination origin. The number is `1` because you sent a valid request in your second request. - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} csrf -n httpbin -``` diff --git a/assets/docs/pages/security/external-auth.md b/assets/docs/pages/security/external-auth.md deleted file mode 100644 index b30614d86..000000000 --- a/assets/docs/pages/security/external-auth.md +++ /dev/null @@ -1,327 +0,0 @@ -Bring your own {{< gloss "External Authorization" >}}external authorization{{< /gloss >}} service to protect requests that go through your Gateway. - -## About external auth {#about} - -{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} lets you integrate your own external authorization service to your Gateway, based on the [Envoy external authorization filter](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/ext_authz_filter). Then, this external authorization service makes authorization decisions for requests that go through the Gateway, as shown in the following diagram. - -```mermaid -sequenceDiagram - participant Client - participant Gateway - participant Ext Auth - participant Backend - - Client->>Gateway: 1. HTTP Request - Gateway->>Ext Auth: 2. Authorization Request - Ext Auth-->>Gateway: 3. Authorization Decision - - alt Authorized - Gateway->>Backend: 4. Forward Request - Backend-->>Gateway: Response - Gateway-->>Client: Response - else Not Authorized - Gateway-->>Client: 5. 403 Forbidden - end -``` - -1. The Client sends a request to the Gateway. -2. The Gateway forwards the request to the Ext Auth service. -3. The Ext Auth service makes a decision as to whether the request is authorized, based on headers, parameters, or other credentials. -4. If authorized, the Gateway forwards the request to the Backend app, which then sends back a response to the Client through the Gateway. -5. If not authorized, the Gateway rejects the request and by default returns a 403 Forbidden response to the Client. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Bring your own external authorization service {#byo-ext-auth} - -First, deploy your own external authorization service as a backend service that is accessible to kgateway. To do so, you configure a custom GatewayExtension resource that points to your external authorization service via gRPC. - -{{< callout type="info" >}} -Keep in mind that your external authorization service must conform to the [Envoy external auth proto](https://github.com/envoyproxy/envoy/blob/main/api/envoy/service/auth/v3/external_auth.proto). The external authorization service also configures the conditions for authorizing a request, such as the inclusion of a certain header or other credentials. -{{< /callout >}} - -{{< callout type="info" >}} -Note that in the following example, resources are created in the same namespace to simplify setup. For example, the external auth service and GatewayExtension are in the same `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace, and the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, HTTPRoute, and backing Service for the sample app are in the same `httpbin` namespace. To create the resources in different namespaces, make sure that you set up a [Kubernetes ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) from the GatewayExtension to the Services that back the external auth service. -{{< /callout >}} - -1. Deploy your external authorization service. The following example uses the [Istio external authorization service](https://github.com/istio/istio/tree/master/samples/extauthz) for quick testing purposes. This service is configured to allow requests with the `x-ext-authz: allow` header. - - ```yaml - kubectl apply -f - <}} - name: ext-authz - labels: - app: ext-authz - spec: - replicas: 1 - selector: - matchLabels: - app: ext-authz - template: - metadata: - labels: - app: ext-authz - app.kubernetes.io/name: ext-authz - spec: - containers: - - image: gcr.io/istio-testing/ext-authz:1.25-dev - name: ext-authz - ports: - - containerPort: 9000 - EOF - ``` - -2. Create a Service for the Deployment that your proxy can access. - - ```yaml - kubectl apply -f - <}} - name: ext-authz - labels: - app: ext-authz - spec: - ports: - - port: 4444 - targetPort: 9000 - protocol: TCP - appProtocol: kubernetes.io/h2c - selector: - app: ext-authz - EOF - ``` - -3. Create a GatewayExtension resource that points to your external authorization Service. Note that the GatewayExtension is created in the same namespace as the external auth service. To use a different namespace, make sure that you set up a [Kubernetes ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) from the GatewayExtension to the Services that back the external auth service. - - ```yaml - kubectl apply -f - <}} - name: basic-ext-auth - labels: - app: ext-authz - spec: - type: ExtAuth - extAuth: - grpcService: - backendRef: - name: ext-authz - port: 4444 - EOF - ``` - -## Create external auth policy {#create-policy} - -You can apply a policy at two levels: the Gateway level or the HTTPRoute level. If you apply the policy at both levels, the request must pass both policies to be authorized. - -1. Send a test request to the httpbin sample app. Verify that you get back a 200 HTTP response code and that no authorization is required. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/headers -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```txt - HTTP/1.1 200 OK - ... - ``` - -2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that applies the GatewayExtension with external authorization at the Gateway level. Note that you can also set the `targetRefs` to select an HTTPRoute, which is demonstrated in later steps. Create the TrafficPolicy in the same namespace as the targeted resource. - - ```yaml - kubectl apply -f - <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - name: gateway-ext-auth-policy - labels: - app: ext-authz - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - extAuth: - extensionRef: - name: basic-ext-auth - EOF - ``` - -3. Repeat your request to the httpbin sample app and verify that the request is denied. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/headers -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: Note the 403 Forbidden response, along with the special `x-ext-authz*` headers that the Istio external authorization service adds to the request to explain the decision. - - ```txt - HTTP/1.1 403 Forbidden - x-ext-authz-check-result: denied - x-ext-authz-check-received: source:{address:{socket_address:{address:"127.0.0.1" port_value:52492}}} destination:{address:{socket_address:{address:"127.0.0.1" port_value:8080}}} request:{time:{seconds:1743195078 nanos:842835000} http:{id:"6918845494626045094" method:"GET" headers:{key:":authority" value:"www.example.com"} headers:{key:":method" value:"GET"} headers:{key:":path" value:"/headers"} headers:{key:":scheme" value:"http"} headers:{key:"accept" value:"*/*"} headers:{key:"user-agent" value:"curl/8.7.1"} headers:{key:"x-envoy-external-address" value:"127.0.0.1"} headers:{key:"x-forwarded-for" value:"10.244.0.7"} headers:{key:"x-forwarded-proto" value:"http"} headers:{key:"x-request-id" value:"be03e2fd-4513-489e-8933-67b90c59815a"} path:"/headers" host:"www.example.com" scheme:"http" protocol:"HTTP/1.1"}} metadata_context:{} route_metadata_context:{} - x-ext-authz-additional-header-override: grpc-additional-header-override-value - content-length: 76 - content-type: text/plain - date: Fri, 28 Mar 2025 20:51:18 GMT - server: envoy - - denied by ext_authz for not found header `x-ext-authz: allow` in the request - ``` - -4. Send another request, this time with the `x-ext-authz: allow` header. The Istio external authorization service is configured to allow requests with this header. Therefore, the request succeeds. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" -H "x-ext-authz: allow" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/headers -H "host: www.example.com" -H "x-ext-authz: allow" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: Note that the 200 response with several `X-Ext-Authz*` headers that explain the decision. - - ```txt - HTTP/1.1 200 OK - ... - ``` - ```json {hl_lines=[18,19,21,22,24,25,27,28]} - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Envoy-External-Address": [ - "127.0.0.1" - ], - "X-Ext-Authz": [ - "allow" - ], - "X-Ext-Authz-Additional-Header-Override": [ - "grpc-additional-header-override-value" - ], - "X-Ext-Authz-Check-Received": [ - "source:{address:{socket_address:{address:\"127.0.0.1\" port_value:41472}}} destination:{address:{socket_address:{address:\"127.0.0.1\" port_value:8080}}} request:{time:{seconds:1743195175 nanos:308379000} http:{id:\"2185898822670104560\" method:\"GET\" headers:{key:\":authority\" value:\"www.example.com\"} headers:{key:\":method\" value:\"GET\"} headers:{key:\":path\" value:\"/headers\"} headers:{key:\":scheme\" value:\"http\"} headers:{key:\"accept\" value:\"*/*\"} headers:{key:\"user-agent\" value:\"curl/8.7.1\"} headers:{key:\"x-envoy-external-address\" value:\"127.0.0.1\"} headers:{key:\"x-ext-authz\" value:\"allow\"} headers:{key:\"x-forwarded-for\" value:\"10.244.0.7\"} headers:{key:\"x-forwarded-proto\" value:\"http\"} headers:{key:\"x-request-id\" value:\"8fc7e284-7c09-4080-9500-f8da4495949d\"} path:\"/headers\" host:\"www.example.com\" scheme:\"http\" protocol:\"HTTP/1.1\"}} metadata_context:{} route_metadata_context:{}" - ], - "X-Ext-Authz-Check-Result": [ - "allowed" - ], - "X-Forwarded-For": [ - "10.244.0.7" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "8fc7e284-7c09-4080-9500-f8da4495949d" - ] - } - } - ``` - -5. Create another {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to disable external authorization for a particular HTTPRoute. This way, requests that do not require external authorization, such as health checks, are allowed through while the external authorization service is still in place for requests to other routes on the Gateway. - - ```yaml - kubectl apply -f - <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - namespace: httpbin - name: route-ext-auth-policy - labels: - app: ext-authz - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - extAuth: - disable: {} - EOF - ``` - - - -6. Send a request without the `x-ext-authz` header and verify that you get back a 200 OK response. This time, the TrafficPolicy with the disabled external authorization service takes precedence so that the request is allowed through. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/headers -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```txt - HTTP/1.1 200 OK - ... - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} for the Gateway and HTTPRoute. - - ```sh - kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -A -l app=ext-authz - ``` - -2. Delete the sample external authorization service and GatewayExtension resource. - - ```sh - kubectl delete gatewayextension,deployment,service -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=ext-authz - ``` - - - - diff --git a/assets/docs/pages/security/ratelimit/global.md b/assets/docs/pages/security/ratelimit/global.md deleted file mode 100644 index 44d2695d8..000000000 --- a/assets/docs/pages/security/ratelimit/global.md +++ /dev/null @@ -1,456 +0,0 @@ - -Configure global rate limiting rules across all of your Gateways to protect the backing services in your cluster. - -## About {#about} - -Global rate limiting in {{< reuse "agw-docs/snippets/kgateway.md" >}} is powered by [Envoy's rate limiting service protocol](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter). With global rate limiting, you can apply distributed, consistent rate limits across multiple Gateways. Unlike local rate limiting, which operates per Gateway instance, global rate limiting uses a central service to coordinate rate limits. Therefore, to use global rate limiting, you must bring your own rate limit service that implements the Envoy protocol. - -With your own rate limit service in place, you get benefits such as: - -- Coordinated rate limiting across multiple Gateways. -- Centralized rate limit management with shared counters. -- Dynamic descriptor-based rate limits that can consider multiple request attributes. -- Consistent user experience, regardless of which Gateway receives the request. - -### Request flow - -Review the following sequence diagram to understand the request flow with global rate limiting. - -```mermaid -sequenceDiagram - participant Client - participant Gateway - participant RateLimiter - participant App - - Client->>Gateway: 1. Send request to protected App - Gateway->>Gateway: 2. Receive request - Gateway->>RateLimiter: 3. Extract descriptors & send to Rate Limit Service - RateLimiter->>RateLimiter: 4. Apply configured limits for descriptors - RateLimiter->>Gateway: Return decision - alt Request allowed - Gateway->>App: 5. Forward request to App - App->>Gateway: Return response - Gateway->>Client: Return response to Client - else Rate limit reached - Gateway->>Client: 6. Deny request & return rate limit message - end -``` - -1. The Client sends a request to an App that is protected by the Gateway. -2. The Gateway receives the request. -3. The Gateway extracts descriptors and sends them to the Rate Limit Service. -4. The Rate Limit Service applies configured limits for those descriptors and returns a decision to the Gateway. -5. If allowed, the Gateway forwards the request to the App. -6. If the rate limit is reached, the Gateway denies the request and returns a message to the Client. - -### Architecture - -The global rate limiting feature consists of three components: - -1. **{{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with rateLimit.global**: Configure your rate limit policy in a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. The rate limit policy includes the descriptors to extract from requests for the Gateway to send to the Rate Limit Service. -2. **GatewayExtension**: Connect {{< reuse "/agw-docs/snippets/kgateway.md" >}} with the Rate Limit Service by using a kgateway GatewayExtension. -3. **Rate Limit Service** - An external service that you set up to implement the Envoy Rate Limit protocol. The Rate Limit Service has the actual rate limit values to enforce on requests, based on the descriptors that the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} includes. - -### Response headers - -When rate limiting is enabled, {{< reuse "agw-docs/snippets/kgateway.md" >}} adds the following headers to responses. These headers help clients understand their current rate limit status and adapt their behavior accordingly. - -| Header | Description | Example | -|--------|-------------|---------| -| x-ratelimit-limit | The rate limit ceiling for the given request | `10, 10;w=60` (10 requests per 60 seconds) | -| x-ratelimit-remaining | The number of requests left for the time window | `5` (5 requests remaining) | -| x-ratelimit-reset | The time in seconds until the rate limit resets | `30` (rate limit resets in 30 seconds) | -| x-envoy-ratelimited | Present when the request is rate limited | `true` | - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Step 1: Deploy your Rate Limit Service {#byo-rate-limit-service} - -You can bring your own rate limit service that implements the Envoy Rate Limit gRPC protocol. - -To get started, you can try out a demo rate limit service from the kgateway project. For more information, see the [GitHub repo](https://github.com/kgateway-dev/kgateway/tree/main/test/kubernetes/e2e/features/rate_limit/testdata). - -1. Create the `kgateway-test-extensions` namespace. - - ```sh - kubectl create namespace kgateway-test-extensions - ``` - -2. Deploy the rate limit service. - - ```bash - kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/rate_limit/global/testdata/rate-limit-server.yaml - ``` - -## Step 2: Define the rate limits {#rate-limits} - -Define the actual rate limit values (requests per unit time) in your Rate Limit Service. For example, using the [Envoy Rate Limit](https://github.com/envoyproxy/ratelimit) service, you configure the rate limits in its configuration file. - -The kgateway example that you deployed in the previous step includes the following rate limit configuration as a Kubernetes ConfigMap. - -```sh -kubectl describe configmap ratelimit-config -n kgateway-test-extensions -``` - -{{< reuse "agw-docs/snippets/review-table.md" >}} - -| Field | Description | -|-------|-------------| -| domain | Required. A globally unique identifier to group together a set of rate limit rules. This way, different teams can have their own set of rate limits that don't conflict with each other. Later, you set the domain to use in the kgateway GatewayExtension. If you have different domains for different teams, each team can create their own GatewayExtension that their {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} can reference. | -| descriptors | A list of key-value pairs that the Rate Limit Service uses to select which rate limit to use on matching requests. Descriptors are case-sensitive. | -| key | Required. The name for the descriptor to use when matching requests. Later, you use the descriptor key in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to decide which rate limits to apply to requests. The Rate Limit Service expects one of the following values for the descriptor key: `remote_address` for a client IP address (`RemoteAddress` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}), `path` for path matching (`Path` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}), a key name for header matching (`Header` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}), or a custom key name for matching on a generic key-value pair (`Generic` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}). | -| value | Optional. Each descriptor can have a value for more specific matching. For example, you might have two descriptor keys that are both for an `X-User-ID` header, but one also has a value of `user1`. This way, you can apply different rate limits to the specific value, such as to further restrict or permit a particular user. Similarly, you can take this approach for remote addresses, paths, and generic key-value pairs such as for `service` plans. | -| rate_limit | Optional. The actual rate limit rule to apply. The example sets different rate limits for each descriptor key. If a descriptor key does not have a rate limit, the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} cannot apply a rate limit to requests, and the requests that match the descriptor are allowed. | -| unit | The unit of time for the rate limit, such as `second`, `minute`, `hour`, or `day`. | -| requests_per_unit | The number of requests to allow per unit of time. | - -Example output: - -```yaml -Data -==== -config.yaml: ----- -domain: api-gateway -descriptors: - - key: remote_address - rate_limit: - unit: minute - requests_per_unit: 1 - - key: path - value: "/path1" - rate_limit: - unit: minute - requests_per_unit: 1 - - key: path - value: "/path2" - rate_limit: - unit: minute - requests_per_unit: 2 - - key: X-User-ID - rate_limit: - unit: minute - requests_per_unit: 1 - - key: X-User-ID - value: user1 - rate_limit: - unit: minute - requests_per_unit: 1 - - key: service - value: premium-api - rate_limit: - unit: minute - requests_per_unit: 2 - - -BinaryData -==== -``` - -## Step 3: Create a GatewayExtension {#gateway-extension} - -Create a GatewayExtension resource that points to your Rate Limit Service. - -1. Create a GatewayExtension. - - ```yaml - kubectl apply -f - <}} - name: global-ratelimit - spec: - type: RateLimit - rateLimit: - grpcService: - backendRef: - name: ratelimit - namespace: kgateway-test-extensions - port: 8081 - domain: "api-gateway" - timeout: "100ms" - failOpen: false - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API docs](../../../reference/api/#ratelimitprovider). - - | Field | Description | Required | - |-------|-------------|----------| - | grpcService | Configuration for connecting to the gRPC rate limit service. | Yes | - | domain | Domain identity for the rate limit service. If you have different domains for different teams, each team can create their own GatewayExtension that their own {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} can reference. | Yes | - | timeout | Timeout for rate limit service calls, such as `100ms`. | No | - | failOpen | When `true`, requests continue even if the rate limit service is unavailable. | No (defaults to `false`) | - -2. Create a Kubernetes ReferenceGrant to allow the GatewayExtension to access the Rate Limit Service. Otherwise, you can create the GatewayExtension and {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} in the same namespace as the Rate Limit Service. - - ```yaml - kubectl apply -f - <}} - to: - - group: "" - kind: Service - EOF - ``` - -## Step 4: Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} {#traffic-policy} - -Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource that applies rate limits to your routes. Note that the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} must be in the same namespace as the GatewayExtension to select it. - -The {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} configures the descriptors that define the dimensions for rate limiting. Each descriptor consists of one or more entries that help categorize and count requests. The descriptor entries match on the descriptor keys that you defined previously in the Rate Limit Service. - -Entries can be of one of the following types: `RemoteAddress`, `Path`, `Header`, or `Generic`. You can combine different entry types so that they are applied together as a rate limit, such as `RemoteAddress` and `Generic` or `Header` and `Path`. The following table describes the different descriptor entry types. For more information, see the [API docs](../../reference/api/#ratelimitpolicy). - -| Type | Description | Additional Fields | -|------|-------------|-------------------| -| Header | Extract the descriptor value from a request header. The header name must match a descriptor key in the Rate Limit Service. | `header`: The name of the header to extract. | -| Generic | Use a static key-value pair that you define as the descriptor. | `generic.key`: The descriptor key that matches the descriptor key in the Rate Limit Service.
`generic.value`: The static value for more specific matching. | -| Path | Use the request path as the descriptor value. The `Path` entry type is mapped to the `path` descriptor key in the Rate Limit Service. | None | -| RemoteAddress | Use the client's IP address as the descriptor value. The `RemoteAddress` entry type is mapped to the `remote_address` descriptor key in the Rate Limit Service. | None | - -Flip through the tabs for different example rate limit policies. Note that the examples apply to the Gateway that you created before you began, but you can also apply a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to an HTTPRoute or specific route. - -{{< tabs tabTotal="5" items="Client IP address, Request path, User ID, Nested global rate limits, Local and global rate limits" >}} - -{{% tab tabName="Client IP address" %}} - -Limit requests based on the client's IP address. - -```yaml -kubectl apply -f - <}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: ip-rate-limit - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - rateLimit: - global: - descriptors: - - entries: - - type: RemoteAddress - extensionRef: - name: global-ratelimit -EOF -``` - -{{% /tab %}} - -{{% tab tabName="Request path" %}} - -Limit requests based on the request path, such as a request with `/path1` or `/path2` in the path as defined in the example Rate Limit Service actions. - -```yaml -kubectl apply -f - <}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: request-path - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - rateLimit: - global: - descriptors: - - entries: - - type: Path - extensionRef: - name: global-ratelimit -EOF -``` - -{{% /tab %}} - -{{% tab tabName="User ID" %}} - -Limit requests based on a user ID from an `X-User-ID` header. - -```yaml -kubectl apply -f - <}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: user-rate-limit - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - rateLimit: - global: - descriptors: - - entries: - - type: Header - header: "X-User-ID" - extensionRef: - name: global-ratelimit -EOF -``` - -{{% /tab %}} - -{{% tab tabName="Nested global rate limits" %}} - -Apply different limits based on both path and user ID. The following example requires nested descriptors to rate limit requests along the path and header. - -```yaml -kubectl apply -f - <}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: combined-rate-limit - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - rateLimit: - global: - descriptors: - - entries: - - type: Path - - type: Header - header: "X-User-ID" - extensionRef: - name: global-ratelimit -EOF -``` - -To rate limit based on `/path1` value for path and `user1` value for header, the matching Rate Limit Service must have nested descriptors as follows: - -```yaml -descriptors: - # Level 1: Path - - key: path - value: "/path1" - descriptors: - # Level 2: User ID (nested under path) - - key: X-User-ID - value: "user1" - rate_limit: - unit: minute - requests_per_unit: 2 -``` - -{{% /tab %}} - -{{% tab tabName="Local and global rate limits" %}} - -Combine local and global rate limiting in the same {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} such as in the following example. For more information, see [Local rate limiting](../local). - -* Local: A rate limit of 5 requests per second is applied to all requests. -* Global: A rate limit of 2 requests per minute is applied to requests with a `service` descriptor key of `premium-api`. - -```yaml -kubectl apply -f - <}} -kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -metadata: - name: local-global-rate-limit - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - rateLimit: - local: - tokenBucket: - maxTokens: 5 - tokensPerFill: 1 - fillInterval: "1s" - global: - descriptors: - - entries: - - type: Generic - generic: - key: "service" - value: "premium-api" - extensionRef: - name: global-ratelimit -``` - -{{% /tab %}} - -{{< /tabs >}} - -## Step 5: Test the rate limits {#test-rate-limits} - -Test the rate limits by sending requests to the Gateway. The following steps assume that you created the **client IP address** example {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, which limits requests to 1 request per minute for a particular client IP address. - -1. Send a test request to the httpbin sample app. The request succeeds because you did not exceed the rate limit of 1 request per minute. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/headers -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```txt - HTTP/1.1 200 OK - ... - ``` - -2. Repeat the request. The request fails because you exceeded the rate limit of 1 request per minute. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/headers -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```txt - HTTP/1.1 429 Too Many Requests - ... - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/rate_limit/global/testdata/rate-limit-server.yaml -kubectl delete gatewayextension global-ratelimit -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} ip-rate-limit user-rate-limit combined-rate-limit local-global-rate-limit -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` - diff --git a/assets/docs/pages/security/ratelimit/local.md b/assets/docs/pages/security/ratelimit/local.md deleted file mode 100644 index a2b509cad..000000000 --- a/assets/docs/pages/security/ratelimit/local.md +++ /dev/null @@ -1,408 +0,0 @@ -Limit the number of requests that are allowed to enter the cluster before global {{< gloss "Rate Limiting" >}}rate limiting{{< /gloss >}} and external auth policies are applied. - -## About {#about} - -Local {{< gloss "Rate Limiting" >}}rate limiting{{< /gloss >}} is a coarse-grained rate limiting capability that is primarily used as a first line of defense mechanism to limit the number of requests that are forwarded to your rate limit servers. - -Without local rate limiting, all requests are directly forwarded to a rate limit server that you set up where the request is either denied or allowed based on the global rate limiting settings that you configured. However, during an attack, too many requests might be forwarded to your rate limit servers and can cause overload or even failure. - -To protect your rate limit servers from being overloaded and to optimize their resource utilization, you can set up local rate limiting in conjunction with global rate limiting. Because local rate limiting is enforced in each Envoy instance that makes up your gateway, no rate limit server is required in this setup. For example, if you have 5 Envoy instances that together represent your gateway, each instance is configured with the limit that you set. - -For more information about local rate limiting, see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter). - -### Architecture - -The following image shows how local rate limiting works in {{< reuse "/agw-docs/snippets/kgateway.md" >}}. As clients send requests to a backend destination, they first reach the Envoy instance that represents your gateway. Local rate limiting settings are applied to an Envoy pod or process. Note that limits are applied to each pod or process. For example, if you have 5 Envoy instances that are configured with a local rate limit of 10 requests per second, the total number of allowed requests per second is 50 (5 x 10). In a global rate limiting setup, this limit is shared between all Envoy instances, so the total number of allowed requests per second is 10. - -Depending on your setup, each Envoy instance or pod is configured with a number of tokens in a token bucket. To allow a request, a token must be available in the bucket so that it can be assigned to a downstream connection. Token buckets are refilled occasionally as defined in the refill setting of the local rate limiting configuration. If no token is available, the connection is closed immediately, and a 429 HTTP response code is returned to the client. - -When a token is available in the token bucket it can be assigned to an incoming connection. The request is then forwarded to your rate limit server to enforce any global rate limiting settings. For example, the request might be further rate limited based on headers or query parameters. Only requests that are within the local and global rate limits are forwarded to the backend destination in the cluster. - -{{< reuse-image src="/img/local-rate-limiting.svg" caption="Local rate limiting" width="600px" >}} -{{< reuse-image-dark srcDark="/img/local-rate-limiting.svg" caption="Local rate limiting" width="600px" >}} - -### Local rate limiting - -In {{< reuse "agw-docs/snippets/kgateway.md" >}}, you use a [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}}]({{< link-hextra path="/about/policies/trafficpolicy/" >}}) to set up local rate limiting for your routes. You can choose between the following attachment options: -* **A particular route in an HTTPRoute resource**: Use the `extensionRef` filter in the HTTPRoute to attach the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to the route you want to rate limit. For an example, see [Route configuration](#route). -* **All routes in an HTTPRoute**: Use the `targetRefs` section in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to attach the policy to a particular HTTPRoute resource. -* **All routes that the Gateway serves**: Use the `targetRefs` section in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to attach the policy to a Gateway. For an example, see [Gateway configuration](#gateway). - -Note that if you apply a policy to an HTTPRoute and to a Gateway at the same time, the HTTPRoute policy takes precedence. For more information, see [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}}]({{< link-hextra path="/about/policies/trafficpolicy/#multiple-targetrefs-TrafficPolicies" >}}). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Route configuration {#route} - -Set up local rate limiting for a particular route. - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your local rate limiting settings. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: local-ratelimit - namespace: httpbin - spec: - rateLimit: - local: - tokenBucket: - maxTokens: 1 - tokensPerFill: 1 - fillInterval: 100s - EOF - ``` - - | Setting | Description | - | ------- | ----------- | - | `maxTokens` | The maximum number of tokens that are available to use. | - | `tokensPerFill` | The number of tokens that are added during a refill. | - | `fillIntervall` | The number of seconds, after which the token bucket is refilled. | - -2. Create an HTTPRoute that limits requests to the httpbin app along the `ratelimit.example` domain. To apply the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that created earlier, you use the `extensionRef` filter. - ```yaml - kubectl apply -f- <}} - hostnames: - - ratelimit.example - rules: - - matches: - - path: - type: PathPrefix - value: / - filters: - - type: ExtensionRef - extensionRef: - name: local-ratelimit - group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -3. Send a request to the httpbin app. Verify that you get back a 200 HTTP response code. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: ratelimit.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: ratelimit.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -4. Send another request to the httpbin app. Note that this time the request is denied with a 429 HTTP response code and a `local_rate_limited` message in your CLI output. Because the route is configured with only 1 token that is refilled every 100 seconds, the token was assigned to the connection of the first request. No tokens were available to be assigned to the second request. If you wait for 100 seconds, the token bucket is refilled and a new connection can be accepted by the route. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: ratelimit.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: ratelimit.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - ... - * Mark bundle as not supporting multiuse - < HTTP/1.1 429 Too Many Requests - HTTP/1.1 429 Too Many Requests - < x-ratelimit-limit: 1 - x-ratelimit-limit: 1 - < x-ratelimit-remaining: 0 - x-ratelimit-remaining: 0 - < x-ratelimit-reset: 79 - x-ratelimit-reset: 79 - ... - Connection #0 to host 34.XXX.XX.XXX left intact - local_rate_limited - ``` - -## Gateway configuration {#gateway} - -Instead of applying local rate limiting to a particular route, you can also apply it to an entire gateway. This way, the local rate limiting settings are applied to all the routes that the gateway serves. - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your local rate limiting settings. Use the `targetRefs` section to apply the policy to a specific Gateway. The policy automatically applies to all the routes that the Gateway serves. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: local-ratelimit - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - rateLimit: - local: - tokenBucket: - maxTokens: 1 - tokensPerFill: 1 - fillInterval: 100s - EOF - ``` - - | Setting | Description | - | ------- | ----------- | - | `targetRefs`| Select the Gateway that you want to apply your local rate limiting configuration to. In this example, the policy is applied to all the routes that the `http` gateway serves. | - | `maxTokens` | The maximum number of tokens that are available to use. | - | `tokensPerFill` | The number of tokens that are added during a refill. | - | `fillIntervall` | The number of seconds, after which the token bucket is refilled. | - -3. Send a request to the httpbin app alongside the `www.example.com` domain that you set up as part of the getting started tutorial. Verify that the request succeeds. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -4. Send another request to the httpbin app. Note that this time the request is denied with a 429 HTTP response code and a `local_rate_limited` message in your CLI output. Because the gateway is configured with only 1 token that is refilled every 100 seconds, the token was assigned to the connection of the first request. No tokens were available to be assigned to the second request. If you wait for 100 seconds, the token bucket is refilled and a new connection can be accepted by the gateway. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - ... - * Mark bundle as not supporting multiuse - < HTTP/1.1 429 Too Many Requests - HTTP/1.1 429 Too Many Requests - < x-ratelimit-limit: 1 - x-ratelimit-limit: 1 - < x-ratelimit-remaining: 0 - x-ratelimit-remaining: 0 - < x-ratelimit-reset: 79 - x-ratelimit-reset: 79 - ... - Connection #0 to host 34.XXX.XX.XXX left intact - local_rate_limited - ``` - -## Disable rate limiting for a route {#disable-route} - -Sometimes, you might want to disable {{< gloss "Rate Limiting" >}}rate limiting{{< /gloss >}} for a route. For example, you might have system critical routes that should be accessible even under high traffic conditions, such as a health check or admin endpoints. You can exclude a route from rate limiting by setting `rateLimit.local` to `{}` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. - -1. Create a Gateway-level {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to enforce local rate limiting on all routes. For more information, refer to the [Gateway configuration](#gateway). - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: local-ratelimit - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - rateLimit: - local: - tokenBucket: - maxTokens: 1 - tokensPerFill: 1 - fillInterval: 100s - EOF - ``` - -2. Create an HTTPRoute for the route that you want to exclude from rate limiting, such as `/anything` on the `httpbin` app. Note that because no {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} applies to this HTTPRoute yet, the Gateway-level rate limit policy is enforced for the `/anything` route. - - ```yaml - kubectl apply -f- <}} - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /anything - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -3. Send two requests to verify that the route is rate limited due to the Gateway-level {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that allows only 1 request per 100 seconds. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - for i in {1..2}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - for i in {1..2}; do curl -vi localhost:8080/anything -H "host: www.example.com"; done - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: Verify that the first request succeeds and the second request is rate limited. - - Request 1: - ``` - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - ``` - - Request 2: - ``` - < HTTP/1.1 429 Too Many Requests - HTTP/1.1 429 Too Many Requests - < x-ratelimit-limit: 1 - x-ratelimit-limit: 1 - < x-ratelimit-remaining: 0 - x-ratelimit-remaining: 0 - < x-ratelimit-reset: 79 - x-ratelimit-reset: 79 - ... - Connection #0 to host 34.XXX.XX.XXX left intact - local_rate_limited - ``` - -4. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to disable rate limiting for the HTTPRoute. - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: disable-ratelimit - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin-anything - rateLimit: - local: {} - EOF - ``` - -5. Repeat the requests. This time, the requests succeed because the HTTPRoute is excluded from rate limiting. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - for i in {1..2}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - for i in {1..2}; do curl -vi localhost:8080/anything -H "host: www.example.com"; done - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - Request 1: - ``` - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - ``` - - Request 2: - ``` - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} local-ratelimit -n httpbin -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} local-ratelimit -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} disable-ratelimit -n httpbin -kubectl delete httproute httpbin-ratelimit -n httpbin -kubectl delete httproute httpbin-anything -n httpbin -``` - - - - diff --git a/assets/docs/pages/setup/additional-settings.md b/assets/docs/pages/setup/additional-settings.md deleted file mode 100644 index 0bf510cf5..000000000 --- a/assets/docs/pages/setup/additional-settings.md +++ /dev/null @@ -1,59 +0,0 @@ -Annotate your Gateway listener to enable additional TLS settings, such as the minimum and maximum TLS version, cipher suites, or allowed certificate hashes. - -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: example-gateway - namespace: default -spec: - gatewayClassName: kgateway - listeners: - - name: https - protocol: HTTPS - port: 443 - tls: - mode: Terminate - certificateRefs: - - name: https - kind: Secret - - name: https-mtls-strict-validation - protocol: HTTPS - port: 8443 - tls: - mode: Terminate - certificateRefs: - - name: https - kind: Secret - options: - kgateway.dev/alpn-protocols: "h2" - kgateway.dev/cipher-suites: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" - kgateway.dev/ecdh-curves: "X25519,P-256" - kgateway.dev/min-tls-version: "1.2" - kgateway.dev/max-tls-version: "1.3" - kgateway.dev/verify-subject-alt-names: "example.com" - kgateway.dev/verify-certificate-hash: "46:DB:0D:C2:E1:4F:0A:05:8C:4F:05:8D:77:B1:8D:7C:1A:BE:18:4F:AF:81:BF:E2:B1:CD:03:43:7F:D8:65:4B" - - name: https-insecure-fallback - protocol: HTTPS - port: 9443 - tls: - mode: Terminate - certificateRefs: - - name: https - kind: Secret -``` - - -The following settings are supported: - -| Setting | Description | -| -- | -- | -| `kgateway.dev/alpn-protocols` | A comma-delimited list of the application protocol that the Gateway can use during a TLS handshake. In this example, HTTP/2 is used.| -| `kgateway.dev/cipher-suites` | A comma-delimited list of the cipher suites that the Gateway can use during a TLS handshake. The example shows the TLSv1_2 and TLSv1_3 cipher suites.| -| `kgateway.dev/ecdh-curves` | A comma-delimited list of key exchange protocols. If unset, the Envoy default of `X25519` and `P-256` are used. When adding a new protocol to this list, ensure it is backwards compatible in the case that the client does not specifically support the new protocol. This example adds the Post-Quantum safe key exchange protocol `X25519MLKEM768`, but falls back to the classic `X25519` or `P-256` protocols if the client does not support it. If you want to allow only the Post-Quantum safe protocol, remove the safe protocols and specify `X25519MLKEM768` only. | -| `kgateway.dev/min-tls-version` | Enforce a minimum TLS version for the listener to use. In this example, TLS version 1.2 is used. | -| `kgateway.dev/max-tls-version` | Enforce a maximum TLS version for the Gateway to use. In this example, TLS version 1.3 is used. | -| `kgateway.dev/verify-certificate-hash` | A comma-delimited list of the certificate hash (fingerprint) that must be present in the peer certificate that is presented during the TLS handshake. Use this setting for [mTLS listeners]({{< link-hextra path="/setup/listeners/mtls/" >}}) only. | -| `kgateway.dev/verify-subject-alt-names` | A comma-delimited list of the Subject Alternative Names that must be present in the peer certificate that is presented during the TLS handshake. Use this setting for [mTLS listeners]({{< link-hextra path="/setup/listeners/mtls/" >}}) only. | - - diff --git a/assets/docs/pages/setup/customize.md b/assets/docs/pages/setup/customize.md deleted file mode 100644 index 75c574248..000000000 --- a/assets/docs/pages/setup/customize.md +++ /dev/null @@ -1,167 +0,0 @@ -The configuration that is used to spin up a gateway proxy is stored in several custom resources, including {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}, and a gateway proxy template. By default, {{< reuse "agw-docs/snippets/kgateway.md" >}} creates these resources for you during the installation so that you can spin up gateway proxies with the [default proxy configuration]({{< link-hextra path="/setup/default/" >}}). You have the following options to change the default configuration for your gateway proxies: - -| Option | Description | -| -- | -- | -| Create your own {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource (recommended) | To adjust the settings on the gateway proxy, you can create your own {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. This approach allows you to spin up gateway proxies with different configurations. Keep in mind that you must maintain the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resources that you created manually. The values in these resources are not automatically updated during upgrades. | -| Change default proxy settings | You can change some of the values for the default gateway proxy updating the values in the {{< reuse "agw-docs/snippets/kgateway.md" >}} Helm chart. The values that you set in your Helm chart are automatically rolled out to the gateway proxies. | -| Create self-managed gateways with custom proxy templates | {{< reuse "agw-docs/snippets/byo-gateway.md" >}} | - -## Customize the gateway proxy - -The example in this guide uses the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource to change settings on the gateway proxy. To find other customization examples, see the [Gateway customization guides]({{< link-hextra path="/setup/customize/" >}}). - -1. Create a {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource to add any custom settings to the gateway. The following example makes the following changes: - - * The Envoy log level is set to `debug` (default value: `info`). - * The Kubernetes service type is changed to NodePort (default value: `LoadBalancer`). - * The `gateway: custom` label is added to the gateway proxy service that exposes the proxy (default value: `gloo=kube-gateway`). - * The `externalTrafficPolicy` is set to `Local` to preserve the original client IP address. - * The `gateway: custom` label is added to the gateway proxy pod (default value: `gloo=kube-gateway` ). - * The security context of the gateway proxy is changed to use the 50000 as the supplemental group ID and user ID (default values: `10101` ). - - For other settings, see the [API docs]({{< link-hextra path="/reference/api/#gatewayparametersspec" >}}) or check out the [Gateway customization guides]({{< link-hextra path="/setup/customize/" >}}). - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - metadata: - name: custom-gw-params - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - kube: - envoyContainer: - bootstrap: - logLevel: debug - service: - type: NodePort - extraLabels: - gateway: custom - - externalTrafficPolicy: Local - - podTemplate: - extraLabels: - gateway: custom - securityContext: - fsGroup: 50000 - runAsUser: 50000 - EOF - ``` - -2. Create a Gateway resource that references your custom {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - infrastructure: - parametersRef: - name: custom-gw-params - group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}} - kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} - listeners: - - protocol: HTTP - port: 80 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. Verify that a pod is created for your gateway proxy and that it has the pod settings that you defined in the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. - - ```sh - kubectl get pods -l app.kubernetes.io/name=custom -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml - ``` - - If the pod does not come up, try running `kubectl get events -n kgateway-system` to see if the Kubernetes API server logged any failures. If no events are logged, ensure that the `kgateway` GatewayClass is present in your cluster and that the Gateway resource shows an `Accepted` status. - - Example output: - - ```yaml {linenos=table,hl_lines=[13,20,21,22],linenostart=1,filename="gateway-pod.yaml"} - apiVersion: v1 - kind: Pod - metadata: - annotations: - prometheus.io/path: /metrics - prometheus.io/port: "9091" - prometheus.io/scrape: "true" - creationTimestamp: "2024-08-07T19:47:27Z" - generateName: custom-7d9bf46f96- - labels: - app.kubernetes.io/instance: custom - app.kubernetes.io/name: custom - gateway: custom - gateway.networking.k8s.io/gateway-name: custom - kgateway: kube-gateway - ... - priority: 0 - restartPolicy: Always - schedulerName: default-scheduler - securityContext: - fsGroup: 50000 - runAsUser: 50000 - ... - ``` - -4. Get the details of the service that exposes the gateway proxy. Verify that the service is of type NodePort and that the extra label was added to the service. - - ```sh - kubectl get service custom -n kgateway-system -o yaml - ``` - - Example output: - - ```yaml {linenos=table,hl_lines=[10,36],linenostart=1,filename="gateway-service.yaml"} - apiVersion: v1 - kind: Service - metadata: - creationTimestamp: "2024-08-07T19:47:27Z" - labels: - app.kubernetes.io/instance: custom - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: custom - app.kubernetes.io/version: kgateway-proxy-v{{< reuse "agw-docs/versions/n-patch.md" >}} - gateway: custom - gateway.networking.k8s.io/gateway-name: custom - kgateway: kube-gateway - helm.sh/chart: kgateway-proxy-v{{< reuse "agw-docs/versions/n-patch.md" >}} - name: custom - namespace: kgateway-system - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1 - controller: true - kind: Gateway - name: custom - uid: d29417ba-60f9-410c-a023-283b250f3d57 - resourceVersion: "7371789" - uid: 67945b5f-e55f-42bb-b5f2-c35932659831 - spec: - ports: - - name: http - nodePort: 30579 - port: 80 - protocol: TCP - targetPort: 8080 - selector: - app.kubernetes.io/instance: custom - app.kubernetes.io/name: custom - gateway.networking.k8s.io/gateway-name: custom - sessionAffinity: None - type: NodePort - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gateway custom -n kgateway-system -kubectl delete {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} custom-gw-params -n kgateway-system -``` diff --git a/assets/docs/pages/setup/customize/aws-elb/alb.md b/assets/docs/pages/setup/customize/aws-elb/alb.md deleted file mode 100644 index 8543147d7..000000000 --- a/assets/docs/pages/setup/customize/aws-elb/alb.md +++ /dev/null @@ -1,183 +0,0 @@ -In this guide you explore how to expose the kgateway proxy with an AWS application load balancer (ALB). - -{{< callout type="warning" >}} -The AWS Load Balancer Controller only supports the creation of an ALB through an Ingress Controller and not through the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}. Because of this, you must create the ALB separately through an Ingress resource that connects it to the service that exposes your gateway proxy. -{{< /callout >}} - -## Before you begin - -1. Create or use an existing AWS account. -2. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway. You do not need to set up a Gateway as you create a custom Gateway as part of this guide. -3. Follow the [Sample app guide]({{< link-hextra path="/install/sample-app/" >}}) to deploy the httpbin sample app. - -## Step 1: Deploy gateway proxy resources - -1. Create a Gateway resource with an HTTP listener. You later pair this Gateway with an AWS ALB. - ```yaml - kubectl apply -n kgateway-system -f- <}} - -5. Use an Ingress resource to define your ALB. When you apply this resource, the AWS Load Balancer Controller creates the ALB in your account. - ```yaml - kubectl apply -f- <}} - If you later change your Ingress resource configuration, you might need to delete and re-create your Ingress resource for AWS to pick up the changes. - {{< /callout >}} - -6. Review the load balancer in the AWS EC2 dashboard. - 1. Go to the [AWS EC2 dashboard](https://console.aws.amazon.com/ec2). - 2. In the left navigation, go to **Load Balancing > Load Balancers**. - 3. Find and open the ALB that was created for you, with a name such as `k8s-gateway-alb-`. Note that it might take a few minutes for the ALB to provision. - 4. On the **Resource map** tab, verify that the load balancer points to healthy EC2 targets in your cluster. For example, you can click on the target EC2 name to verify that the instance summary lists your cluster name. - {{< reuse-image src="img/alb.png" >}} - {{< reuse-image-dark srcDark="img/alb.png" >}} - -## Step 3: Test the ALB - -1. In the **Details** pane of the ALB, get the **DNS name** that was assigned to your ALB and save it as an environment variable. - ```sh - export INGRESS_GW_ADDRESS= - ``` - -2. Send a request to the httpbin app. Verify that you get back a 200 HTTP response code. - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:80/headers -H "host: albtest.com:80" - ``` - - Example output: - ```console - ... - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the Ingress, HTTPRoute, DirectResponse, and Gateway resources. - ```sh - kubectl delete ingress alb -n kgateway-system - kubectl delete httproute httpbin-alb -n httpbin - kubectl delete httproute httpbin-healthcheck -n httpbin - kubectl delete directresponse httpbin-healthcheck-dr -n httpbin - kubectl delete gateway alb -n kgateway-system - ``` - -2. Delete the AWS IAM resources that you created. - ```sh - aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME} - eksctl delete iamserviceaccount --name=${IAM_SA} --cluster=${CLUSTER_NAME} - ``` - -3. Uninstall the Helm release for the `aws-load-balancer-controller`. - ```sh - helm uninstall aws-load-balancer-controller -n kube-system - ``` - - - - - diff --git a/assets/docs/pages/setup/customize/aws-elb/nlb.md b/assets/docs/pages/setup/customize/aws-elb/nlb.md deleted file mode 100644 index 9eeeb5e9b..000000000 --- a/assets/docs/pages/setup/customize/aws-elb/nlb.md +++ /dev/null @@ -1,293 +0,0 @@ -In this guide you explore how to expose the kgateway proxy with an AWS network load balancer (NLB). The following use cases are covered: - -* **NLB HTTP**: Create an HTTP listener on the NLB that exposes an HTTP endpoint on your gateway proxy. Traffic from the NLB to the proxy is not secured. -* **TLS passthrough**: Expose an HTTPS endpoint of your gateway with an NLB. The NLB passes through HTTPS traffic to the gateway proxy where the traffic is terminated. - -{{< callout type="warning" >}} -Keep in mind the following considerations when working with an NLB: -* An AWS NLB has an idle timeout of 350 seconds that you cannot change. This limitation can increase the number of reset TCP connections. -{{< /callout >}} - -## Before you begin - -1. Create or use an existing AWS account. -2. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway, set up a gateway resource, and deploy the httpbin sample app. - -## Step 1: Deploy the AWS Load Balancer controller - -{{< reuse "agw-docs/snippets/aws-elb-controller-install.md" >}} - -## Step 2: Deploy your gateway proxy - -1. Create a GatewayParameters resource with custom AWS annotations. These annotations instruct the AWS load balancer controller to expose the gateway proxy with a public-facing AWS NLB. - ```yaml - kubectl apply -f- <}} - {{% tab %}} - - Create a simple NLB that accepts HTTP traffic on port 80 and forwards this traffic to the HTTP listener on your gateway proxy. - - {{< reuse-image src="/img/elb-http.svg" >}} - {{< reuse-image-dark srcDark="/img/elb-http.svg" >}} - - This Gateway resource references the custom GatewayParameters resource that you created. - ```yaml - kubectl apply -f- <}} - {{< reuse-image-dark srcDark="/img/elb-tls-passthrough.svg" >}} - - 1. Create a self-signed TLS certificate to configure your gateway proxy with an HTTPS listener. - {{< reuse "agw-docs/snippets/listeners-https-create-cert.md" >}} - - 2. Create a Gateway with an HTTPS listener that terminates incoming TLS traffic. Make sure to reference the custom GatewayParameters resource and the Kubernetes secret that contains the TLS certificate information. - ```yaml - kubectl apply -f- <}} - -3. Verify that your gateway is created. - ```sh - kubectl get gateway aws-cloud -n kgateway-system - ``` - -4. Verify that the gateway service is exposed with an AWS NLB and assigned an AWS hostname. - ```sh - kubectl get services aws-cloud -n kgateway-system - ``` - - Example output: - ```console - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - aws-cloud LoadBalancer 172.20.39.233 k8s-kgateway-awscloud-edaaecf0c5-2d48d93624e3a4bf.elb.us-east-2.amazonaws.com 80:30565/TCP 12s - ``` - -5. Review the NLB in the AWS EC2 dashboard. - 1. Go to the [AWS EC2 dashboard](https://console.aws.amazon.com/ec2). - 2. In the left navigation, go to **Load Balancing > Load Balancers**. - 3. Find and open the NLB that was created for you, with a name such as `k8s-kgateway-awscloud-`. - 4. On the **Resource map** tab, verify that the load balancer points to EC2 targets in your cluster. For example, you can click on the target EC2 name to verify that the instance summary lists your cluster name. - -## Step 3: Test traffic to the NLB {#test-traffic} - -{{< tabs items="Simple HTTP NLB,TLS passthrough" >}} -{{% tab %}} - -1. Create an HTTPRoute resource and associate it with the gateway that you created. - ```yaml - kubectl apply -f- <}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the Ingress and Gateway resources. - ```sh - kubectl delete gatewayparameters custom-gw-params -n kgateway-system - kubectl delete gateway aws-cloud -n kgateway-system - kubectl delete httproute httpbin-elb -n httpbin - kubectl delete secret tls -n kgateway-system - ``` - -2. Delete the AWS IAM resources that you created. - ```sh - aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME} - eksctl delete iamserviceaccount --name=${IAM_SA} --cluster=${CLUSTER_NAME} - ``` - -3. Uninstall the Helm release for the `aws-load-balancer-controller`. - ```sh - helm uninstall aws-load-balancer-controller -n kube-system - ``` - - - - - diff --git a/assets/docs/pages/setup/default.md b/assets/docs/pages/setup/default.md deleted file mode 100644 index e85725d24..000000000 --- a/assets/docs/pages/setup/default.md +++ /dev/null @@ -1,29 +0,0 @@ -Learn about the different {{< reuse "agw-docs/snippets/kgateway.md" >}} and Kubernetes resources that make up your gateway proxy deployment. - -## GatewayClass - -The GatewayClass is a {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}-native resource that defines the controller that spins up and configures gateway proxies in your environment. - -When you install {{< reuse "agw-docs/snippets/kgateway.md" >}}, the following GatewayClass resources are automatically created with the following configuration. - -{{< reuse "agw-docs/snippets/class-setup.md" >}} - -## Gateway proxy template - -When you create a Gateway resource, a default gateway proxy template for [agentgateway](https://github.com/kgateway-dev/kgateway/blob/{{< reuse "agw-docs/versions/github-branch.md" >}}/pkg/kgateway/helm/agentgateway/templates/deployment.yaml) proxies is used to automatically spin up and bootstrap a gateway proxy deployment and service in your cluster. The template includes agentgateway configuration that binds the gateway proxy deployment to the Gateway resource that you created. In addition, the settings in the [{{< reuse "agw-docs/snippets/gatewayparameters.md" >}}](#gatewayparameters) resource are used to configure the gateway proxy. - -The resulting gateway proxy is managed for you and its configuration is automatically updated based on the settings in the GatewayParameters resource. To publicly expose the gateway proxy deployment, a service of type LoadBalancer is created for you. Depending on the cloud provider that you use, the LoadBalancer service is assigned a public IP address or hostname that you can use to reach the gateway. To expose an app on the gateway, you must create an HTTPRoute resource and define the matchers and filter rules that you want to apply before forwarding the request to the app in your cluster. You can review the [Get started]({{< link-hextra path="/quickstart/" >}}), [traffic management]({{< link-hextra path="/traffic-management/" >}}), [security]({{< link-hextra path="/security/" >}}), and [resiliency]({{< link-hextra path="/resiliency/" >}}) guides to find examples for how to route and secure traffic to an app. - -You can change the default configuration of your gateway proxy by creating custom {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resources, or updating the default {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} values in your {{< reuse "agw-docs/snippets/kgateway.md" >}} Helm chart. If you change the values in the Helm chart, {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically applies the changes to the default {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resources. - -{{< callout type="info" >}} -Do not edit or change the default {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource directly. Always update the values in the {{< reuse "agw-docs/snippets/kgateway.md" >}} Helm chart so that they persist between upgrades. -{{< /callout >}} - -## {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} {#gatewayparameters} - -{{< reuse "agw-docs/snippets/gatewayparameters-about.md" >}} - -## Reserved ports - -{{< reuse "agw-docs/snippets/reserved-ports.md" >}} diff --git a/assets/docs/pages/setup/hpa.md b/assets/docs/pages/setup/hpa.md deleted file mode 100644 index 4aba3b404..000000000 --- a/assets/docs/pages/setup/hpa.md +++ /dev/null @@ -1,99 +0,0 @@ -You can bring your own Horizontal Pod Autoscaler (HPA) plug-in to {{< reuse "agw-docs/snippets/kgateway.md" >}}. This way, you can automatically scale gateway proxy pods up and down based on certain thresholds, like memory and CPU consumption. - -To allow integration with HPA plug-ins, do not specify any custom replicas in the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. This way, your HPA plug-in can scale the proxy based on your autoscaling strategy. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up your own HPA plug-in - -1. Deploy the Kubernetes `metrics-server` in your cluster. The `metrics-server` retrieves metrics, such as CPU and memory consumption for your workloads. These metrics can be used by the HPA plug-in to determine if the pod must be scaled up or down. - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml - kubectl -n kube-system patch deployment metrics-server \ - --type=json \ - -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]' - ``` - - Example output: - ```console - serviceaccount/metrics-server created - clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created - clusterrole.rbac.authorization.k8s.io/system:metrics-server created - rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created - clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server:system:auth-delegator created - clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created - service/metrics-server created - deployment.apps/metrics-server configured - apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created - ``` - -2. Review the metrics for the http Gateway. - ```sh - kubectl top pod -n {{< reuse "agw-docs/snippets/namespace.md" >}} | grep http - ``` - - Example output: - ``` - http-594455765c-5szpq 3m 19Mi - ``` - -6. Create a HorizontalPodAutoscaler resource that scales your gateway proxy up to 10 replicas if the memory consumption exceeds 10Mi. You can adjust this value depending on the memory value that you retrieved in the previous step. - ```yaml - kubectl apply -f- <}} - spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: http - minReplicas: 1 - maxReplicas: 10 - metrics: - - type: Resource - resource: - name: memory - target: - type: AverageValue - averageValue: 10Mi - EOF - ``` - -7. Wait a few minutes for Kubernetes to scale up your gateway proxies. Then, check the number of `http` pods that were created. Because every pod exceeds the memory threshold that you defined in the HPA policy, Kubernetes scales up the pods to the 10 maximum replicas. - ```sh - kubectl top pod -n {{< reuse "agw-docs/snippets/namespace.md" >}} | grep http - ``` - - Example output: - ``` - http-594455765c-5szpq 3m 19Mi - http-594455765c-gvf9g 3m 19Mi - http-594455765c-h2zb9 3m 19Mi - http-594455765c-mghsf 3m 19Mi - http-594455765c-n6prj 3m 19Mi - http-594455765c-nvs6c 3m 19Mi - http-594455765c-srfcz 3m 19Mi - http-594455765c-ssvjx 3m 19Mi - http-594455765c-tx2z6 3m 19Mi - http-594455765c-vxjbp 3m 19Mi - ``` - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete hpa hpa -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -``` - - - - - diff --git a/assets/docs/pages/setup/http10.md b/assets/docs/pages/setup/http10.md deleted file mode 100644 index e78f5963b..000000000 --- a/assets/docs/pages/setup/http10.md +++ /dev/null @@ -1,62 +0,0 @@ -Configure your gateway proxy to accept older HTTP protocols. - -## About HTTP/1.0 and HTTP/0.9 - -By default, Envoy-based gateway proxies return a 426 Upgrade Required HTTP response code for HTTP/1.0 and HTTP/0.9 requests. HTTP/0.9 was a simple, rudimentary protocol that was introduced in 1991 and supported only the `GET` HTTP method. Other methods, such as `POST`, `PUT`, and `DELETE` were later introduced in HTTP/1.0. - -Both protocol versions are rarely used nowadays. However, some applications might still require support for these versions for backwards compatibililty. To allow the gateway proxy to accept these types of requests, you can create an HTTPListenerPolicy and attach it to your Gateway. - -{{< callout >}} -{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}} -{{< /callout >}} - - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-listeners.md" >}} - -## Set up HTTP 1.0 support - -1. Create an HTTPListenerPolicy with the `acceptHttp10` field. In the `targetRefs`, attach the policy to the Gateway that you want to support the HTTP/1.0 protocol. - ```yaml - kubectl apply -f- <}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - acceptHttp10: true - EOF - ``` - -2. Port-forward the gateway proxy on port 19000 to open the Envoy admin interface. - ```sh - kubectl port-forward deploy/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000 - ``` - -3. Open the [Envoy admin interface](http://localhost:19000/config_dump) and look for the `http_protocol_options` filter in your Envoy filter chain. Then, verify that the `accept_http_10` field is set to `true`. - - Example output: - ```console - "http_protocol_options": { - "accept_http_10": true - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httplistenerpolicy accept-http10 -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` - - - - - diff --git a/assets/docs/pages/setup/listener-mtls.md b/assets/docs/pages/setup/listener-mtls.md deleted file mode 100644 index 4ed47a9c0..000000000 --- a/assets/docs/pages/setup/listener-mtls.md +++ /dev/null @@ -1,731 +0,0 @@ -Add a [FrontendTLSConfig](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#frontendtlsconfig) to a Gateway to create a mutual TLS (mTLS) listener. - -## About FrontendTLS - -When configuring an mTLS listener on a Gateway, the client application and the Gateway must exchange certificates to verify their identities before a connection can be established. After a TLS connection is established, the TLS connection is terminated at the Gateway and the unencrypted HTTP traffic is forwarded to the backend destination. - -FrontendTLS supports the following configurations: - -* **Default (required)**: Create the default client certificate validation configuration for all Gateway listeners that handle HTTPS traffic. For an example, see the [Default configuration for all listeners](#default) guide. -* **perPort (optional)**: Override the default configuration with port-specific configuration. The configuration is applied only to matching ports that handle HTTPS traffic. For all other ports that handle HTTPS traffic, the default configuration continues to apply. For an example, see the [Per port configuration](#perport) guide. - -In addition, you can choose between the following validation modes: -* **AllowValidOnly**: A connection between a client and the gateway proxy can only be established if the gateway can validate the client's TLS certificate successfully. For an example, see the [Default configuration for all listeners](#default) guide. -* **AllowInsecureFallback**: The gateway proxy can establish a TLS connection, even if the client TLS certificate could not be validated successfully. For an example, see the [Per port configuration](#perport) guide. - -## About this guide - -In this guide, you learn how to apply default certificate validation configuration for all HTTPS listeners on a Gateway and how to override this configuration for a specific port. You further explore secure and insecure certificate validation modes, and use TLS annotations to limit connections to clients that present certificates with a specific Subject Alt Name and certificate hash. - -Throughout this guide, you use self-signed TLS certificates for the Certificate Authority. These certificates are used to sign the TLS certificates for the gateway proxy (server) and httpbin client. - -{{< callout type="warning" >}} -Self-signed certificates are used for demonstration purposes. Do not use self-signed certificates in production environments. Instead, use certificates that are issued from a trust Certificate Authority. -{{< /callout >}} - -## Before you begin - -{{< reuse "agw-docs/snippets/cert-prereqs.md" >}} - -5. Install the experimental channel of the Kubernetes Gateway API. This API is required to use the FrontendTLS configuration on a Gateway. - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml - ``` - - -## Create TLS certificates - -Create self-signed TLS certificates that you use for the mutual TLS connection between your client application (`curl`) and the gateway proxy. - -{{< callout type="warning" >}} -Self-signed certificates are used for demonstration purposes. Do not use self-signed certificates in production environments. Instead, use certificates that are issued from a trust Certificate Authority. -{{< /callout >}} - - - -1. Create the `example_certs` directory and navigate into this directory. - ```sh - mkdir example_certs && cd example_certs - ``` - -2. Create self-signed certificates for the Certificate Authority (CA) that you later use to sign the server and client certificates. - ```sh - # Create CA private key - openssl genrsa -out ca-key.pem 2048 - - # Create CA certificate (valid for 1 year) - openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem \ - -subj "/CN=Test CA/O=Test Org" - ``` - -3. Create the server certificates for the Gateway that is signed by the CA that you created in the previous step. The Gateway uses these certificates to terminate incoming TLS connections. - ```sh - # Create server private key - openssl genrsa -out server-key.pem 2048 - - # Create server certificate signing request - openssl req -new -key server-key.pem -out server.csr \ - -subj "/CN=example.com/O=Test Org" - - # Create server certificate signed by CA (valid for 1 year) - openssl x509 -req -days 365 -in server.csr -CA ca-cert.pem -CAkey ca-key.pem \ - -CAcreateserial -out server-cert.pem \ - -extensions v3_req -extfile <(echo "[v3_req]"; echo "subjectAltName=DNS:example.com,DNS:*.example.com") - ``` - -4. Store the server certificate and key in a Kubernetes secret. - ```yaml - # Base64 encode server certificate and key - SERVER_CERT=$(cat server-cert.pem | base64 -w 0) - SERVER_KEY=$(cat server-key.pem | base64 -w 0) - - # Create the secret - kubectl create secret tls https-cert \ - --cert=server-cert.pem \ - --key=server-key.pem \ - -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -5. Store the CA certificates in a configmap. The gateway proxy later uses these certificates to validate the client certificate that is presented during the TLS handshake. - ```sh - kubectl create configmap ca-cert \ - --from-file=ca.crt=ca-cert.pem \ - -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -6. Create a client certificate and private key. You use these credentials later when sending a request to the gateway proxy. The client certificate is signed by the same CA that you used for the gateway proxy. - ```sh - # Create client private key - openssl genrsa -out client-key.pem 2048 - - # Create client certificate signing request - openssl req -new -key client-key.pem -out client.csr \ - -subj "/CN=client.example.com/O=Test Org" - - # Create client certificate signed by CA (valid for 1 year) - openssl x509 -req -days 365 -in client.csr -CA ca-cert.pem -CAkey ca-key.pem \ - -CAcreateserial -out client-cert.pem \ - -extensions v3_req -extfile <(echo "[v3_req]"; echo "subjectAltName=DNS:example.com,DNS:*.example.com") - ``` - -7. Continue with configuring a [Default configuration for all listeners](#default). Alternatively, you can explore how to [override the default configuration for a specific port](#perport). - - -## Default configuration for all listeners {#default} - -1. Create a Gateway with a default frontend TLS configuration that applies to all listeners that handle HTTPS traffic. The following example configures two HTTPS listeners on the Gateway. Both listeners use the same server TLS credentials to terminate incoming HTTPS connections. The validation mode is set to `AllowValidOnly` to allow connection only if a valid certificate is presented during the TLS handshake. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - tls: - frontend: - default: - validation: - mode: AllowValidOnly - caCertificateRefs: - - name: ca-cert - kind: ConfigMap - group: "" - listeners: - - name: https-8443 - protocol: HTTPS - port: 8443 - tls: - mode: Terminate - certificateRefs: - - name: https-cert - kind: Secret - allowedRoutes: - namespaces: - from: All - - name: https-8444 - protocol: HTTPS - port: 8444 - tls: - mode: Terminate - certificateRefs: - - name: https-cert - kind: Secret - allowedRoutes: - namespaces: - from: All - EOF - ``` - -2. Create an HTTPRoute that routes incoming traffic on the `example.com` domain to the mTLS Gateway that you created. - ```yaml - kubectl apply -f- <}} - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -5. Get the external address of the gateway and save it in an environment variable. Note that it might take a few seconds for the gateway address to become available. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing">}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} mtls -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deploy/mtls -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:8443 8444:8444 - ``` - {{% /tab %}} - {{< /tabs >}} - -6. Send a request to the httpbin app without a client certificate on both 8443 and 8444 ports. Verify that the TLS handshake fails, because a TLS certificate is required to establish the connection. - {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address" %}} - ```sh - curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get - - curl -v -k --resolve "example.com:8444:${INGRESS_GW_ADDRESS}" https://example.com:8444/get - ``` - {{% /tab %}} - {{% tab tabName="LoadBalancer hostname" %}} - ```sh - curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get - - curl -v -k --resolve "example.com:8444:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8444/get - ``` - - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -v -k https://localhost:8443/get \ - --resolve example.com:8443:127.0.0.1 \ - -H "Host: example.com" - - curl -v -k https://localhost:8444/get \ - --resolve example.com:8444:127.0.0.1 \ - -H "Host: example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - - Example output: - ``` - * LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0 - * Failed receiving HTTP2 data: 56(Failure when receiving data from the peer) - * Connection #0 to host localhost left intact - curl: (56) LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0 - ``` - -7. Repeat the request. This time, you include the client certificate that you created earlier. - {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address" %}} - ```sh - curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - - curl -v -k --resolve "example.com:8444:${INGRESS_GW_ADDRESS}" https://example.com:8444/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - {{% /tab %}} - {{% tab tabName="LoadBalancer hostname" %}} - ```sh - curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - - curl -v -k --resolve "example.com:8444:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8444/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -v -k https://localhost:8443/get \ - --resolve example.com:8443:127.0.0.1 \ - -H "Host: example.com" \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - - curl -v -k https://localhost:8444/get \ - --resolve example.com:8444:127.0.0.1 \ - -H "Host: example.com" \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output for port 8444: - ``` - * Connection #0 to host localhost left intact - * Added example.com:8444:127.0.0.1 to DNS cache - * Host localhost:8444 was resolved. - * IPv6: ::1 - * IPv4: 127.0.0.1 - * Trying [::1]:8444... - * Connected to localhost (::1) port 8444 - * ALPN: curl offers h2,http/1.1 - * (304) (OUT), TLS handshake, Client hello (1): - * (304) (IN), TLS handshake, Server hello (2): - * (304) (IN), TLS handshake, Unknown (8): - * (304) (IN), TLS handshake, Request CERT (13): - * (304) (IN), TLS handshake, Certificate (11): - * (304) (IN), TLS handshake, CERT verify (15): - * (304) (IN), TLS handshake, Finished (20): - * (304) (OUT), TLS handshake, Certificate (11): - * (304) (OUT), TLS handshake, CERT verify (15): - * (304) (OUT), TLS handshake, Finished (20): - * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF - * ALPN: server accepted h2 - * Server certificate: - * subject: CN=example.com; O=Test Org - * start date: Jan 13 20:19:17 2026 GMT - * expire date: Jan 13 20:19:17 2027 GMT - * issuer: CN=Test CA; O=Test Org - * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. - * using HTTP/2 - * [HTTP/2] [1] OPENED stream for https://localhost:8444/get - * [HTTP/2] [1] [:method: GET] - * [HTTP/2] [1] [:scheme: https] - * [HTTP/2] [1] [:authority: example.com] - * [HTTP/2] [1] [:path: /get] - * [HTTP/2] [1] [user-agent: curl/8.7.1] - * [HTTP/2] [1] [accept: */*] - > GET /get HTTP/2 - > Host: example.com - > User-Agent: curl/8.7.1 - > Accept: */* - - * Request completely sent off - < HTTP/2 200 - < access-control-allow-credentials: true - < access-control-allow-origin: * - < content-type: application/json; encoding=utf-8 - < date: Tue, 13 Jan 2026 21:59:07 GMT - < content-length: 515 - < x-envoy-upstream-service-time: 1 - < server: envoy - ... - ``` - - -## Per port configuration {#perport} - -In this example, you override the default certificate validation configuration for port 8444. - -1. Update your Gateway to add in port-specific validation configuration for port 8444. In the following example, you override the default certificate validation for port 8444. This configuration allows requests, even if an invalid certificate was presented during the TLS handshake. Port 8443 continues to only allow connections if a valid certificate is presented. - ```yaml {hl_lines=[18,19,20,21,22,23,24,25,26]} - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - tls: - frontend: - default: - validation: - mode: AllowValidOnly - caCertificateRefs: - - name: ca-cert - kind: ConfigMap - group: "" - perPort: - - port: 8444 - tls: - validation: - mode: AllowInsecureFallback - caCertificateRefs: - - name: ca-cert - kind: ConfigMap - group: "" - listeners: - - name: https-8443 - protocol: HTTPS - port: 8443 - tls: - mode: Terminate - certificateRefs: - - name: https-cert - kind: Secret - allowedRoutes: - namespaces: - from: All - - name: https-8444 - protocol: HTTPS - port: 8444 - tls: - mode: Terminate - certificateRefs: - - name: https-cert - kind: Secret - allowedRoutes: - namespaces: - from: All - EOF - ``` - -2. If you have not done so yet, get the external address of the gateway and save it in an environment variable. Note that it might take a few seconds for the gateway address to become available. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing">}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} mtls -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deploy/mtls -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:8443 8444:8444 - ``` - {{% /tab %}} - {{< /tabs >}} - -3. Send a request to the httpbin app on both ports without a valid certificate. Verify that the request on port 8443 fails, because the default validation configuration does not allow to establish a connection without a valid certificate. The connection on port 8444 however is established as the port-specific validation configuration mode is set to `AllowInsecureFallback`. - {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address" %}} - ```sh - curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get - - curl -v -k --resolve "example.com:8444:${INGRESS_GW_ADDRESS}" https://example.com:8444/get - ``` - {{% /tab %}} - {{% tab tabName="LoadBalancer hostname" %}} - ```sh - curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get - - curl -v -k --resolve "example.com:8444:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8444/get - ``` - - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -v -k https://localhost:8443/get \ - --resolve example.com:8443:127.0.0.1 \ - -H "Host: example.com" - - curl -v -k https://localhost:8444/get \ - --resolve example.com:8444:127.0.0.1 \ - -H "Host: example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output for port 8443: - ``` - * LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0 - * Failed receiving HTTP2 data: 56(Failure when receiving data from the peer) - * Connection #0 to host localhost left intact - curl: (56) LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0 - ``` - - Example output for port 8444: - ``` - ... - * Request completely sent off - < HTTP/2 200 - ... - ``` - -4. Repeat the request with a valid certificate. Verify that both requests succeed. - {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address" %}} - ```sh - curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - - curl -v -k --resolve "example.com:8444:${INGRESS_GW_ADDRESS}" https://example.com:8444/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - {{% /tab %}} - {{% tab tabName="LoadBalancer hostname" %}} - ```sh - curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - - curl -v -k --resolve "example.com:8444:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8444/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -v -k https://localhost:8443/get \ - --resolve example.com:8443:127.0.0.1 \ - -H "Host: example.com" \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - - curl -v -k https://localhost:8444/get \ - --resolve example.com:8444:127.0.0.1 \ - -H "Host: example.com" \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - {{% /tab %}} - {{< /tabs >}} - -## Additional TLS settings - -You can configure your mTLS listener to limit connections to clients that present a certificate with a specific certificate hash and Subject Alternative Names. Alternatively, you can configure your listeners to enforce other TLS settings, such as a minimum or maximum TLS version, specific cipher suites, or CSDH curves. For more information, see [Additional TLS settings]({{< link-hextra path="/setup/listeners/tls-settings/" >}}). - - -1. Get the certificate hash of the client certificate. - ```sh - openssl x509 -in client-cert.pem -noout -fingerprint -sha256 - ``` - - Example output: - ``` - sha256 Fingerprint=46:DB:0D:C2:E1:4F:0A:05:8C:4F:05:8D:77:B1:8D:7C:1A:BE:18:4F:AF:81:BF:E2:B1:CD:03:43:7F:D8:65:4B - ``` - -2. Update port 8443 on the Gateway to allow connections only if the client certificate includes a specific hash and Subject Alt Name. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - tls: - frontend: - default: - validation: - mode: AllowValidOnly - caCertificateRefs: - - name: ca-cert - kind: ConfigMap - group: "" - listeners: - - name: https-8443 - protocol: HTTPS - port: 8443 - tls: - mode: Terminate - certificateRefs: - - name: https-cert - kind: Secret - options: - kgateway.dev/verify-subject-alt-names: "example.com" - kgateway.dev/verify-certificate-hash: "46:DB:0D:C2:E1:4F:0A:05:8C:4F:05:8D:77:B1:8D:7C:1A:BE:18:4F:AF:81:BF:E2:B1:CD:03:43:7F:D8:65:4B" - allowedRoutes: - namespaces: - from: All - EOF - ``` - - | Setting | Description | - | -- | -- | - | `kgateway.dev/verify-certificate-hash` | A comma-delimited list of the certificate hash (fingerprint) that must be present in the peer certificate that is presented during the TLS handshake. | - | `kgateway.dev/verify-subject-alt-names` | A comma-delimited list of the Subject Alternative Names that must be present in the peer certificate that is presented during the TLS handshake. | - -3. Send a request to the httpbin app with your client certificate. Verify that the request succeeds. - {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address" %}} - ```sh - curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - {{% /tab %}} - {{% tab tabName="LoadBalancer hostname" %}} - ```sh - curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - - ``` - - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -v -k https://localhost:8443/get \ - --resolve example.com:8443:127.0.0.1 \ - -H "Host: example.com" \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Added example.com:8443:172.18.0.10 to DNS cache - * Hostname example.com was found in DNS cache - * Trying 172.18.0.10:8443... - * Connected to example.com (172.18.0.10) port 8443 - * ALPN: curl offers h2,http/1.1 - * (304) (OUT), TLS handshake, Client hello (1): - * (304) (IN), TLS handshake, Server hello (2): - * (304) (IN), TLS handshake, Unknown (8): - * (304) (IN), TLS handshake, Request CERT (13): - * (304) (IN), TLS handshake, Certificate (11): - * (304) (IN), TLS handshake, CERT verify (15): - * (304) (IN), TLS handshake, Finished (20): - * (304) (OUT), TLS handshake, Certificate (11): - * (304) (OUT), TLS handshake, CERT verify (15): - * (304) (OUT), TLS handshake, Finished (20): - * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF - * ALPN: server accepted h2 - * Server certificate: - * subject: CN=example.com; O=Test Org - * start date: Jan 14 16:29:20 2026 GMT - * expire date: Jan 14 16:29:20 2027 GMT - * issuer: CN=Test CA; O=Test Org - * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. - * using HTTP/2 - * [HTTP/2] [1] OPENED stream for https://example.com:8443/get - * [HTTP/2] [1] [:method: GET] - * [HTTP/2] [1] [:scheme: https] - * [HTTP/2] [1] [:authority: example.com:8443] - * [HTTP/2] [1] [:path: /get] - * [HTTP/2] [1] [user-agent: curl/8.7.1] - * [HTTP/2] [1] [accept: */*] - > GET /get HTTP/2 - > Host: example.com:8443 - > User-Agent: curl/8.7.1 - > Accept: */* - > - * Request completely sent off - < HTTP/2 200 - ... - ``` - -4. Change the annotation values in the Gateway to a value that does not exist in the client certificate. For example, you can change the Subject Alt Name to `mtls.com`. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - tls: - frontend: - default: - validation: - mode: AllowValidOnly - caCertificateRefs: - - name: ca-cert - kind: ConfigMap - group: "" - listeners: - - name: https-8443 - protocol: HTTPS - port: 8443 - tls: - mode: Terminate - certificateRefs: - - name: https-cert - kind: Secret - options: - kgateway.dev/verify-subject-alt-names: "mtls.com" - kgateway.dev/verify-certificate-hash: "46:DB:0D:C2:E1:4F:0A:05:8C:4F:05:8D:77:B1:8D:7C:1A:BE:18:4F:AF:81:BF:E2:B1:CD:03:43:7F:D8:65:4B" - allowedRoutes: - namespaces: - from: All - EOF - ``` - -5. Repeat the request to the httpbin app with your client certificate. Verify that the request now fails. - {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address" %}} - ```sh - curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - {{% /tab %}} - {{% tab tabName="LoadBalancer hostname" %}} - ```sh - curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - - ``` - - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -v -k https://localhost:8443/get \ - --resolve example.com:8443:127.0.0.1 \ - -H "Host: example.com" \ - --cert client-cert.pem \ - --key client-key.pem \ - --cacert ca-cert.pem - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0 - * Failed receiving HTTP2 data: 56(Failure when receiving data from the peer) - * Connection #0 to host localhost left intact - curl: (56) LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0 - ``` - - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-https -n httpbin -kubectl delete gateway mtls -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete secret https-cert -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete configmap ca-cert -n {{< reuse "agw-docs/snippets/namespace.md" >}} -rm -rf ../example_certs -``` - \ No newline at end of file diff --git a/assets/docs/pages/setup/listeners/http.md b/assets/docs/pages/setup/listeners/http.md deleted file mode 100644 index 74ae63cd4..000000000 --- a/assets/docs/pages/setup/listeners/http.md +++ /dev/null @@ -1,330 +0,0 @@ -Create an HTTP listener on your API Gateway. Then, your API Gateway listens for HTTP traffic on the specified port and hostname that you configure. This Gateway can be used as the main ingress for the apps in your cluster. You can also create multiple Gateways to listen for traffic on different ports and hostnames. - -Next, you set up an HTTPRoute resource to route requests through the Gateway to backing services in your cluster. HTTPRoutes can refer to any gateway independent of the namespace they are in. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-listeners.md" >}} - -## Set up an HTTP listener {#setup-http} - -Set up an HTTP listener on your Gateway. - -If you plan to set up your listener as part of a ListenerSet, keep the following considerations in mind. For more information, see [ListenerSets (experimental)]({{< link-hextra path="/setup/listeners/overview/#listenersets" >}}). -* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}} -* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later. - -1. Create a Gateway resource with an HTTP listener. - - {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - ```yaml - kubectl apply -f- <}} - labels: - example: httpbin-mydomain - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - hostname: mydomain.com - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |---|---| - |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. | - |`spec.listeners`|Configure the listeners for this Gateway. In this example, you configure an HTTP Gateway that listens for incoming traffic for the `mydomain.com` domain on port 8080. The Gateway can serve HTTP routes from any namespace. | - - {{% /tab %}} - {{% tab tabName="ListenerSets (experimental)" %}} - - 1. Create a Gateway that enables the attachment of ListenerSets. - - ```yaml - kubectl apply -f- <}} - labels: - example: httpbin-mydomain - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - allowedListeners: - namespaces: - from: All - listeners: - - protocol: HTTP - port: 80 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |---|---| - |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. | - |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace, which is helpful in multitenant environments. You can also limit the allowed listeners. To limit to listeners in the same namespace as the Gateway, set this value to `Same`. To limit to listeners with a particular label, set this value to `Selector`. | - |`spec.listeners`| {{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on port 80, which differs from port 8080 in the ListenerSet that you create later. | - - 2. Create a ListenerSet that configures an HTTP listener for the Gateway. - - ```yaml - kubectl apply -f- <}} - kind: Gateway - group: gateway.networking.k8s.io - listeners: - - protocol: HTTP - port: 8080 - hostname: mydomain.com - name: http-listener-set - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |--|--| - |`spec.parentRef`|The name of the Gateway to attach the ListenerSet to. | - |`spec.listeners`|Configure the listeners for this ListenerSet. In this example, you configure an HTTP gateway that listens for incoming traffic for the `mydomain.com` domain on port 8080. The gateway can serve HTTP routes from any namespace. | - - {{% /tab %}} - {{< /tabs >}} - -2. Check the status of the Gateway to make sure that your configuration is accepted. Note that in the output, a `NoConflicts` status of `False` indicates that the Gateway is accepted and does not conflict with other Gateway configuration. - ```sh - kubectl get gateway my-http-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml - ``` - -3. Create an HTTPRoute resource for the httpbin app that is served by the Gateway that you created. - - {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - ```yaml - kubectl apply -f- <}} - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - {{% /tab %}} - {{% tab tabName="ListenerSets (experimental)" %}} - ```yaml - kubectl apply -f- <}} - -4. Verify that the HTTPRoute is applied successfully. - ```sh - kubectl get httproute/httpbin-mydomain -n httpbin -o yaml - ``` - - Example output: Notice in the `status` section that the parentRef is either the Gateway or the ListenerSet, depending on how you attached the HTTPRoute. - - ```yaml - ... - status: - parents: - - conditions: - - lastTransitionTime: "2025-04-29T20:48:51Z" - message: "" - observedGeneration: 3 - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: "2025-04-29T20:48:51Z" - message: "" - observedGeneration: 3 - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - controllerName: kgateway.dev/kgateway - parentRef: - group: gateway.networking.k8s.io - kind: Gateway - name: my-http-gateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -5. Verify that the listener now has a route attached. - - {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - - ```sh - kubectl get gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} my-http-gateway -o yaml - ``` - - Example output: - - ```yaml - ... - listeners: - - attachedRoutes: 1 - ``` - {{% /tab %}} - {{% tab tabName="ListenerSets (experimental)" %}} - - ```sh - kubectl get xlistenerset -n httpbin my-http-listenerset -o yaml - ``` - - Example output: - - ```yaml - ... - listeners: - - attachedRoutes: 1 - ``` - - Note that because the HTTPRoute is attached to the ListenerSet, the Gateway does not show the route in its status. - - ```sh - kubectl get gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} my-http-gateway -o yaml - ``` - - Example output: - - ```yaml - ... - listeners: - - attachedRoutes: 0 - ``` - - If you create another HTTPRoute that attaches to the Gateway and uses the same listener as the ListenerSet, then the route is reported in the status of both the Gateway (attachedRoutes: 1) and the ListenerSet (attachedRoutes: 2). - - {{% /tab %}} - {{< /tabs >}} - -6. Get the external address of the gateway and save it in an environment variable. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} my-http-gateway -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/my-http-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - {{% /tab %}} - {{< /tabs >}} - -7. Send a request to the httpbin app and verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: mydomain.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: mydomain.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - - Example output: - ```console - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < date: Fri, 03 Nov 2023 20:02:48 GMT - date: Fri, 03 Nov 2023 20:02:48 GMT - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -{{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} -{{% tab tabName="Gateway listeners" %}} -```sh -kubectl delete -A gateways,httproutes -l example=httpbin-mydomain -``` -{{% /tab %}} -{{% tab tabName="ListenerSet (experimental)" %}} -```sh -kubectl delete -A gateways,httproutes,xlistenersets -l example=httpbin-mydomain -``` -{{% /tab %}} -{{< /tabs >}} - - - - - diff --git a/assets/docs/pages/setup/listeners/https.md b/assets/docs/pages/setup/listeners/https.md deleted file mode 100644 index 24c9d3de1..000000000 --- a/assets/docs/pages/setup/listeners/https.md +++ /dev/null @@ -1,369 +0,0 @@ -Create an HTTPS listener on your API gateway. Then, your API gateway listens for secured HTTPS traffic on the specified port and hostname that you configure. - -## Before you begin - -{{< reuse "agw-docs/snippets/cert-prereqs.md" >}} - -## Create a TLS certificate - -{{< reuse "agw-docs/snippets/listeners-https-create-cert.md" >}} - -## Set up an HTTPS listener {#setup-https} - -Set up an HTTPS listener on your Gateway. - -If you plan to set up your listener as part of a ListenerSet, keep the following considerations in mind. For more information, see [ListenerSets (experimental)]({{< link-hextra path="/setup/listeners/overview/#listenersets" >}}). -* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}} -* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later. - -1. Create a gateway resource with an HTTPS listener. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} - - {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - ```yaml - kubectl apply -f- <}} - labels: - example: httpbin-https - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTPS - port: 443 - name: https - tls: - mode: Terminate - certificateRefs: - - name: https - kind: Secret - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |---|---| - |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} | - |`spec.listeners`|Configure the listeners for this Gateway. The Gateway can serve HTTPS routes from any namespace. | - |`spec.listeners.tls.mode`|The TLS mode that you want to use for incoming requests. In this example, HTTPS requests are terminated at the Gateway and the unencrypted request is forwarded to the service in the cluster. | - |`spec.listeners.tls.certificateRefs`|The Kubernetes secret that holds the TLS certificate and key for the Gateway. The Gateway uses these credentials to establish the TLS connection with a client, and to decrypt incoming HTTPS requests.| - - {{% /tab %}} - {{% tab tabName="ListenerSets (experimental)" %}} - - 1. Create a Gateway that enables the attachment of ListenerSets. - - ```yaml - kubectl apply -f- <}} - labels: - example: httpbin-https - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - allowedListeners: - namespaces: - from: All - listeners: - - protocol: HTTPS - port: 80 - name: https - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |---|---| - |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} | - |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace, which is helpful in multitenant environments. You can also limit the allowed listeners. To limit to listeners in the same namespace as the Gateway, set this value to `Same`. To limit to listeners with a particular label, set this value to `Selector`. | - |`spec.listeners`| {{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on port 80, which differs from port 443 in the ListenerSet that you create later. | - - 2. Create a ListenerSet that configures an HTTPS listener for the Gateway. - - ```yaml - kubectl apply -f- <}} - labels: - example: httpbin-https - spec: - parentRef: - name: https - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - kind: Gateway - group: gateway.networking.k8s.io - listeners: - - protocol: HTTPS - port: 443 - hostname: https.example.com - name: https-listener-set - tls: - mode: Terminate - certificateRefs: - - name: https - kind: Secret - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |--|--| - |`spec.parentRef`|The name of the Gateway to attach the ListenerSet to. | - |`spec.listeners`|Configure the listeners for this ListenerSet. In this example, you configure an HTTPS gateway that listens for incoming traffic for the `https.example.com` domain on port 443. The gateway can serve HTTP routes from any namespace. | - |`spec.listeners.tls.mode`|The TLS mode that you want to use for incoming requests. In this example, HTTPS requests are terminated at the gateway and the unencrypted request is forwarded to the service in the cluster. | - |`spec.listeners.tls.certificateRefs`|The Kubernetes secret that holds the TLS certificate and key for the gateway. The gateway uses these credentials to establish the TLS connection with a client, and to decrypt incoming HTTPS requests.| - - {{% /tab %}} - {{< /tabs >}} - -2. Check the status of the Gateway to make sure that your configuration is accepted. Note that in the output, a `NoConflicts` status of `False` indicates that the Gateway is accepted and does not conflict with other Gateway configuration. - ```sh - kubectl get gateway https -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml - ``` - -3. Create an HTTPRoute resource for the httpbin app that is served by the gateway or ListenerSet that you created. - - {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - ```yaml - kubectl apply -f- <}} - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - {{% /tab %}} - {{% tab tabName="ListenerSets (experimental)" %}} - ```yaml - kubectl apply -f- <}} - kind: XListenerSet - group: gateway.networking.x-k8s.io - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -4. Verify that the HTTPRoute is applied successfully. - ```sh - kubectl get httproute/httpbin-https -n httpbin -o yaml - ``` - - Example output: Notice in the `status` section that the parentRef is either the Gateway or the ListenerSet, depending on how you attached the HTTPRoute. - - ```yaml - ... - status: - parents: - - conditions: - - lastTransitionTime: "2025-04-29T20:48:51Z" - message: "" - observedGeneration: 3 - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: "2025-04-29T20:48:51Z" - message: "" - observedGeneration: 3 - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - controllerName: kgateway.dev/kgateway - parentRef: - group: gateway.networking.k8s.io - kind: Gateway - name: https - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -5. Verify that the listener now has a route attached. - - {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - - ```sh - kubectl get gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} https -o yaml - ``` - - Example output: - - ```yaml - ... - listeners: - - attachedRoutes: 1 - ``` - {{% /tab %}} - {{% tab tabName="ListenerSet (experimental)" %}} - - ```sh - kubectl get xlistenerset -n {{< reuse "agw-docs/snippets/namespace.md" >}} my-https-listenerset -o yaml - ``` - - Example output: - - ```yaml - ... - listeners: - - attachedRoutes: 1 - ``` - - Note that because the HTTPRoute is attached to the ListenerSet, the Gateway does not show the route in its status. - - ```sh - kubectl get gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} https -o yaml - ``` - - Example output: - - ```yaml - ... - listeners: - - attachedRoutes: 0 - ``` - - If you create another HTTPRoute that attaches to the Gateway and uses the same listener as the ListenerSet, then the route is reported in the status of both the Gateway (attachedRoutes: 1) and the ListenerSet (attachedRoutes: 2). - - {{% /tab %}} - {{< /tabs >}} - -6. Get the external address of the gateway and save it in an environment variable. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} https -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward svc/https -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:443 - ``` - {{% /tab %}} - {{< /tabs >}} - -7. Send a request to the httpbin app and verify that you see the TLS handshake and you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik --resolve "https.example.com:443:${INGRESS_GW_ADDRESS}" https://https.example.com:443/status/200 - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik --connect-to https.example.com:443:localhost:8443 https://https.example.com:443/status/200 - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * ALPN, offering h2 - * ALPN, offering http/1.1 - * successfully set certificate verify locations: - * CAfile: /etc/ssl/cert.pem - * CApath: none - * TLSv1.2 (OUT), TLS handshake, Client hello (1): - * TLSv1.2 (IN), TLS handshake, Server hello (2): - * TLSv1.2 (IN), TLS handshake, Certificate (11): - * TLSv1.2 (IN), TLS handshake, Server key exchange (12): - * TLSv1.2 (IN), TLS handshake, Server finished (14): - * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): - * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): - * TLSv1.2 (OUT), TLS handshake, Finished (20): - * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): - * TLSv1.2 (IN), TLS handshake, Finished (20): - * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 - * ALPN, server accepted to use h2 - * Server certificate: - * subject: CN=*; O=gateway - * start date: Nov 5 01:54:04 2023 GMT - * expire date: Nov 2 01:54:04 2033 GMT - * issuer: CN=*; O=root - * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. - * Using HTTP2, server supports multi-use - * Connection state changed (HTTP/2 confirmed) - * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 - * Using Stream ID: 1 (easy handle 0x15200e800) - * > GET /status/200 HTTP/2 - * > Host: https.example.com - * > user-agent: curl/7.77.0 - * > accept: */* - * > - * * Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)! - * < HTTP/2 200 - * HTTP/2 200 - * ... - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -{{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} -{{% tab tabName="Gateway listeners" %}} -```sh -kubectl delete -A gateways,httproutes,secret -l example=httpbin-https -rm -rf example_certs -``` -{{% /tab %}} -{{% tab tabName="ListenerSet (experimental)" %}} -```sh -kubectl delete -A gateways,httproutes,xlistenersets,secret -l example=httpbin-https -rm -rf example_certs -``` -{{% /tab %}} -{{< /tabs >}} - - - - - diff --git a/assets/docs/pages/setup/listeners/overview.md b/assets/docs/pages/setup/listeners/overview.md deleted file mode 100644 index 3a2768181..000000000 --- a/assets/docs/pages/setup/listeners/overview.md +++ /dev/null @@ -1,96 +0,0 @@ -Set up listeners on your API Gateway. A listener configures how your API Gateway accepts and processes incoming requests. - -In the Kubernetes Gateway API, you can create listeners in two main ways: - -* Inline as part of the Gateway resource. -* As a separate resource called a ListenerSet. - -## Inline on the Gateway {#inline} - -A common, simple approach is to write the listener inline on the Gateway resource. You have the flexibility to write different protocols, ports, and even TLS certificates. Each listener can specify its own hostname, or inherit the hostname of the Gateway. Gateways support up to 64 listeners. - -Most examples in both the {{< reuse "agw-docs/snippets/kgateway.md" >}} and Kubernetes Gateway API docs use the inline approach. - -## ListenerSets (experimental) {#listenersets} - -{{< callout type="warning" >}} -{{< reuse "agw-docs/versions/warn-2-1-only.md" >}} {{< reuse "agw-docs/versions/warn-experimental.md" >}} As such, the ListenerSet CRD is prefixed with `X` to indicate that it is experimental. -{{< /callout >}} - -With ListenerSets, you can group together listeners that have their own unique configuration, such as different protocols, ports, hostnames, or TLS settings. Then, the ListenerSet refers to a Gateway, which can be in a different namespace than the ListenerSet. The same Gateway can also have multiple ListenerSets. - -Similar to Gateways, ListenerSets can have a maximum of 64 listeners. However, because you can attach multiple ListenerSets to a single Gateway, now a single Gateway can have more than 64 listeners. Keep in mind that more listeners can impact how long it takes to propagate configuration changes on the Gateway. If you have more than 1,000 listeners, consider attaching ListenerSets to multiple Gateways. - -### ListenerSet use cases {#listenerset-use-cases} - -As such, you might use ListenerSets for the following advantages: - -- **Multitenancy**: You can let different teams create their own ListenerSets, but share the same Gateway and backing load balancing infrastructure. -- **Inheritance**: Because ListenerSets inherit routes and policies from the Gateway, you can standardize the configuration of listeners across a multitenant environment. Teams still have the flexibility to overwrite settings in the ListenerSet. -- **Large scale deployments**: By using ListenerSets, Gateways can have more than 64 listeners attached. Teams can also share the same ListenerSet configuration to avoid duplication. -- **Certificates for more listeners per gateway**: Because you can now have more than 64 listeners per Gateway, a single Gateway can forward secured traffic to more backends that might have their own certificates. This approach aligns with projects that might require service-level certificates, such as Istio Ambient Mesh or Knative. - -The following diagram presents a simple illustration of how ListenerSets can help you decentralize route configuration in a multitenant environment at scale. - -* Team 1 and Team 2 each manage their own Service and HTTPRoute resources within their respective namespaces. -* Each HTTPRoute refers to a namespace-local ListenerSet. This way, each team controls how their routes are exposed, such as the protocol, port, and TLS certificate settings. -* The ListenerSets from both teams share a common Gateway in a separate namespace. A separate Gateway team can setup and manage centralized infrastructure or enforce policies as appropriate. - - -```mermaid -flowchart TD - - subgraph team1 namespace - SVC1[Services] - HR1[HTTPRoutes] - LS1[ListenerSet] - end - - subgraph team2 namespace - SVC2[Services] - HR2[HTTPRoutes] - LS2[ListenerSet] - end - - subgraph shared namespace - GW[Gateway] - end - - HR1 -- "parentRef" --> LS1 - LS1 -- "parentRef" --> GW - HR1 -- "backendRef" --> SVC1 - - HR2 -- "parentRef" --> LS2 - LS2 -- "parentRef" --> GW - HR2 -- "backendRef" --> SVC2 -``` - -### Prerequisites {#prerequisites} - -To use ListenerSets, you must have the following environment: - -1. Install the Kubernetes Gateway API v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}} or later experimental channel, which includes the `XListenerSet` CRD. - - ```sh - kubectl apply --server-side --kustomize "https://github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}" - ``` - -2. Follow the [Get Started guide]({{< link-hextra path="/quickstart/" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}. - -3. If you already have a {{< reuse "agw-docs/snippets/kgateway.md" >}} installation, restart the `{{< reuse "agw-docs/snippets/pod-name.md" >}}` deployment to pick up the new CRDs. - - ```sh - kubectl rollout restart deployment/{{< reuse "agw-docs/snippets/pod-name.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -### More information {#more-info} - -The listener setup guides in this section include tabs for examples of using both the inline and ListenerSet approaches. - -For more information about ListenerSets, see the [Kubernetes Gateway API docs](https://gateway-api.sigs.k8s.io/geps/gep-1713/). - - - - - - diff --git a/assets/docs/pages/setup/listeners/sni.md b/assets/docs/pages/setup/listeners/sni.md deleted file mode 100644 index daca081cb..000000000 --- a/assets/docs/pages/setup/listeners/sni.md +++ /dev/null @@ -1,548 +0,0 @@ -Serve multiple hosts on the same HTTPS listener. - -## About SNI - -Each host comes with its own TLS certificates that the Gateway uses to authenticate and authorize client requests. - -Serving multiple hosts on a single listener is also referred to as Server Name Indication (SNI) routing. SNI is an extension to the TLS protocol and allows clients to indicate which hostname they want to connect to at the start of the TLS handshake. After the HTTPS/TLS traffic is accepted at the gateway, the TLS connection is terminated, and the unencrypted HTTP/TCP request is forwarded to the destination. - -## About this guide - -In this guide, you learn how to set up an HTTPS Gateway that serves two different domains, `httpbin.example.com` and `petstore.example.com` on the same port 443. When sending a request to the Gateway, you indicate the hostname you want to connect to. Based on the selected hostname, the Gateway presents the hostname-specific certificate. - -{{< reuse-image src="img/sni-listener.svg" width="700px">}} -{{< reuse-image-dark srcDark="img/sni-listener-dark.svg" width="700px" >}} - -## Before you begin - -{{< reuse "agw-docs/snippets/cert-prereqs.md" >}} - -## Deploy sample apps - -Deploy the Petstore sample app. This app is used alongside the httpbin app from the [Get started]({{< link-hextra path="/quickstart" >}}) guide to demonstrate the SNI routing capabilities. - -1. Deploy the Petstore app. - ```sh - kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo/v1.16.x/example/petstore/petstore.yaml - ``` - - Example output: - ```console - deployment.apps/petstore created - service/petstore created - ``` - -2. Verify that the Petstore app is up and running. - ```sh - kubectl get pods - ``` - - Example output: - ``` - NAME READY STATUS RESTARTS AGE - petstore-66cddd5bb4-x7vdd 1/1 Running 0 26s - ``` - -## Set up TLS certificates for multiple domains - -Create TLS certificates for the `httpbin.example.com` and `petstore.example.com` domains that are signed by a self-signed root CA. - -{{< callout type="warning" >}} -Self-signed certificates are used for demonstration purposes. Do not use self-signed certificates in production environments. Instead, use certificates that are issued from a trusted Certificate Authority. -{{< /callout >}} - -{{< callout type="info" >}} -When generating your Envoy certificates, make sure to use encryption algorithms that are supported in Envoy. To learn more about supported algorithms that you can use for your certificates and keys, see the Envoy documentation. -{{< /callout >}} - -1. Create a root certificate and private key to sign the certificates for your services. - ```shell - mkdir example_certs - openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs/example.com.key -out example_certs/example.com.crt - ``` - -2. Generate a TLS certificate and key for the `httpbin.example.com` domain. - ```shell - openssl req -out example_certs/httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/httpbin.example.com.key -subj "/CN=httpbin.example.com/O=httpbin organization" - openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 0 -in example_certs/httpbin.example.com.csr -out example_certs/httpbin.example.com.crt - ``` - -3. Generate a TLS certificate and key for the `petstore.example.com` domain. - ```shell - openssl req -out example_certs/petstore.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/petstore.example.com.key -subj "/CN=petstore.example.com/O=petstore organization" - openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 1 -in example_certs/petstore.example.com.csr -out example_certs/petstore.example.com.crt - ``` - -4. Verify that you have the required certificates and keys. - ```shell - ls example_cert* - ``` - - Example output: - ``` - petstore.example.com.crt petstore.example.com.key example.com.crt httpbin.example.com.crt httpbin.example.com.key - petstore.example.com.csr example.com.key httpbin.example.com.csr - ``` - -6. Store the credentials for the `httpbin.example.com` domain in a Kubernetes secret. - ```shell - kubectl create -n {{< reuse "agw-docs/snippets/namespace.md" >}} secret tls httpbin-credential \ - --key=example_certs/httpbin.example.com.key \ - --cert=example_certs/httpbin.example.com.crt - ``` - -7. Store the credentials for the `petstore.example.com` domain in a Kubernetes secret. - ```shell - kubectl create -n {{< reuse "agw-docs/snippets/namespace.md" >}} secret tls petstore-credential \ - --key=example_certs/petstore.example.com.key \ - --cert=example_certs/petstore.example.com.crt - ``` - -## Set up SNI routing - -Set up an SNI Gateway that serves multiple hosts on the same port. - -If you plan to set up your listener as part of a ListenerSet, keep the following considerations in mind. For more information, see [ListenerSets (experimental)]({{< link-hextra path="/setup/listeners/overview/#listenersets" >}}). -* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}} -* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later. - -1. Create an SNI Gateway. The Gateway defines two hosts on the same HTTPS listener. Each host is configured with the host-specific TLS certificate that you set up earlier. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} - - {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTPS - port: 443 - name: httpbin - hostname: "httpbin.example.com" - tls: - mode: Terminate - certificateRefs: - - name: httpbin-credential - kind: Secret - allowedRoutes: - namespaces: - from: All - - protocol: HTTPS - port: 443 - name: petstore - hostname: "petstore.example.com" - tls: - mode: Terminate - certificateRefs: - - name: petstore-credential - kind: Secret - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |--|--| - |`spec.gatewayClassName`| The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}| - |`spec.listeners`|Configure the listeners for this Gateway. In this example, you configure two HTTPS listeners. One listener is for the httpbin app and the other is for the petstore app. Each listener refers to a secret that holds the TLS certificate and key for the hostname that the listener is configured for. | - |`spec.listeners.tls.mode`|The TLS mode that you want to use for incoming requests. In this example, HTTPS requests are terminated at the Gateway and the unencrypted request is forwarded to the service in the cluster. | - |`spec.listeners.tls.certificateRefs`|The Kubernetes secret that holds the TLS certificate and key for the Gateway. The Gateway uses these credentials to establish the TLS connection with a client, and to decrypt incoming HTTPS requests.| - - {{% /tab %}} - {{% tab tabName="ListenerSet (experimental)" %}} - - 1. Create a Gateway that enables the attachment of ListenerSets. - - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - allowedListeners: - namespaces: - from: All - listeners: - - protocol: HTTP - port: 80 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |--|--| - |`spec.gatewayClassName`| The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}| - |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace, which is helpful in multitenant environments. You can also limit the allowed listeners. To limit to listeners in the same namespace as the Gateway, set this value to `Same`. To limit to listeners with a particular label, set this value to `Selector`. | - | `spec.listeners` | {{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on HTTP port 80, which differs from the HTTPS port 443 in the ListenerSet that you create later. | - - 2. Create a ListenerSet that configures an HTTPS listener for each app that the Gateway serves. - - ```yaml - kubectl apply -f- <}} - spec: - parentRef: - name: sni - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - kind: Gateway - group: gateway.networking.k8s.io - listeners: - - protocol: HTTPS - port: 443 - name: httpbin - hostname: "httpbin.example.com" - tls: - mode: Terminate - certificateRefs: - - name: httpbin-credential - kind: Secret - allowedRoutes: - namespaces: - from: All - - protocol: HTTPS - port: 443 - name: petstore - hostname: "petstore.example.com" - tls: - mode: Terminate - certificateRefs: - - name: petstore-credential - kind: Secret - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |--|--| - |`spec.parentRef`|The name of the Gateway to attach the ListenerSet to. | - |`spec.listeners`|Configure the listeners for this gateway. In this example, you configure two HTTPS listeners. One listener is for the httpbin app and the other is for the petstore app. Each listener refers to a secret that holds the TLS certificate and key for the hostname that the listener is configured for. | - |`spec.listeners.tls.mode`|The TLS mode that you want to use for incoming requests. In this example, HTTPS requests are terminated at the gateway and the unencrypted request is forwarded to the service in the cluster. | - |`spec.listeners.tls.certificateRefs`|The Kubernetes secret that holds the TLS certificate and key for the gateway. The gateway uses these credentials to establish the TLS connection with a client, and to decrypt incoming HTTPS requests.| - - {{% /tab %}} - {{< /tabs >}} - -2. Create an HTTPRoute that routes incoming requests on the `httpbin.example.com` domain to the httpbin app. - - {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - - ```yaml - kubectl apply -f- <}} - hostnames: - - "httpbin.example.com" - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - - {{% /tab %}} - {{% tab tabName="ListenerSet (experimental)" %}} - - ```yaml - kubectl apply -f- <}} - kind: XListenerSet - group: gateway.networking.x-k8s.io - hostnames: - - "httpbin.example.com" - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -3. Create an HTTPRoute that routes incoming requests on the `petstore.example.com` domain to the petstore app. - - {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - - ```yaml - kubectl apply -f- <}} - hostnames: - - "petstore.example.com" - rules: - - backendRefs: - - name: petstore - port: 8080 - EOF - ``` - - {{% /tab %}} - {{% tab tabName="ListenerSet (experimental)" %}} - - ```yaml - kubectl apply -f- <}} - kind: XListenerSet - group: gateway.networking.x-k8s.io - hostnames: - - "petstore.example.com" - rules: - - backendRefs: - - name: petstore - port: 8080 - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -4. Get the external address of the Gateway and save it in an environment variable. Note that it might take a few seconds for the Gateway address to become available. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} sni -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward svc/sni -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:443 - ``` - {{% /tab %}} - {{< /tabs >}} - -5. Send a request to the `httpbin.example.com` domain with the client certificate that you created earlier. Verify that the gateway presents the TLS certificate for the `httpbin.example.com` domain during the TLS handshake. - {{< tabs items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" tabTotal="3" >}} - {{% tab tabName="LoadBalancer IP address" %}} - ```sh - curl -vik --resolve "httpbin.example.com:443:${INGRESS_GW_ADDRESS}" https://httpbin.example.com:443/anything - ``` - {{% /tab %}} - {{% tab tabName="LoadBalancer hostname" %}} - ```sh - curl -vik --resolve "httpbin.example.com:443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://httpbin.example.com:443/anything - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik --connect-to httpbin.example.com:443:localhost:8443 https://httpbin.example.com:443/anything - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Added httpbin.example.com:443:3.XXX.XXX.XX to DNS cache - * Hostname httpbin.example.com was found in DNS cache - * Trying 3.128.214.17:443... - * Connected to httpbin.example.com (3.XXX.XXX.XX) port 443 - * ALPN: curl offers h2,http/1.1 - * (304) (OUT), TLS handshake, Client hello (1): - * (304) (IN), TLS handshake, Server hello (2): - * (304) (IN), TLS handshake, Unknown (8): - * (304) (IN), TLS handshake, Certificate (11): - * (304) (IN), TLS handshake, CERT verify (15): - * (304) (IN), TLS handshake, Finished (20): - * (304) (OUT), TLS handshake, Finished (20): - * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF - * ALPN: server accepted h2 - * Server certificate: - * subject: CN=httpbin.example.com; O=httpbin organization - * issuer: O=example Inc.; CN=example.com - * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. - * using HTTP/2 - * [HTTP/2] [1] OPENED stream for https://httpbin.example.com:443/headers - * [HTTP/2] [1] [:method: GET] - * [HTTP/2] [1] [:scheme: https] - * [HTTP/2] [1] [:authority: httpbin.example.com] - * [HTTP/2] [1] [:path: /headers] - * [HTTP/2] [1] [user-agent: curl/8.7.1] - * [HTTP/2] [1] [accept: */*] - > GET /headers HTTP/2 - > Host: httpbin.example.com - > User-Agent: curl/8.7.1 - > Accept: */* - > - * Request completely sent off - < HTTP/2 200 - HTTP/2 200 - ... - "Accept": [ - "*/*" - ], - "Host": [ - "httpbin.example.com" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "https" - ], - "X-Request-Id": [ - "33654cba-7198-4b7c-a850-8629fd230145" - ] - } - } - ``` - -6. Send a request to the `petstore.example.com` domain with the client certificate that you created earlier. Verify that the gateway presents the TLS certificate for the `petstore.example.com` domain during the TLS handshake. - {{< tabs items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" tabTotal="3" >}} - {{% tab tabName="LoadBalancer IP address" %}} - ```sh - curl -vik --resolve "petstore.example.com:443:${INGRESS_GW_ADDRESS}" https://petstore.example.com:443/api/pets - ``` - {{% /tab %}} - {{% tab tabName="LoadBalancer hostname" %}} - ```sh - curl -vik --resolve "petstore.example.com:443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://petstore.example.com:443/api/pets - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik --connect-to petstore.example.com:443:localhost:8443 https://petstore.example.com:443/api/pets - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Added petstore.example.com:443:3.XXX.XXX.XX to DNS cache - * Hostname petstore.example.com was found in DNS cache - * Trying 3.128.214.17:443... - * Connected to petstore.example.com (3.XXX.XXX.XX) port 443 - * ALPN: curl offers h2,http/1.1 - * (304) (OUT), TLS handshake, Client hello (1): - * (304) (IN), TLS handshake, Server hello (2): - * (304) (IN), TLS handshake, Unknown (8): - * (304) (IN), TLS handshake, Certificate (11): - * (304) (IN), TLS handshake, CERT verify (15): - * (304) (IN), TLS handshake, Finished (20): - * (304) (OUT), TLS handshake, Finished (20): - * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF - * ALPN: server accepted h2 - * Server certificate: - * subject: CN=petstore.example.com; O=petstore organization - * issuer: O=example Inc.; CN=example.com - * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. - * using HTTP/2 - * [HTTP/2] [1] OPENED stream for https://petstore.example.com:443/api/pets - * [HTTP/2] [1] [:method: GET] - * [HTTP/2] [1] [:scheme: https] - * [HTTP/2] [1] [:authority: petstore.example.com] - * [HTTP/2] [1] [:path: /api/pets] - * [HTTP/2] [1] [user-agent: curl/8.7.1] - * [HTTP/2] [1] [accept: */*] - > GET /api/pets HTTP/2 - > Host: petstore.example.com - > User-Agent: curl/8.7.1 - > Accept: */* - > - * Request completely sent off - < HTTP/2 200 - HTTP/2 200 - ... - - [{"id":1,"name":"Dog","status":"available"},{"id":2,"name":"Cat","status":"pending"}] - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Remove the routing resources for the HTTPS route, including the Kubernetes secret that holds the TLS certificate and key. - - {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - - ```sh - kubectl delete secret httpbin-credential -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete secret petstore-credential -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete gateway sni -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete httproute httpbin-https -n httpbin - kubectl delete httproute petstore-https -n default - kubectl delete deployment petstore - kubectl delete service petstore - ``` - {{% /tab %}} - {{% tab tabName="ListenerSet (experimental)" %}} - ```sh - kubectl delete secret httpbin-credential -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete secret petstore-credential -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete gateway sni -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete xlistenerset sni-listenerset -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl delete httproute httpbin-https -n httpbin - kubectl delete httproute petstore-https -n default - kubectl delete deployment petstore - kubectl delete service petstore - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Remove the `example_certs` directory that stores your TLS credentials. - ```sh - rm -rf example_certs - ``` - - - - - diff --git a/assets/docs/pages/setup/listeners/tcp.md b/assets/docs/pages/setup/listeners/tcp.md deleted file mode 100644 index 998cd2105..000000000 --- a/assets/docs/pages/setup/listeners/tcp.md +++ /dev/null @@ -1,364 +0,0 @@ -The following guide deploys a sample TCP echo app, sets up a TCP listener on the gateway, and creates a [TCPRoute](https://gateway-api.sigs.k8s.io/guides/tcp) to the sample app. - -{{< callout type="warning" >}} -{{< reuse "agw-docs/versions/warn-experimental.md" >}} -{{< /callout >}} - -## Before you begin - -1. Follow the [Get started guide]({{< link-hextra path="/quickstart" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}. - -2. Install the experimental channel of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} so that you can use TCPRoutes. - - ```shell - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml - ``` - -3. {{< reuse "agw-docs/snippets/prereq-listenerset.md" >}} - - **ListenerSets**: {{< reuse "agw-docs/versions/warn-2-1-only.md" >}} Also, you must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later. - -4. Deploy the sample TCP echo app. - - ```yaml - kubectl apply -f- <}}). -* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}} -* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later. - -1. Create a Gateway with a TCP listener. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} - {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - ```yaml - kubectl apply -f- <}} - labels: - app: tcp-echo - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: TCP - port: 8000 - name: tcp - allowedRoutes: - kinds: - - kind: TCPRoute - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |--|--| - |`spec.gatewayClassName`| The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} | - |`spec.listeners`|Configure the listeners for this Gateway. In this example, you configure a TCP Gateway that listens for incoming traffic on port 8000. The Gateway can serve TCPRoutes from any namespace. | - - {{% /tab %}} - {{% tab tabName="ListenerSets (experimental)" %}} - - 1. Create a Gateway that enables the attachment of ListenerSets. - - ```yaml - kubectl apply -f- <}} - labels: - app: tcp-echo - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - allowedListeners: - namespaces: - from: All - listeners: - - protocol: TCP - port: 80 - name: generic-tcp - allowedRoutes: - kinds: - - kind: TCPRoute - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |---|---| - |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}| - |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace.| - |`spec.listeners`|{{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on port 80, which differs from port 8000 in the ListenerSet that you create later.| - - 2. Create a ListenerSet that configures a TCP listener for the Gateway. - - ```yaml - kubectl apply -f- <}} - labels: - app: tcp-echo - spec: - parentRef: - name: tcp-gateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - kind: Gateway - group: gateway.networking.k8s.io - listeners: - - protocol: TCP - port: 8000 - name: tcp-listener-set - allowedRoutes: - kinds: - - kind: TCPRoute - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |--|--| - |`spec.parentRef`|The name of the Gateway to attach the ListenerSet to. | - |`spec.listeners`|Configure the listeners for this ListenerSet. In this example, you configure a TCP listener for port 8000. The gateway can serve TCPRoutes from any namespace. | - {{% /tab %}} - {{< /tabs >}} - -2. Check the status of the Gateway to make sure that your configuration is accepted. Note that in the output, a `NoConflicts` status of `False` indicates that the Gateway is accepted and does not conflict with other Gateway configuration. - ```sh - kubectl get gateway tcp-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml - ``` - - Example output: - - ```console - status: - addresses: - - type: IPAddress - value: ${INGRESS_GW_ADDRESS} - conditions: - - lastTransitionTime: "2024-11-20T16:01:25Z" - message: "" - observedGeneration: 2 - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: "2024-11-20T16:01:25Z" - message: "" - observedGeneration: 2 - reason: Programmed - status: "True" - type: Programmed - ``` - -3. Create a ReferenceGrant to allow TCPRoutes to reference the tcp-echo service. - - ```yaml - kubectl apply -f- <}} - to: - - group: "" - kind: Service - EOF - ``` - -## Create a TCPRoute - -1. Create the TCPRoute resource. - {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}} - {{% tab tabName="Gateway listeners" %}} - ```yaml - kubectl apply -f- <}} - labels: - app: tcp-echo - spec: - parentRefs: - - name: tcp-gateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - sectionName: tcp - rules: - - backendRefs: - - name: tcp-echo - namespace: default - port: 1025 - EOF - ``` - {{% /tab %}} - {{% tab tabName="ListenerSets (experimental)" %}} - ```yaml - kubectl apply -f- <}} - labels: - app: tcp-echo - spec: - parentRefs: - - name: my-tcp-listenerset - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - kind: XListenerSet - group: gateway.networking.x-k8s.io - sectionName: tcp-listener-set - rules: - - backendRefs: - - name: tcp-echo - namespace: default - port: 1025 - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Verify that the TCPRoute is applied successfully. - - ```sh - kubectl get tcproute/tcp-route-echo -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml - ``` - - Example output: - - ```console - status: - parents: - - conditions: - - lastTransitionTime: "2024-11-21T16:22:52Z" - message: "" - observedGeneration: 1 - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: "2024-11-21T16:22:52Z" - message: "" - observedGeneration: 1 - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - controllerName: kgateway.dev/kgateway - parentRef: - group: gateway.networking.k8s.io - kind: Gateway - name: tcp-gateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - sectionName: tcp - ``` - -## Verify the TCP route {#verify-tcp-route} - -Verify that the TCP route to the TCP echo app is working. - -1. Get the external address of the gateway and save it in an environment variable. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} tcp-gateway -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/tcp-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8000:8000 - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Send a TCP request to the external address of the TCP gateway on port 8000. You might use a tool such as telnet or netcat as in the following example. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - nc $INGRESS_GW_ADDRESS 8000 - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - nc localhost 8000 - ``` - {{% /tab %}} - {{< /tabs >}} - - The output is an open session for you to send more requests. - -3. Enter any string to verify that the TCP echo service "echoes," returning the same string back. - - ```console - hello - ``` - - Example output: - - ```console - hello - hello - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```shell -kubectl delete -A gateways,tcproutes,pod,svc -l app=tcp-echo -``` - - - - - diff --git a/assets/docs/pages/setup/listeners/tls-passthrough.md b/assets/docs/pages/setup/listeners/tls-passthrough.md deleted file mode 100644 index 6844a1239..000000000 --- a/assets/docs/pages/setup/listeners/tls-passthrough.md +++ /dev/null @@ -1,433 +0,0 @@ -Set up a TLS listener on the Gateway that serves one or more hosts and passes TLS traffic through to a destination. Because TLS traffic is not terminated at the Gateway, the destination must be capable of handling incoming TLS traffic. - -## Before you begin - -{{< reuse "agw-docs/snippets/cert-prereqs.md" >}} - -## Deploy an nginx server that is configured for HTTPS traffic - -Deploy a sample nginx server and configure the server for HTTPS traffic. - -1. Create a root certificate for the `example.com` domain. You use this certificate to sign the certificate for your nginx service later. - ```shell - mkdir example_certs - openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs/example.com.key -out example_certs/example.com.crt - ``` - -2. Create a server certificate and private key for the `nginx.example.com` domain. - ``` - openssl req -out example_certs/nginx.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/nginx.example.com.key -subj "/CN=nginx.example.com/O=some organization" - openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 0 -in example_certs/nginx.example.com.csr -out example_certs/nginx.example.com.crt - ``` - -3. Create a secret that stores the certificate and key for the nginx server. - ```shell - kubectl create secret tls nginx-server-certs \ - --key example_certs/nginx.example.com.key \ - --cert example_certs/nginx.example.com.crt - ``` - -5. Prepare your nginx configuration. The following example configures nginx for HTTPS traffic with the certificate that you created earlier. - ```shell - cat <<\EOF > ./nginx.conf - events { - } - - http { - log_format main '$remote_addr - $remote_user [$time_local] $status ' - '"$request" $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - access_log /var/log/nginx/access.log main; - error_log /var/log/nginx/error.log; - - server { - listen 443 ssl; - - root /usr/share/nginx/html; - index index.html; - - server_name nginx.example.com; - ssl_certificate /etc/nginx-server-certs/tls.crt; - ssl_certificate_key /etc/nginx-server-certs/tls.key; - } - } - EOF - ``` - -6. Store the nginx configuration in a configmap. - ```shell - kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf - ``` - -7. Deploy the nginx server. - ```yaml - kubectl apply -f- <}}). -* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}} -* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later. - -{{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}} -{{% tab tabName="Gateway listeners" %}} -1. Create a Gateway that passes through incoming TLS requests for the `nginx.example.com` domain. - - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - listeners: - - name: tls - protocol: TLS - hostname: "nginx.example.com" - tls: - mode: Passthrough - port: 8443 - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |---|---| - |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}| - |`spec.listeners`|Configure the listeners for this Gateway. In this example, you configure a TLS passthrough Gateway that listens for incoming traffic for the `nginx.example.com` domain on port 8443. The Gateway can serve TLS routes from any namespace.| - |`spec.listeners.tls.mode`|The TLS mode for incoming requests. In this example, TLS requests are passed through to the backend service without being terminated at the Gateway.| - -{{% /tab %}} -{{% tab tabName="ListenerSets (experimental)" %}} - -1. Create a Gateway that enables the attachment of ListenerSets. - - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - allowedListeners: - namespaces: - from: All - listeners: - - protocol: TLS - port: 80 - name: generic-tls - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |---|---| - |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} | - |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace.| - |`spec.listeners`|{{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on port 80, which differs from port 443 in the ListenerSet that you create later.| - -2. Create a ListenerSet that configures a TLS passthrough listener for the Gateway. - - ```yaml - kubectl apply -f- <}} - spec: - parentRef: - name: tls-passthrough - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - kind: Gateway - group: gateway.networking.k8s.io - listeners: - - protocol: TLS - port: 8443 - hostname: nginx.example.com - name: tls-listener-set - tls: - mode: Passthrough - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - |Setting|Description| - |--|--| - |`spec.parentRef`|The name of the Gateway to attach the ListenerSet to.| - |`spec.listeners`|Configure the listeners for this ListenerSet. In this example, you configure a TLS passthrough listener for the `nginx.example.com` domain on port 8443.| - |`spec.listeners.tls.mode`|The TLS mode for incoming requests. TLS requests are passed through to the backend service without being terminated at the Gateway.| - -{{% /tab %}} -{{< /tabs >}} - -## Create a TLSRoute - -{{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}} -{{% tab tabName="Gateway listeners" %}} -```yaml -kubectl apply -f- <}} - rules: - - backendRefs: - - group: "" - kind: Service - name: my-nginx - port: 443 -EOF -``` -{{% /tab %}} -{{% tab tabName="ListenerSets (experimental)" %}} -```yaml -kubectl apply -f- <}} - kind: XListenerSet - group: gateway.networking.x-k8s.io - rules: - - backendRefs: - - group: "" - kind: Service - name: my-nginx - port: 443 -EOF -``` -{{% /tab %}} -{{< /tabs >}} - -## Verify TLS passthrough traffic for nginx - -{{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} -{{% tab tabName="Cloud Provider LoadBalancer" %}} -1. Get the external address of the gateway proxy and save it in an environment variable.external address of the gateway proxy and save it in an environment variable. - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} tls-passthrough -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` -2. Send a request to the `nginx.example.com` domain and verify that you get back a 200 HTTP response code from your nginx server. Because nginx accepts incoming TLS traffic only, the 200 HTTP response code proves that TLS traffic was not terminated at the Gateway. In addition, you can verify that you get back the server certificate that you configured your nginx server with in the beginning. - - * **Load balancer IP**: - ```shell - curl -vik --resolve "nginx.example.com:8443:${INGRESS_GW_ADDRESS}" --cacert example_certs/example.com.crt https://nginx.example.com:8443/ - ``` - - * **Load balancer hostname**: - ```shell - curl -vik --resolve "nginx.example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" --cacert example_certs/example.com.crt https://nginx.example.com:8443/ - ``` - - Example output: - ```console - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < Server: nginx/1.27.4 - Server: nginx/1.27.4 - ... - < - - - - - Welcome to nginx! - - - -

Welcome to nginx!

-

If you see this page, the nginx web server is successfully installed and - working. Further configuration is required.

- -

For online documentation and support please refer to - nginx.org.
- Commercial support is available at - nginx.com.

- -

Thank you for using nginx.

- - - * Connection #0 to host nginx.example.com left intact - ``` -{{% /tab %}} -{{% tab tabName="Port-forward for local testing" %}} -1. Port-forward the tls-passthrough gateway proxy pod on port 8443. - ```sh - kubectl port-forward deployment/tls-passthrough -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:8443 - ``` -2. Send a request to the `nginx.example.com` domain and verify that you get back a 200 HTTP response code from your nginx server. Because nginx accepts incoming TLS traffic only, the 200 HTTP response code proves that TLS traffic was not terminated at the Gateway. In addition, you can verify that you get back the server certificate that you configured your nginx server with in the beginning. - ```sh - curl -vi --cacert example_certs/example.com.crt --resolve "nginx.example.com:8443:127.0.0.1" https://nginx.example.com:8443 - ``` - - Example output: - ```console - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < Server: nginx/1.27.4 - Server: nginx/1.27.4 - ... - < - - - - - Welcome to nginx! - - - -

Welcome to nginx!

-

If you see this page, the nginx web server is successfully installed and - working. Further configuration is required.

- -

For online documentation and support please refer to - nginx.org.
- Commercial support is available at - nginx.com.

- -

Thank you for using nginx.

- - - * Connection #0 to host nginx.example.com left intact - ``` - -{{% /tab %}} -{{< /tabs >}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -{{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}} -{{% tab tabName="Gateway listeners" %}} - -```sh -rm -r example_certs -rm nginx.conf -kubectl delete configmap nginx-configmap -kubectl delete tlsroute tlsroute -kubectl delete gateway tls-passthrough -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete deployment my-nginx -kubectl delete service my-nginx -kubectl delete secret nginx-server-certs -``` -{{% /tab %}} -{{% tab tabName="ListenerSet (experimental)" %}} -```sh -rm -r example_certs -rm nginx.conf -kubectl delete configmap nginx-configmap -kubectl delete tlsroute tlsroute -kubectl delete XListenerSet my-tls-listenerset -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete gateway tls-passthrough -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete deployment my-nginx -kubectl delete service my-nginx -kubectl delete secret nginx-server-certs -``` -{{% /tab %}} -{{< /tabs >}} - - - - - - - diff --git a/assets/docs/pages/setup/selfmanaged.md b/assets/docs/pages/setup/selfmanaged.md deleted file mode 100644 index ca0c539c7..000000000 --- a/assets/docs/pages/setup/selfmanaged.md +++ /dev/null @@ -1,157 +0,0 @@ -Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway. You do not need to create a Gateway resource, because you create a self-managed Gateway as part of this guide. - -## Create a self-managed gateway proxy - -1. Create a GatewayParameters resource that allows you to create self-managed gateway proxies. - ```yaml - kubectl apply -f- <}}/pkg/kgateway/helm/envoy/templates/deployment.yaml). - - Example configuration to update in the ConfigMap `data.envoy.yaml` section: - - ```yaml - admin: - address: - socket_address: { address: 127.0.0.1, port_value: 19000 } - node: - cluster: $GATEWAY_NAME.$GATEWAY_NAMESPACE - metadata: - role: gloo-kube-gateway-api~$GATEWAY_NAMESPACE~$GATEWAY_NAMESPACE-$GATEWAY_NAME - static_resources: - listeners: - - name: read_config_listener - address: - socket_address: { address: 0.0.0.0, port_value: 8082 } - filter_chains: - - filters: - - name: envoy.filters.network.http_connection_manager - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager - stat_prefix: ingress_http - codec_type: AUTO - route_config: - name: main_route - virtual_hosts: - - name: local_service - domains: ["*"] - routes: - - match: - path: "/ready" - headers: - - name: ":method" - string_match: - exact: GET - route: - cluster: admin_port_cluster - http_filters: - - name: envoy.filters.http.router - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router - clusters: - - name: xds_cluster - alt_stat_name: xds_cluster - connect_timeout: 5.000s - load_assignment: - cluster_name: xds_cluster - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: $CONTROLLER_HOST - port_value: 9977 - typed_extension_protocol_options: - envoy.extensions.backends.http.v3.HttpProtocolOptions: - "@type": type.googleapis.com/envoy.extensions.backends.http.v3.HttpProtocolOptions - explicit_http_config: - http2_protocol_options: {} - backend_connection_options: - tcp_keepalive: - keepalive_time: 10 - type: STRICT_DNS - respect_dns_ttl: true - - name: admin_port_cluster - connect_timeout: 5.000s - type: STATIC - lb_policy: ROUND_ROBIN - load_assignment: - cluster_name: admin_port_cluster - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: 19000 - dynamic_resources: - ads_config: - transport_api_version: V3 - api_type: GRPC - rate_limit_settings: {} - grpc_services: - - envoy_grpc: - cluster_name: xds_cluster - cds_config: - resource_api_version: V3 - ads: {} - lds_config: - resource_api_version: V3 - ads: {} - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gatewayparameters self-managed -n kgateway-system -kubectl delete gateway self-managed -n kgateway-system -``` diff --git a/assets/docs/pages/traffic-management/buffering.md b/assets/docs/pages/traffic-management/buffering.md deleted file mode 100644 index 8bb93ea54..000000000 --- a/assets/docs/pages/traffic-management/buffering.md +++ /dev/null @@ -1,145 +0,0 @@ -Fine-tune connection speeds for read and write operations by setting a connection buffer limit. - -{{< callout >}} -{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}} -{{< /callout >}} - -## About read and write buffer limits - -By default, {{< reuse "/agw-docs/snippets/kgateway.md" >}} is set up with 1MiB of request read and write buffer for each gateway. For large requests that must be buffered and that exceed the default buffer limit, {{< reuse "/agw-docs/snippets/kgateway.md" >}} either disconnects the connection to the downstream service if headers were already sent, or returns a 413 HTTP response code. To make sure that large requests can be sent and received, you can specify the maximum number of bytes that can be buffered between the gateway and the downstream service. Alternatively, when using {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an edge proxy, configuring the buffer limit can be important when dealing with untrusted downstreams. By setting the limit to a small number, such as 32KiB, you can better guard against potential attacks or misconfigured downstreams that could excessively use the proxy's resources. - -The connection buffer limit can be configured on the Gateway level or on an individual route. - -## Considerations when using httpbin - -When you use the httpbin sample app, keep in mind that httpbin limits the maximum body size to 1 mebibyte (1Mi). If you send a request to httpbin with a body size that is larger than that, httpbin automatically rejects the request with a 400 HTTP response code. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up buffer limits per gateway - -Use an annotation to set a per-connection buffer limit on your Gateway, which applies the buffer limit to all routes served by the Gateway. - -1. Create a {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} called `transformation-buffer-body` that forces buffering by transforming the response from the httpbin sample app. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation-buffer-body - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - body: - parseAs: AsString - value: '{{ body() }}' - EOF - ``` - -2. Annotate the http Gateway resource to set a buffer limit of 1 kilobytes. - ```yaml - kubectl apply -f- <}} - annotations: - kgateway.dev/per-connection-buffer-limit: '1Ki' - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. To test the buffer limit, create a payload in a temp file that exceeds the 1Ki buffer limit. - ```sh - dd if=/dev/zero bs=2048 count=1 | base64 -w 0 > /tmp/large_payload_2k.txt - ``` - -4. Send a request to the `/anything` httpbin path with the large payload. Verify that the request fails with a connection error or timeout, indicating that the buffer limit was exceeded. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik -X POST http://$INGRESS_GW_ADDRESS:8080/anything \ - -H "host: www.example.com:8080" \ - -H "Content-Type: text/plain" \ - -d "{\"payload\": \"$(< /tmp/large_payload_2k.txt)\"}" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik -X POST http://localhost:8080/anything \ - -H "host: www.example.com:8080" \ - -H "Content-Type: text/plain" \ - -d "{\"payload\": \"$(< /tmp/large_payload_2k.txt)\"}" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * upload completely sent off: 2747 bytes - < HTTP/1.1 413 Payload Too Large - HTTP/1.1 413 Payload Too Large - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < content-length: 17 - content-length: 17 - < server: envoy - server: envoy - ``` - -5. Test the buffer limit again by sending a request with a small payload, `"hello world"`. This request succeeds with a normal response from httpbin because the payload size is within the 1Ki limit. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik -X POST http://$INGRESS_GW_ADDRESS:8080/anything \ - -H "host: www.example.com:8080" \ - -H "Content-Type: application/json" \ - -d "{\"payload\": \"hello world\"}" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik -X POST http://localhost:8080/anything \ - -H "host: www.example.com:8080" \ - -H "Content-Type: application/json" \ - -d "{\"payload\": \"hello world\"}" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```json - * upload completely sent off: 27 bytes - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - "url": "http://www.example.com:8080/anything", - "data": "{\"payload\": \"hello world\"}", - "files": null, - "form": null, - "json": { - "payload": "hello world" - } - } - ``` diff --git a/assets/docs/pages/traffic-management/destination-types/backends/lambda/creds-secret.md b/assets/docs/pages/traffic-management/destination-types/backends/lambda/creds-secret.md deleted file mode 100644 index f4dde34e1..000000000 --- a/assets/docs/pages/traffic-management/destination-types/backends/lambda/creds-secret.md +++ /dev/null @@ -1,208 +0,0 @@ -Use {{< reuse "/agw-docs/snippets/kgateway.md" >}} to route traffic requests directly to an [Amazon Web Services (AWS) Lambda](https://aws.amazon.com/lambda/resources/) function. - -Note that this guide uses a Kubernetes secret that contains **long-lived IAM user access keys** (prefixed `AKIA`), not temporary STS/SSO credentials, which can cause failures with signature errors. To use AWS IAM roles to control access instead, see [Access AWS Lambda with a service account]({{< link-hextra path="/traffic-management/destination-types/backends/lambda/service-accounts/" >}}). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Create an AWS credentials secret - -Create a Kubernetes secret that contains your AWS access key and secret key. You must use a long-lived IAM user access keys (prefixed `AKIA`), not temporary STS/SSO credentials. {{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} uses this secret to connect to AWS Lambda for authentication and function invocation. - -1. Save the AWS account and region that your Lambda instance exists in as environment variables. - ```sh - export REGION= - export ACCOUNT_ID= - ```` - -2. Save your IAM user access key (prefixed `AKIA...`) and secret key as environment variables. Make sure that the `AWS_SESSION_TOKEN` is **not** set. - ```bash - export AWS_ACCESS_KEY_ID="" - export AWS_SECRET_ACCESS_KEY="" - ``` - If you do not have a long-lived IAM user access key pair, you can create one for your IAM user. - * AWS console: - 1. Navigate to **IAM → Users → (your user)**. - 2. In the **Security credentials** tab, scroll to the **Access keys** panel, and click **Create access key**. - 3. Select the CLI option, and create the access key. - 4. Copy the output access key ID (prefixed `AKIA...`) and secret access key. - * `aws` CLI: - ```bash - aws iam create-access-key --user-name - ``` - -3. Verify that these credentials have the appropriate permissions to interact with AWS Lambda. - ```bash - aws sts get-caller-identity --region ${REGION} - aws lambda invoke --function-name echo2 --region ${REGION} /tmp/out.json - ``` - If either command fails, grant the IAM user Lambda invocation permissions in one of the following ways, and re-run the test commands. - * AWS console: - 1. Navigate to **IAM → Users → (your user)**. - 2. In the **Permissions** tab, click **Add permissions → Create inline policy**. - 3. Toggle to the **JSON** editor. - 4. Paste the following policy to allow Lambda function invocation. - ```json - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "lambda:InvokeFunction", - "Resource": "arn:aws:lambda:us-east-1:802411188784:function:echo2" - } - ] - } - ``` - * `aws` CLI: - ```bash - aws iam put-user-policy \ - --user-name \ - --policy-name AllowInvokeEcho2 \ - --policy-document "{ - \"Version\": \"2012-10-17\", - \"Statement\": [ - {\"Effect\": \"Allow\", \"Action\": \"lambda:InvokeFunction\", \"Resource\": \"arn:aws:lambda:${REGION}:${ACCOUNT_ID}:function:echo2\"} - ] - }" - ``` - -4. Create a Kubernetes secret that contains the AWS access key and secret key. Leave `sessionToken` empty for long-lived keys. - ```yaml - kubectl apply -n {{< reuse "/agw-docs/snippets/namespace.md" >}} -f - << EOF - apiVersion: v1 - kind: Secret - metadata: - name: aws-creds - stringData: - accessKey: ${AWS_ACCESS_KEY_ID} - secretKey: ${AWS_SECRET_ACCESS_KEY} - sessionToken: "" - type: Opaque - EOF - ``` - -## Create a Lambda function - -Create an AWS Lambda function to test {{< reuse "/agw-docs/snippets/kgateway.md" >}} routing. - -1. Log in to the AWS console and navigate to the Lambda page. - -2. Click the **Create Function** button. - -3. Name the function `echo` and click **Create function**. - -4. Replace the default contents of `index.mjs` with the following Node.js function, which returns a response body that contains exactly what was sent to the function in the request body. - - ```js - export const handler = async(event) => { - const response = { - statusCode: 200, - body: `Response from AWS Lambda. Here's the request you just sent me: ${JSON.stringify(event)}` - }; - return response; - }; - ``` - -5. Click **Deploy**. - -## Create a Backend and HTTPRoute - -Create `Backend` and `HTTPRoute` resources to route requests to the Lambda function. - -1. In your terminal, create a Backend resource that references the Lambda secret. Update the `region` with your AWS account region, such as `us-east-1`, and update the `accountId`. - - ```yaml - kubectl apply -f - <}} - spec: - type: AWS - aws: - region: ${REGION} - accountId: "${ACCOUNT_ID}" - auth: - type: Secret - secretRef: - name: aws-creds - lambda: - functionName: echo - EOF - ``` - -2. Create an HTTPRoute resource that references the `lambda` Backend. - - ```yaml - kubectl apply -f - <}} - spec: - parentRefs: - - name: http - namespace: {{< reuse "/agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /echo - backendRefs: - - name: lambda - namespace: {{< reuse "/agw-docs/snippets/namespace.md" >}} - group: gateway.kgateway.dev - kind: Backend - EOF - ``` - -3. Confirm that {{< reuse "/agw-docs/snippets/kgateway.md" >}} correctly routes requests to Lambda by sending a curl request to the `echo` function. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -H "Host: lambda.${REGION}.amazonaws.com" \ - $INGRESS_GW_ADDRESS:8080/echo \ - -d '{"key1":"value1", "key2":"value2"}' -X POST - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -H "Host: lambda.${REGION}.amazonaws.com" \ - localhost:8080/echo \ - -d '{"key1":"value1", "key2":"value2"}' -X POST - ``` - {{% /tab %}} - {{< /tabs >}} - - Example response: - - ```json - {"statusCode":200,"body":"Response from AWS Lambda. Here's the request you just sent me: {\"key1\":\"value1\",\"key2\":\"value2\"}"}% - ``` - -At this point, {{< reuse "/agw-docs/snippets/kgateway.md" >}} is routing directly to the `echo` Lambda function! - -## Cleanup - -{{% reuse "agw-docs/snippets/cleanup.md" %}} - -1. Delete the `lambda` HTTPRoute and `lambda` Backend. - - ```sh - kubectl delete HTTPRoute lambda -n {{< reuse "/agw-docs/snippets/namespace.md" >}} - kubectl delete Backend lambda -n {{< reuse "/agw-docs/snippets/namespace.md" >}} - ``` - -2. Delete the `aws-creds` secret. - - ```sh - kubectl delete secret aws-creds -n {{< reuse "/agw-docs/snippets/namespace.md" >}} - ``` - -3. Use the AWS Lambda console to delete the `echo` test function. - diff --git a/assets/docs/pages/traffic-management/destination-types/backends/lambda/service-accounts.md b/assets/docs/pages/traffic-management/destination-types/backends/lambda/service-accounts.md deleted file mode 100644 index 95f711cc7..000000000 --- a/assets/docs/pages/traffic-management/destination-types/backends/lambda/service-accounts.md +++ /dev/null @@ -1,396 +0,0 @@ -Associate an IAM role with a gateway proxy service account, and configure {{< reuse "/agw-docs/snippets/kgateway.md" >}} to use that service account to access AWS Lambda. - -## About - -Amazon Web Services (AWS) offers the ability to associate an IAM role with a Kubernetes service account, also known as creating an IRSA. {{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} supports discovering and invoking AWS Lambda functions by using an IRSA. For more information, see the [AWS documentation](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html). - -In this guide, you follow these steps: - -**AWS resources**: -* Associate your EKS cluster with an IAM OIDC provider -* Create an IAM policy that allows interactions with Lambda functions -* Create an IAM role that associates the IAM policy with the gateway proxy service account (an IRSA) -* Deploy the Amazon EKS Pod Identity Webhook to your cluster -* Create a Lambda function for testing - -**{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} resources**: -* Install {{< reuse "/agw-docs/snippets/kgateway.md" >}} -* Annotate the gateway proxy service account with the IRSA -* Set up routing to your function by creating `Upstream` and `HTTPRoute` resources - -## Before you begin - -{{< callout type="warning" >}} -This guide requires you to enable IAM settings in your EKS cluster, such as the AWS Pod Identity Webhook, **before** you deploy {{< reuse "/agw-docs/snippets/kgateway.md" >}} components that are created during installation, such as the Gateway CRD and the gateway proxy service account. You might use this guide with a fresh EKS test cluster to try out Lambda function invocation with {{< reuse "/agw-docs/snippets/kgateway.md" >}} service accounts. -{{< /callout >}} - -## Configure AWS IAM resources {#iam} - -Save your AWS details, and create an IRSA for the gateway proxy pod to use. - -1. Save the region where your Lambda functions exist, the region where your EKS cluster exists, your cluster name, and the ID of the AWS account. - ```sh - export AWS_LAMBDA_REGION= - export AWS_CLUSTER_REGION= - export CLUSTER_NAME= - export AWS_ACCOUNT_ID= - ``` - -2. Save and verify your cluster's OIDC provider details. - 1. Get the OIDC provider for your cluster, in the format `oidc.eks..amazonaws.com/id/`. - ```sh - export OIDC_PROVIDER=$(aws eks describe-cluster --name ${CLUSTER_NAME} --region ${AWS_CLUSTER_REGION} --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///") - echo $OIDC_PROVIDER - ``` - * If an OIDC provider is not returned, follow the AWS documentation to [Create an IAM OIDC provider for your cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html), and then run this command again to save the OIDC provider in an environment variable. - 2. Verify that the OIDC provider's ARN is listed as an entry in AWS IAM. - ```sh - aws iam list-open-id-connect-providers \ - --query "OpenIDConnectProviderList[?contains(Arn, '${OIDC_PROVIDER}')].Arn" \ - --output text - ``` - * If your OIDC provider is not returned, add it to IAM. - ```sh - aws iam create-open-id-connect-provider \ - --url "https://${OIDC_PROVIDER}" \ - --client-id-list sts.amazonaws.com \ - --thumbprint-list "$(openssl s_client -servername $(echo ${OIDC_PROVIDER} | cut -d/ -f1) -showcerts -connect $(echo ${OIDC_PROVIDER} | cut -d/ -f1):443 /dev/null | openssl x509 -fingerprint -noout -sha1 | cut -d= -f2 | tr -d ':')" - ``` - -3. Create an IAM policy to allow access to the following four Lambda actions. Note that the permissions to discover and invoke functions are listed in the same policy. In a more advanced setup, you might separate discovery and invocation permissions into two IAM policies. - ```sh - cat >policy.json <}}` namespace is specified, because in later steps you create an HTTP gateway named `http`. - ```sh - cat >role.json <}}:http" - } - } - } - ] - } - EOF - - aws iam create-role --role-name lambda-role --assume-role-policy-document file://role.json - ``` - 2. Attach the IAM role to the IAM policy. This IAM role for the service account is known as an IRSA. - ```sh - aws iam attach-role-policy --role-name lambda-role --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/lambda-policy - ``` - 3. Verify that the policy is attached to the role. - ```sh - aws iam list-attached-role-policies --role-name lambda-role - ``` - Example output: - ```json - { - "AttachedPolicies": [ - { - "PolicyName": "lambda-policy", - "PolicyArn": "arn:aws:iam::111122223333:policy/lambda-policy" - } - ] - } - ``` - -## Deploy the Amazon EKS Pod Identity Webhook {#webhook} - -**Before you install {{< reuse "/agw-docs/snippets/kgateway.md" >}}**, deploy the [Amazon EKS Pod Identity Webhook](https://github.com/aws/amazon-eks-pod-identity-webhook/), which allows pods' service accounts to use AWS IAM roles. When you create the {{< reuse "/agw-docs/snippets/kgateway.md" >}} proxy in the next section, this webhook mutates the proxy's service account so that it can assume your IAM role to invoke Lambda functions. - -1. In your EKS cluster, install [cert-manager](https://cert-manager.io/docs/), which is a prerequisite for the webhook. - ```sh - wget https://github.com/cert-manager/cert-manager/releases/download/v1.12.4/cert-manager.yaml - kubectl apply -f cert-manager.yaml - ``` - -2. Verify that all cert-manager pods are running. - ```sh - kubectl get pods -n cert-manager - ``` - -3. Deploy the Amazon EKS Pod Identity Webhook. - ```sh - kubectl apply -f https://raw.githubusercontent.com/solo-io/workshops/refs/heads/master/kgateway/2-1/default/data/steps/deploy-amazon-pod-identity-webhook/auth.yaml - kubectl apply -f https://raw.githubusercontent.com/solo-io/workshops/refs/heads/master/kgateway/2-1/default/data/steps/deploy-amazon-pod-identity-webhook/deployment-base.yaml - kubectl apply -f https://raw.githubusercontent.com/solo-io/workshops/refs/heads/master/kgateway/2-1/default/data/steps/deploy-amazon-pod-identity-webhook/mutatingwebhook.yaml - kubectl apply -f https://raw.githubusercontent.com/solo-io/workshops/refs/heads/master/kgateway/2-1/default/data/steps/deploy-amazon-pod-identity-webhook/service.yaml - ``` - -4. Verify that the webhook deployment completes. - ```sh - kubectl rollout status deploy/pod-identity-webhook - ``` - -## Install {{< reuse "/agw-docs/snippets/kgateway.md" >}} {#install} - -Be sure that you [deployed the Amazon EKS Pod Identity Webhook](#webhook) to your cluster first before you continue to install {{< reuse "/agw-docs/snippets/kgateway.md" >}}. - -{{< reuse "agw-docs/snippets/envoy/get-started.md" >}} - -## Annotate the gateway proxy service account {#annotate} - -1. Create a GatewayParameters resource to specify the `eks.amazonaws.com/role-arn` IRSA annotation for the gateway proxy service account. - ```yaml - kubectl apply -f- <}} - spec: - kube: - serviceAccount: - extraAnnotations: - eks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/lambda-role - EOF - ``` - -2. Create the following `http` Gateway resource, which includes a reference to the `http-lambda` GatewayParameters. - ```yaml - kubectl apply -f- <}} - annotations: - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - infrastructure: - parametersRef: - name: http-lambda - group: gateway.kgateway.dev - kind: GatewayParameters - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. Check the status of the gateway to make sure that your configuration is accepted. Note that in the output, a `NoConflicts` status of `False` indicates that the gateway is accepted and does not conflict with other gateway configuration. - ```sh - kubectl get gateway http -n {{< reuse "/agw-docs/snippets/namespace.md" >}} -o yaml - ``` - -4. Verify that the `http` service account has the `eks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/lambda-role` annotation. - ```sh - kubectl describe serviceaccount http -n {{< reuse "/agw-docs/snippets/namespace.md" >}} - ``` - -## Create a Lambda function - -Create an AWS Lambda function to test {{< reuse "/agw-docs/snippets/kgateway.md" >}} routing. - -1. Log in to the AWS console and navigate to the Lambda page. - -2. Click the **Create Function** button. - -3. Name the function `echo` and click **Create function**. - -4. Replace the default contents of `index.mjs` with the following Node.js function, which returns a response body that contains exactly what was sent to the function in the request body. - - ```js - export const handler = async(event) => { - const response = { - statusCode: 200, - body: `Response from AWS Lambda. Here's the request you just sent me: ${JSON.stringify(event)}` - }; - return response; - }; - ``` - -5. Click **Deploy**. - -## Set up routing to your function {#routing} - -Create `Backend` and `HTTPRoute` resources to route requests to the Lambda function. - -1. Create a Backend resource that references the AWS region, ID of the account that contains the IAM role, and `echo` function that you created. - ```yaml - kubectl apply -f - <}} - spec: - type: AWS - aws: - region: ${AWS_LAMBDA_REGION} - accountId: "${AWS_ACCOUNT_ID}" - lambda: - functionName: echo - EOF - ``` - -2. Create an HTTPRoute resource that references the `lambda` Backend. - - ```yaml - kubectl apply -f - <}} - spec: - parentRefs: - - name: http - namespace: {{< reuse "/agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /echo - backendRefs: - - name: lambda - namespace: {{< reuse "/agw-docs/snippets/namespace.md" >}} - group: gateway.kgateway.dev - kind: Backend - EOF - ``` - -3. Get the external address of the gateway and save it in an environment variable. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "/agw-docs/snippets/namespace.md" >}} http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/http -n {{< reuse "/agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - {{% /tab %}} - {{< /tabs >}} - -4. Confirm that {{< reuse "/agw-docs/snippets/kgateway.md" >}} correctly routes requests to Lambda by sending a curl request to the `echo` function. Note that the first request might take a few seconds to process, because the AWS Security Token Service (STS) credential request must be performed first. However, after the credentials are cached, subsequent requests are processed more quickly. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -H "Host: lambda.${AWS_LAMBDA_REGION}.amazonaws.com" \ - $INGRESS_GW_ADDRESS:8080/echo \ - -d '{"key1":"value1", "key2":"value2"}' -X POST - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -H "Host: lambda.${AWS_LAMBDA_REGION}.amazonaws.com" \ - $INGRESS_GW_ADDRESS:8080/echo \ - -d '{"key1":"value1", "key2":"value2"}' -X POST - ``` - {{% /tab %}} - {{< /tabs >}} - - Example response: - ```json - {"statusCode":200,"body":"Response from AWS Lambda. Here's the request you just sent me: {\"key1\":\"value1\",\"key2\":\"value2\"}"}% - ``` - -At this point, {{< reuse "/agw-docs/snippets/kgateway.md" >}} is routing directly to the `echo` Lambda function using an IRSA! - -## Cleanup - -{{% reuse "agw-docs/snippets/cleanup.md" %}} - -### Resources for the `echo` function - -1. Delete the `lambda` HTTPRoute and `lambda` Backend. - ```sh - kubectl delete HTTPRoute lambda -n {{< reuse "/agw-docs/snippets/namespace.md" >}} - kubectl delete Backend lambda -n {{< reuse "/agw-docs/snippets/namespace.md" >}} - ``` - -2. Use the AWS Lambda console to delete the `echo` test function. - -### IRSA authorization (optional) - -If you no longer need to access Lambda functions from {{< reuse "/agw-docs/snippets/kgateway.md" >}}: - -1. Delete the GatewayParameters resources. - ```sh - kubectl delete GatewayParameters http-lambda -n {{< reuse "/agw-docs/snippets/namespace.md" >}} - ``` - -2. Remove the reference to the `http-lambda` GatewayParameters from the `http` Gateway. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. Delete the pod identity webhook. - ```sh - kubectl delete deploy pod-identity-webhook - ``` - -4. Remove cert-manager. - ```sh - kubectl delete -f cert-manager.yaml -n cert-manager - kubectl delete ns cert-manager - ``` - -5. Delete the AWS IAM resources that you created. - ```sh - aws iam detach-role-policy --role-name lambda-role --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/lambda-policy - aws iam delete-role --role-name lambda-role - aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/lambda-policy - ``` - diff --git a/assets/docs/pages/traffic-management/destination-types/kube-services/grpc-services.md b/assets/docs/pages/traffic-management/destination-types/kube-services/grpc-services.md deleted file mode 100644 index 3eea26208..000000000 --- a/assets/docs/pages/traffic-management/destination-types/kube-services/grpc-services.md +++ /dev/null @@ -1,362 +0,0 @@ -Route traffic to gRPC services using the GRPCRoute resource for protocol-aware routing. - -## About - -GRPCRoute provides protocol-aware routing for gRPC traffic within the Kubernetes Gateway API. Unlike HTTPRoute, which requires matching on HTTP paths and methods, GRPCRoute allows you to define routing rules using gRPC-native concepts like service and method names. - -Consider the difference: -- **HTTPRoute Match**: `path:/com.example.User/Login`, `method: POST` -- **GRPCRoute Match**: `service: yages.Echo`, `method: Ping` - -The GRPCRoute approach is more readable, less error-prone, and aligns with the Gateway API's role-oriented philosophy. - -## Before you begin - -1. [Install {{< reuse "/agw-docs/snippets/kgateway.md" >}}]({{< link-hextra path="/quickstart/" >}}) in a cluster. -2. [Install `grpcurl`](https://github.com/fullstorydev/grpcurl) for testing on your computer. - -## Deploy a sample gRPC service {#sample-grpc} - -Deploy a sample gRPC service for testing purposes. The sample service has two APIs: - -- `yages.Echo.Ping`: Takes no input (empty message) and returns a `pong` message. -- `yages.Echo.Reverse`: Takes input content and returns the content in reverse order, such as `hello world` becomes `dlrow olleh`. - -Steps to set up the sample gRPC service: - -1. Deploy the gRPC echo server and client. - - ```yaml - kubectl apply -f - <}} - to: - - group: "" - kind: Service - EOF - ``` - - Example output: - ```txt - referencegrant.gateway.networking.k8s.io/allow-grpc-route-to-echo created - ``` - -## Set up the Gateway for gRPC routes {#gateway} - -Create an HTTPS listener so that the gateway can route gRPC traffic. GRPCRoute requires HTTPS listeners for TLS termination. For more information, see the [HTTPS listener guide](../../../../setup/listeners/https/). - -1. Create a TLS certificate for testing. - - ```bash - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout grpc.example.com.key \ - -out grpc.example.com.crt \ - -subj "/CN=grpc.example.com" - - kubectl create secret tls grpc-example-com-cert \ - -n {{< reuse "agw-docs/snippets/namespace.md" >}} \ - --key grpc.example.com.key \ - --cert grpc.example.com.crt - ``` - -2. Create a Gateway resource with an HTTPS listener. - - ```yaml - kubectl apply -f - <}} - labels: - app: grpc-echo - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTPS - port: 443 - name: https - hostname: "grpc.example.com" - tls: - mode: Terminate - certificateRefs: - - name: grpc-example-com-cert - allowedRoutes: - namespaces: - from: All - EOF - ``` - - {{< reuse "agw-docs/snippets/review-table.md" >}} - - | Setting | Description | - |---------|-------------| - | `spec.gatewayClassName` | The name of the Kubernetes GatewayClass. When you set up {{< reuse "/agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. | - | `spec.listeners` | Configure the listeners for this Gateway. GRPCRoute requires HTTPS listeners with TLS termination. | - | `hostname` | The hostname for SNI-based routing. Must match the hostname in your GRPCRoute. | - | `tls.mode: Terminate` | Terminates TLS at the gateway, required for GRPCRoute. | - -3. Check the status of the Gateway. - - ```bash - kubectl get gateway grpc-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml - ``` - - Example output: - ```yaml - status: - addresses: - - type: IPAddress - value: ${INGRESS_GW_ADDRESS} - conditions: - - lastTransitionTime: "2024-11-20T16:01:25Z" - message: "" - observedGeneration: 2 - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: "2024-11-20T16:01:25Z" - message: "" - observedGeneration: 2 - reason: Programmed - status: "True" - type: Programmed - ``` - -## Create a GRPCRoute {#create-grpcroute} - -1. Create the GRPCRoute resource. Include the `grpc.reflection.v1alpha.ServerReflection` method to enable dynamic API exploration. For detailed information about GRPCRoute fields and configuration options, see the [Gateway API GRPCRoute documentation](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GRPCRoute). - - ```yaml - kubectl apply -f - <}} - labels: - app: grpc-echo - spec: - parentRefs: - - name: grpc-gateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - sectionName: https - hostnames: - - "grpc.example.com" - rules: - - matches: - - method: - service: "grpc.reflection.v1alpha.ServerReflection" - backendRefs: - - name: grpc-echo-svc - namespace: default - port: 3000 - - backendRefs: - - name: grpc-echo-svc - namespace: default - port: 3000 - EOF - ``` - -2. Verify that the GRPCRoute is applied successfully. - - ```bash - kubectl get grpcroute grpc-echo-route -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml - ``` - - Example output: - ```yaml - status: - parents: - - conditions: - - lastTransitionTime: "2024-11-21T16:22:52Z" - message: "" - observedGeneration: 1 - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: "2024-11-21T16:22:52Z" - message: "" - observedGeneration: 1 - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - controllerName: kgateway.dev/kgateway - parentRef: - group: gateway.networking.k8s.io - kind: Gateway - name: grpc-gateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - sectionName: https - ``` - -## Verify the gRPC route {#verify-grpcroute} - -Verify that the gRPC route to the echo service is working. - -1. Get the external address of the gateway and save it in an environment variable. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```bash - export GATEWAY_IP=$(kubectl get gateway grpc-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o jsonpath='{.status.addresses[0].value}') - echo $GATEWAY_IP - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```bash - kubectl port-forward svc/grpc-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:443 - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Explore the API dynamically. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```bash - grpcurl -insecure -authority grpc.example.com $GATEWAY_IP:443 list - grpcurl -insecure -authority grpc.example.com $GATEWAY_IP:443 describe yages.Echo - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```bash - grpcurl -insecure -authority grpc.example.com localhost:8443 list - grpcurl -insecure -authority grpc.example.com localhost:8443 describe yages.Echo - ``` - {{% /tab %}} - {{< /tabs >}} - - Expected response: - ``` - grpc.health.v1.Health - grpc.reflection.v1alpha.ServerReflection - yages.Echo - yages.Echo is a service: - service Echo { - rpc Ping ( .yages.Empty ) returns ( .yages.Content ); - rpc Reverse ( .yages.Content ) returns ( .yages.Content ); - } - ``` - -3. Send a gRPC request to test the route. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```bash - grpcurl -insecure \ - -authority grpc.example.com \ - $GATEWAY_IP:443 \ - yages.Echo/Ping - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```bash - grpcurl -insecure \ - -authority grpc.example.com \ - localhost:8443 \ - yages.Echo/Ping - ``` - {{% /tab %}} - {{< /tabs >}} - - Expected response: - ```json - { - "text": "pong" - } - ``` - -## Next steps - -Explore the traffic management, resiliency, and security policies that you can apply to make your gRPC services more robust and secure. - -{{< cards >}} - {{< card link="../../../../traffic-management/" title="Traffic management" >}} - {{< card link="../../../../resiliency/" title="Resiliency" >}} - {{< card link="../../../../security/" title="Security" >}} -{{< /cards >}} - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```bash -kubectl delete -A gateways,grpcroutes,pod,svc,secrets -l app=grpc-echo -kubectl delete referencegrant allow-grpc-route-to-echo -n default -``` - diff --git a/assets/docs/pages/traffic-management/destination-types/kube-services/http-services.md b/assets/docs/pages/traffic-management/destination-types/kube-services/http-services.md deleted file mode 100644 index bd3119c2c..000000000 --- a/assets/docs/pages/traffic-management/destination-types/kube-services/http-services.md +++ /dev/null @@ -1,32 +0,0 @@ -Route traffic to an HTTP or HTTPS Kubernetes service. - -You can route to a Kubernetes service by referencing that service in the `backendRefs` section of your HTTPRoute resource as shown in the following example. - -{{< callout type="info" >}} -Most guides in this documentation route traffic to a Kubernetes service directly. If you want to route to external resources, such as a static hostname or AWS resource, create a [Backend]({{< link-hextra path="/traffic-management/destination-types/backends/" >}}) resource. -{{< /callout >}} - -```yaml {linenos=table,hl_lines=[13,14,15],linenostart=1,filename="k8s-service-httproute.yaml"} -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: kube-backend - namespace: default -spec: - parentRefs: - - name: http - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - hostnames: - - httpbin.example.com - rules: - - backendRefs: - - name: httpbin - port: 8000 - filters: - - type: ExtensionRef - extensionRef: - group: gateway.kgateway.dev - kind: TrafficPolicy - name: rewrite -``` - diff --git a/assets/docs/pages/traffic-management/dfp.md b/assets/docs/pages/traffic-management/dfp.md deleted file mode 100644 index 5c4abeb6a..000000000 --- a/assets/docs/pages/traffic-management/dfp.md +++ /dev/null @@ -1,111 +0,0 @@ -Dynamically resolve upstream hosts at request time. - -## About Dynamic Forward Proxy - -Dynamic Forward Proxy (DFP) is a filter in Envoy that allows a gateway proxy to act as a generic HTTP(S) forward proxy without the need to preconfigure all possible upstream hosts. Instead, the DFP dynamically resolves the upstream host at request time by using DNS. - -DFPs are especially useful in highly dynamic environments where services come up and down frequently. Such churn makes it hard for a service registry to list all available endpoints at a given time. With DFP, you do not need to have pre-defined destinations. This approach gives you more flexibility to resolve endpoints as the request comes in. - -Another common use case for DFPs is to control and monitor all egress traffic. For example, you can apply policies, such as rate limiting, authentication, authorization, and access logging. You can also easily access metrics for the egress traffic that is routed through the forward proxy. - -DFPs are configured in a Backend resource and an HTTPRoute that routes traffic to the DFP Backend. If a request reaches the gateway proxy, the proxy extracts the host header value from the request and uses DNS to resolve the host to an IP address. Then, the request is forwarded to the resolved IP address. - -### Considerations - -DFPs offer great flexibility for defining routing patterns for your upstream hosts. However, consider the following downsides when using a DFP: - -* You cannot configure failover or client-side load balancing policies for DFP-configured routes because no pre-defined upstream hosts exist that determine the desired upstream service. -* DNS resolution is done at runtime, which can have performance implications. If Envoy detects a new domain name, Envoy pauses the request and synchronously resolves this domain to get the IP address of the endpoint. Then, Envoy caches the IP address locally. - - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up a Dynamic Forward Proxy - -1. Create a Backend for the Dynamic Forward Proxy. - ```yaml - kubectl apply -f- <}} - rules: - - backendRefs: - - name: dfp-backend - group: gateway.kgateway.dev - kind: Backend - EOF - ``` - -3. Send a request to a hostname of your choice, such as `httpbin.org`. Verify that your gateway proxy successfully resolves the `httpbin.org` host and returns its welcome page. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik http://$INGRESS_GW_ADDRESS:8080 -H "host: httpbin.org" - ``` - {{% /tab %}} - {{% tab tabName="Port forward for local testing" %}} - ```sh - curl -vik http://localhost:8080 -H "host: httpbin.org" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - - - - - - httpbin.org - - - - - - -

Welcome to nginx!

-

If you see this page, the nginx web server is successfully installed and - working. Further configuration is required.

- -

For online documentation and support please refer to - nginx.org.
- Commercial support is available at - nginx.com.

- -

Thank you for using nginx.

- - - ``` - -5. Get the access logs of your gateway proxy. - ```sh - kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} logs deployments/http | tail -1 | jq --sort-keys - ``` - - Example output: - ```console {hl_lines=[9]} - { - "authority": "http2.example.com:8080", - "backendCluster": "kube_default_nginx_8080", - "backendHost": "10.0.2.26:80", - "bytes_received": 0, - "bytes_sent": 615, - "method": "GET", - "path": "/", - "protocol": "HTTP/2", - "req_x_forwarded_for": "10.0.15.215", - "request_id": "c996b154-9299-4f00-b356-8cc66472e613", - "resp_backend_service_time": "0", - "response_code": 200, - "response_flags": "-", - "start_time": "2025-06-23T16:23:09.615Z", - "total_duration": 0, - "user_agent": "curl/8.7.1" - } - ``` - - -## HTTP/2 for external services - -1. Create a Backend resource that represents your external service. In this example, you configure a Backend for the `https://nghttp2.org/httpbin/` domain. This domain requires requests to be sent with the HTTP/2 protocol. - ```yaml - kubectl apply -f- <}} - hostnames: - - static.example - rules: - - backendRefs: - - name: http2 - kind: Backend - group: gateway.kgateway.dev - filters: - - type: URLRewrite - urlRewrite: - hostname: nghttp2.org - path: - type: ReplacePrefixMatch - replacePrefixMatch: /httpbin/ - EOF - ``` - -3. Send a request to the `static.example` domain. The request is forwarded to the `nghttp2.org/httpbin/` path, which only accepts HTTP/2 requests. Verify that the request succeeds and that you get back a 200 HTTP response code. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik http://$INGRESS_GW_ADDRESS:8080/ -H "host: static.example:8080" --http2-prior-knowledge - ``` - - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/ -H "host: static.example" --http2-prior-knowledge - ``` - - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[8,9]} - ... - > GET / HTTP/2 - > Host: static.example:8080 - > User-Agent: curl/8.7.1 - > Accept: */* - > - * Request completely sent off - < HTTP/2 200 - HTTP/2 200 - < content-type: text/html; charset=utf-8 - content-type: text/html; charset=utf-8 - < content-length: 9649 - content-length: 9649 - < access-control-allow-origin: * - access-control-allow-origin: * - < access-control-allow-credentials: true - access-control-allow-credentials: true - < x-backend-header-rtt: 6.191667 - x-backend-header-rtt: 6.191667 - < alt-svc: h3=":443"; ma=3600 - alt-svc: h3=":443"; ma=3600 - < server: envoy - server: envoy - < via: 1.1 nghttpx - via: 1.1 nghttpx - < x-frame-options: SAMEORIGIN - x-frame-options: SAMEORIGIN - < x-xss-protection: 1; mode=block - x-xss-protection: 1; mode=block - < x-content-type-options: nosniff - x-content-type-options: nosniff - < x-envoy-upstream-service-time: 6504 - x-envoy-upstream-service-time: 6504 - < - ... - ``` - -4. Get the access logs of your gateway proxy. - ```sh - kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} logs deployments/http | tail -1 | jq --sort-keys - ``` - - Example output: - ```console {hl_lines=[9]} - { - "authority": "nghttp2.org", - "backendCluster": "backend_default_http2_0", - "backendHost": "139.162.123.134:80", - "bytes_received": 0, - "bytes_sent": 9649, - "method": "GET", - "path": "/", - "protocol": "HTTP/2", - "req_x_forwarded_for": "10.0.9.76", - "request_id": "6e8baf82-2c2b-40cc-b5c0-d2d2295d3abf", - "resp_backend_service_time": "313", - "response_code": 200, - "response_flags": "-", - "start_time": "2025-06-23T16:25:22.639Z", - "total_duration": 314, - "user_agent": "curl/8.7.1" - } - ``` - - - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute nginx -kubectl delete pod nginx -kubectl delete service nginx -kubectl delete configmap nginx-conf -kubectl delete backend http2 -kubectl delete httproute http2 -``` - - - diff --git a/assets/docs/pages/traffic-management/match/header.md b/assets/docs/pages/traffic-management/match/header.md deleted file mode 100644 index a1356a548..000000000 --- a/assets/docs/pages/traffic-management/match/header.md +++ /dev/null @@ -1,220 +0,0 @@ -Specify a set of headers which incoming requests must match in entirety, such as with regular expressions (regex). - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/api-types/httproute/#matches). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up exact header matching - -Match headers by an exact string, such as `version`. - -1. Create an HTTPRoute resource. - ```yaml - kubectl apply -f- <}} - hostnames: - - match.example - rules: - - matches: - - headers: - - name: version - value: v2 - type: Exact - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Send a request to the httpbin app on the `match.example` domain without any headers. Verify that you get back a 404 HTTP response code as no matching request could be found. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 404 Not Found - HTTP/1.1 404 Not Found - < date: Sat, 04 Nov 2023 03:16:43 GMT - date: Sat, 04 Nov 2023 03:16:43 GMT - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -3. Send another request to the httpbin app on the `match.example` domain. This time, add the `version: v2` header that you configured in the HTTPRoute. Verify that your request now succeeds and you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: match.example:8080" -H "version: v2" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: match.example" -H "version: v2" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < date: Sat, 04 Nov 2023 03:19:26 GMT - date: Sat, 04 Nov 2023 03:19:26 GMT - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -## Set up regex header matching - -Match headers with regular expressions (regex). - -1. Create an HTTPRoute resource to match multiple headers with regex. Only if all headers are present in the request, the request is accepted and processed by the gateway proxy. The following rules apply: - * ` (dogs|cats)`: The value of the `pet` request header must either be `dogs` or `cats`. - * `\\d[.]\\d.*`: The value of the `version` header must meet the following conditions: - * `\\d` matches a single digit. - * `[.]` matches a literal period. - * `\\d.*` matches a single digit followed by zero or any character. - * Allowed pattern: `3.0-game`, not allowed: `30` - * `Bearer\s.*`: The value of the `Authorization` request header must be `Bearer` followed by a space (`\s`), followed by zero or any characters (`.*`). - * Allowed pattern: `Bearer 123`, not allowed: `Bearer` - ```yaml - kubectl apply -f- <}} - hostnames: - - match.example - rules: - - matches: - - headers: - - name: pet - value: (dogs|cats) - type: RegularExpression - - name: version - value: \\d[.]\\d.* - type: RegularExpression - - name: Authorization - value: Bearer\s.* - type: RegularExpression - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Send a request to the httpbin app on the `match.example` domain and add valid values for each of your headers. Verify that the request succeeds and you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: match.example:8080" -H "host: match.example" \ - -H "Authorization: Bearer 123" \ - -H "pet: dogs" \ - -H "version: 3.0" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: match.example" -H "host: match.example" \ - -H "Authorization: Bearer 123" \ - -H "pet: dogs" \ - -H "version: 3.0" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -3. Send another request to the httpbin app on the `match.example` domain. This time, you change the value of the `version` header to an invalid value that does not meet the regular expression that you defined. Verify that the request is denied with a 404 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: match.example:8080" -H "host: match.example" \ - -H "Authorization: Bearer 123" \ - -H "pet: dogs" \ - -H "version: 30" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: match.example" -H "host: match.example" \ - -H "Authorization: Bearer 123" \ - -H "pet: dogs" \ - -H "version: 30" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Request completely sent off - < HTTP/1.1 404 Not Found - HTTP/1.1 404 Not Found - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - - ``` -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-match -n httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/match/host.md b/assets/docs/pages/traffic-management/match/host.md deleted file mode 100644 index 0fb66c46c..000000000 --- a/assets/docs/pages/traffic-management/match/host.md +++ /dev/null @@ -1,104 +0,0 @@ -Expose a route on multiple hosts. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/api-types/httproute/#matches). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up host matching - -1. Create an HTTPRoute that is exposed on two domains, `host1.example` and `host2.example`. - ```yaml - kubectl apply -f- <}} - hostnames: - - host1.example - - host2.example - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Send a request to the `/status/200` path of the httpbin app on the `host1.example` domain. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: host1.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: host1.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -3. Send another request to the httpbin app. This time, you send it along the `host2.example` domain. Verify that the request succeeds and that you also get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: host2.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: host2.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-match -n httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/match/method.md b/assets/docs/pages/traffic-management/match/method.md deleted file mode 100644 index 4e1f9afb4..000000000 --- a/assets/docs/pages/traffic-management/match/method.md +++ /dev/null @@ -1,133 +0,0 @@ -Specify an HTTP method, such as POST, GET, PUT, PATCH, or DELETE, to match requests against. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/api-types/httproute/#matches). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up HTTP method matching - -1. Create an HTTPRoute resource for the `match.example` domain that serves incoming GET requests for the httpbin app. - ```yaml - kubectl apply -f- <}} - hostnames: - - match.example - rules: - - matches: - - method: "GET" - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Send a GET request to the httpbin app on the `match.example` domain. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/get -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/get -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-type: application/json; encoding=utf-8 - content-type: application/json; encoding=utf-8 - < date: Sat, 04 Nov 2023 03:34:12 GMT - date: Sat, 04 Nov 2023 03:34:12 GMT - < content-length: 422 - content-length: 422 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - - < - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "match.example:8080" - ], - "User-Agent": [ - "curl/7.77.0" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "6823bc28-ba8e-47df-a3a0-1aa21628db0e" - ] - }, - "origin": "10.116.3.7:47022", - "url": "http://match.example:8080/get" - } - ``` - -3. Send another request to the httpbin app on the `match.example` domain. This time, you use the `POST` method. Verify that your request is not forwarded to the httpbin app and that you get back a 404 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi -X POST http://$INGRESS_GW_ADDRESS:8080/post -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi -X POST localhost:8080/post -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 404 Not Found - HTTP/1.1 404 Not Found - < date: Tue, 23 Apr 2024 18:47:53 GMT - date: Tue, 23 Apr 2024 18:47:53 GMT - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ... - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-match -n httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/match/path.md b/assets/docs/pages/traffic-management/match/path.md deleted file mode 100644 index 6f8aa6580..000000000 --- a/assets/docs/pages/traffic-management/match/path.md +++ /dev/null @@ -1,320 +0,0 @@ -Match the targeted path of an incoming request against specific path criteria. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/api-types/httproute/#matches). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up exact matching - -1. Create an HTTPRoute resource for the `match.example` domain that matches incoming requests on the `/status/200` exact path. - ```yaml - kubectl apply -f- <}} - hostnames: - - match.example - rules: - - matches: - - path: - type: Exact - value: /status/200 - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Send a request to the `/status/200` path of the httpbin app on the `match.example` domain. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < date: Sat, 04 Nov 2023 03:19:26 GMT - date: Sat, 04 Nov 2023 03:19:26 GMT - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -3. Send another request to the httpbin app. This time, use the `/headers` path. Because this path is not specified in the HTTPRoute, the request fails and a 404 HTTP response code is returned. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 404 Not Found - HTTP/1.1 404 Not Found - < date: Tue, 23 Apr 2024 18:52:01 GMT - date: Tue, 23 Apr 2024 18:52:01 GMT - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -## Set up prefix path matching - -1. Create an HTTPRoute resource for the `match.example` domain that matches incoming requests on the `/anything` prefix path. - ```yaml - kubectl apply -f- <}} - hostnames: - - match.example - rules: - - matches: - - path: - type: PathPrefix - value: /anything - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Send a request to the `/anything/team1` path of the httpbin app on the `match.example` domain. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything/team1 -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/anything/team1 -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < date: Sat, 04 Nov 2023 03:19:26 GMT - date: Sat, 04 Nov 2023 03:19:26 GMT - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -3. Send another request to the httpbin app. This time, use the `/headers` path. Because this path is not specified in the HTTPRoute, the request fails and a 404 HTTP response code is returned. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 404 Not Found - HTTP/1.1 404 Not Found - < date: Tue, 23 Apr 2024 18:52:01 GMT - date: Tue, 23 Apr 2024 18:52:01 GMT - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -## Set up regex matching - -Use [RE2 syntax](https://github.com/google/re2/wiki/Syntax) for regular expressions to match incoming requests. - -1. Create an HTTPRoute resource for the `match.example` domain that uses a regular expression (regex) to match incoming requests. The following regex patterns are defined in the example: - * **`\/.*my-path.*`**: - * The request path must start with `/` - * The expression `.*` means that any character before and after the `my-path` string is allowed. - * Allowed pattern: `/anything/this-is-my-path-1`, not allowed: `/anything`. - * **`/anything/stores/[^/]+?/entities`**: - * The request path must start with `/anything/stores/`. - * `[^/]+?` matches any character except `/`. - * The request path must end with `/entities`. - * Allowed pattern: `/anything/stores/us/entities`, not allowed: `/anything/stores/us/south/entities`. - * **`/anything/(dogs|cats)/\\d[.]\\d.*`** - * The request path must start with `/anything/`, followed by either `dogs/` or `cats/`. - * `\\d` matches a single digit. - * `[.]` matches a literal period. - * `\\d.*` matches a single digit followed by zero or any character. - * Allowed pattern: `/anything/dogs/3.0-game`, not allowed: `/anything/birds` - ```yaml - kubectl apply -f- <}} - hostnames: - - "match.example" - rules: - - matches: - - path: - type: RegularExpression - value: \/.*my-path.* - - path: - type: RegularExpression - value: /anything/stores/[^/]+?/entities - - path: - type: RegularExpression - value: /anything/(dogs|cats)/\\d[.]\\d.* - backendRefs: - - name: httpbin - namespace: httpbin - port: 8000 - EOF - ``` - -2. Send multiple requests to the httpbin app on the `match.example` domain. - * `/anything/this-is-my-path-1` matches the regex pattern `\/.*my-path.*` - * `/anything/stores/us/entities` matches the regex pattern `/anything/stores/[^/]+?/entities` - * `/anything/dogs/3.0-game` matches the regex pattern `/anything/(dogs|cats)/\\d[.]\\d.*` - - Verify that the requests succeed and that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything/this-is-my-path-1 -H "host: match.example:8080" - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything/stores/us/entities -H "host: match.example:8080" - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything/dogs/3.0-game -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/anything/this-is-my-path-1 -H "host: match.example" - curl -vi localhost:8080/anything/stores/us/entities -H "host: match.example" - curl -vi localhost:8080/anything/dogs/3.0-game -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < date: Sat, 04 Nov 2023 03:19:26 GMT - date: Sat, 04 Nov 2023 03:19:26 GMT - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -3. Send requests to the httpbin app that do not meet the defined regex patterns. - * `/anything` does not match the regex pattern `\/.*my-path.*` - * `/anything/stores/us/south/entities` does not match the regex pattern `/anything/stores/[^/]+?/ - * `/anything/birds/1.1-game` does not match the regex pattern `/anything/(dogs|cats)/\\d[.]\\d.*` - - Verify that all requests fail with a 404 HTTP response code, because the path does not match the regex pattern that you defined. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: match.example:8080" - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything/stores/us/south/entities -H "host: match.example:8080" - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything/birds/1.1-game -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/anything -H "host: match.example" - curl -vi localhost:8080/anything/stores/us/south/entities -H "host: match.example" - curl -vi localhost:8080/anything/birds/1.1-game -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Request completely sent off - < HTTP/1.1 404 Not Found - HTTP/1.1 404 Not Found - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-match -n httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/match/query.md b/assets/docs/pages/traffic-management/match/query.md deleted file mode 100644 index e3d729293..000000000 --- a/assets/docs/pages/traffic-management/match/query.md +++ /dev/null @@ -1,106 +0,0 @@ -Specify a set of URL query parameters which requests must match in entirety. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/api-types/httproute/#matches). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up query parameter matching - -1. Create an HTTPRoute resource for the `match.example` domain that matches incoming requests with a `user=me` query parameter. - ```yaml - kubectl apply -f- <}} - hostnames: - - match.example - rules: - - matches: - - queryParams: - - type: Exact - value: me - name: user - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -2. Send a request to the `/status/200` path of the httpbin app on the `match.example` domain without any query parameters. Verify that your request is not forwarded to the httpbin app because no matching query parameter is found. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/status/200 -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 404 Not Found - HTTP/1.1 404 Not Found - < date: Sat, 04 Nov 2023 03:45:39 GMT - date: Sat, 04 Nov 2023 03:45:39 GMT - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -3. Send a request to the `/status/200` path of the httpbin app on the `match.example` domain. This time, you provide the `user=me` query parameter. Verify that your request now succeeds and that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi "http://$INGRESS_GW_ADDRESS:8080/status/200?user=me" -H "host: match.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi "localhost:8080/status/200?user=me" -H "host: match.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < date: Sat, 04 Nov 2023 03:49:17 GMT - date: Sat, 04 Nov 2023 03:49:17 GMT - < content-length: 0 - content-length: 0 - < x-envoy-upstream-service-time: 1 - x-envoy-upstream-service-time: 1 - < server: envoy - server: envoy - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-match -n httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/proxy-protocol.md b/assets/docs/pages/traffic-management/proxy-protocol.md deleted file mode 100644 index 0925d3d2c..000000000 --- a/assets/docs/pages/traffic-management/proxy-protocol.md +++ /dev/null @@ -1,69 +0,0 @@ -Preserve connection information such as the client IP address and port for traffic that goes through your gateway proxy. - -## About proxy protocol - -[Proxy Protocol](https://www.haproxy.org/download/2.1/doc/proxy-protocol.txt) is used to preserve a client’s IP address to ensure that upstream services receive the full network information, even when traffic is proxied through other components, such as an AWS Network Load Balancer or the gateway proxy itself. The gateway proxy and upstream services can then use this information to apply accurate rate limiting policies, make routing decisions, and properly log and audit traffic. - -Without proxy protocol, the proxy removes the source IP address on incoming requests and instead adds its own IP address to it. Upstream services can therefore only see the IP address of the last proxy that handled the request, which can impact security measures and access control. - - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Setup - -1. Create a ListenerPolicy resource to enable proxy protocol for the listeners on your gateway proxy. The following example enables proxy protocol on all listeners that are configured on the gateway. - ```yaml - kubectl apply -f- <}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: http - default: - proxyProtocol: {} - EOF - ``` - -2. Verify that your configuration is applied by reviewing the Envoy configuration. - ```sh - kubectl port-forward deploy/http -n kgateway-system 19000 & - PF_PID=$! - - sleep 2 - - curl -s http://localhost:19000/config_dump | \ - jq '.configs[] - | select(.["@type"] == "type.googleapis.com/envoy.admin.v3.ListenersConfigDump") - | .static_listeners[].listener.listener_filters?, - .dynamic_listeners[].active_state.listener.listener_filters?' - - kill $PF_PID - ``` - - Example output: - ``` - [ - { - "name": "envoy.filters.listener.proxy_protocol", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol", - "stat_prefix": "kgateway-system_proxy-protocol" - } - } - ] - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete listenerPolicy proxy-protocol -n {{< reuse "agw-docs/snippets/namespace.md" >}} -``` diff --git a/assets/docs/pages/traffic-management/redirect/host.md b/assets/docs/pages/traffic-management/redirect/host.md deleted file mode 100644 index ad4208cf5..000000000 --- a/assets/docs/pages/traffic-management/redirect/host.md +++ /dev/null @@ -1,70 +0,0 @@ -Redirect requests to a different host. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRequestRedirectFilter). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up host redirects - -1. Create an HTTPRoute for the httpbin app. In the following example, requests for the `host.redirect.example` domain are redirected to the `www.example.com` hostname, and a 302 HTTP response code is returned to the user. - ```yaml - kubectl apply -f- <}} - hostnames: - - host.redirect.example - rules: - - filters: - - type: RequestRedirect - requestRedirect: - hostname: "www.example.com" - statusCode: 302 - EOF - ``` - -4. Send a request to the httpbin app on the `host.redirect.example` domain and verify that you get back a 302 HTTP response code and the redirect location `www.example.com/headers`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: host.redirect.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: host.redirect.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 302 Found - HTTP/1.1 302 Found - < location: http://www.example.com/headers - location: http://www.example.com/headers - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-redirect -n httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/redirect/https.md b/assets/docs/pages/traffic-management/redirect/https.md deleted file mode 100644 index b5bbff658..000000000 --- a/assets/docs/pages/traffic-management/redirect/https.md +++ /dev/null @@ -1,220 +0,0 @@ -Redirect HTTP traffic to HTTPS. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRequestRedirectFilter). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up an HTTPS listener - -{{% reuse "agw-docs/snippets/listeners-https-create-cert.md" %}} - -5. Configure an HTTPS listener on the Gateway that you created earlier. Note that your Gateway now has two listeners, `http` and `https`. You reference these listeners later in this guide to configure the HTTP to HTTPS redirect. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - - name: https - port: 443 - protocol: HTTPS - tls: - mode: Terminate - certificateRefs: - - name: https - kind: Secret - allowedRoutes: - namespaces: - from: All - EOF - ``` - -## Redirect HTTP traffic to HTTPS - -1. Create an HTTPRoute for the httpbin app that sets up a `RequestRedirect` filter. By using the `https` scheme, you instruct the Gateway to redirect HTTP traffic to HTTPS and send back a 301 HTTP response code to the client. - ```yaml - kubectl apply -f- <}} - sectionName: http - hostnames: - - redirect.example - rules: - - filters: - - type: RequestRedirect - requestRedirect: - scheme: https - statusCode: 301 - EOF - ``` - - |Setting|Description| - |--|--| - |`spec.parentRefs.name`
`spec.parentRefs.namespace` |The name and namespace of the Gateway resource that serves the route. In this example, you use the Gateway that you set up earlier. | - |`spec.parentRefs.sectionName`|The Gateway listener to bind this route to. In this example, you want to apply the HTTPS redirect to all traffic that is sent to the HTTP listener on the Gateway. | - |`spec.hostnames`| The hostname for which you want to apply the redirect.| - |`spec.rules.filters.type`|The type of filter that you want to apply to incoming requests. In this example, the `RequestRedirect` is used.| - |`spec.rules.filters.requestRedirect.scheme`|The type of redirect that you want to apply. The `https` scheme redirects all incoming HTTP traffic to HTTPS. | - |`spec.rules.filters.requestRedirect.statusCode`|The HTTP status code that you want to return to the client in case of a redirect. For a permanent redirect, use the 301 HTTP status code. | - -2. Create another HTTPRoute for the httpbin app that routes incoming HTTPS traffic to the httpbin app. Note that you bind this HTTPRoute to the HTTPS listener on your gateway by using `sectionName: https`. - ```yaml - kubectl apply -f- <}} - sectionName: https - hostnames: - - redirect.example - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -3. Send an HTTP request to the httpbin app on the `redirect.example` domain. Verify that you get back a 301 HTTP response code and that your redirect location shows `https://redirect.example:8080/status/200`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: redirect.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik localhost:8080/status/200 -H "host: redirect.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 301 Moved Permanently - HTTP/1.1 301 Moved Permanently - < location: https://redirect.example:8080/status/200 - location: https://redirect.example:8080/status/200 - < date: Mon, 06 Nov 2024 01:48:12 GMT - date: Mon, 06 Nov 2024 01:48:12 GMT - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -4. Send an HTTPS request to the httpbin app on the `redirect.example` domain. Verify that you get back a 200 HTTP response code and that you can see a successful TLS handshake with the gateway. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik https://$INGRESS_GW_ADDRESS:443/status/200 -H "host: redirect.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - 1. Port-forward the gateway proxy on port 8443. - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:8443 - ``` - - 2. Send an HTTPS request to the httpbin app. - ```sh - curl -vik --connect-to redirect.example:443:localhost:8443 https://redirect.example/status/200 - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * ALPN: curl offers h2,http/1.1 - * (304) (OUT), TLS handshake, Client hello (1): - * (304) (IN), TLS handshake, Server hello (2): - * (304) (IN), TLS handshake, Unknown (8): - * (304) (IN), TLS handshake, Certificate (11): - * (304) (IN), TLS handshake, CERT verify (15): - * (304) (IN), TLS handshake, Finished (20): - * (304) (OUT), TLS handshake, Finished (20): - * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF - * ALPN: server did not agree on a protocol. Uses default. - * Server certificate: - * subject: CN=*; O=any domain - * start date: Mar 14 13:37:22 2025 GMT - * expire date: Mar 14 13:37:22 2026 GMT - * issuer: O=any domain; CN=* - * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. - * using HTTP/1.x - > GET /status/200 HTTP/1.1 - > Host: redirect.example - > User-Agent: curl/8.7.1 - > Accept: */* - > - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - ``` - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Remove the HTTPRoutes for the httpbin app and the Kubernetes secret that holds the TLS certificate and key. - ```sh - kubectl delete httproute,secret -A -l gateway=https - ``` - -2. Remove the example_certs directory that stores your TLS credentials. - ```sh - rm -rf example_certs - ``` - -3. Remove the HTTPS listener from your Gateway. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - - - diff --git a/assets/docs/pages/traffic-management/redirect/path.md b/assets/docs/pages/traffic-management/redirect/path.md deleted file mode 100644 index 761ed41d7..000000000 --- a/assets/docs/pages/traffic-management/redirect/path.md +++ /dev/null @@ -1,217 +0,0 @@ -Redirect requests to a different path prefix. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRequestRedirectFilter). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} -## Set up path redirects - -Path redirects use the HTTP path modifier to replace either an entire path or path prefixes. - -### Replace prefix path - -1. Create an HTTPRoute for the httpbin app. In the following example, requests to the `/get` path are redirected to the `/status/200` path, and a 302 HTTP response code is returned to the user. - - Because the `ReplacePrefixPath` path modifier is used, only the path prefix is replaced during the redirect. For example, requests to `http://path.redirect.example/get` result in the `https://path.redirect.example/status/200` redirect location. However, for longer paths, such as in `http://path.redirect.example/get/headers`, only the prefix is replaced and a redirect location of `https://path.redirect.example/status/200/headers` is returned. - - ```yaml - kubectl apply -f- <}} - hostnames: - - path.redirect.example - rules: - - matches: - - path: - type: PathPrefix - value: /get - filters: - - type: RequestRedirect - requestRedirect: - path: - type: ReplacePrefixMatch - replacePrefixMatch: /status/200 - statusCode: 302 - EOF - ``` - - |Setting|Description| - |--|--| - |`spec.parentRefs.name`
`spec.parentRefs.namespace`|The name and namespace of the Gateway resource that serves the route. In this example, you use the Gateway that you created earlier. | - |`spec.hostnames`| The hostname for which you want to apply the redirect.| - |`spec.rules.matches.path`|The prefix path that you want to redirect. In this example, you want to redirect all requests to the `/get` path. | - |`spec.rules.filters.type`|The type of filter that you want to apply to incoming requests. In this example, the `RequestRedirect` is used.| - |`spec.rules.filters.requestRedirect.path.type`|The type of path modifier that you want to apply. In this example, you want to replace only the prefix path. | - |`spec.rules.filters.requestRedirect.path.replacePrefixPath`|The prefix path you want to redirect to. In this example, all requests to the `/get` prefix path are redirected to the `/status/200` prefix path. | - |`spec.rules.filters.requestRedirect.statusCode`| The HTTP status code that you want to return to the client in case of a redirect. For non-permanent redirects, use the 302 HTTP response code. | - -2. Send a request to the httpbin app on the `path.redirect.example` domain. Verify that you get back a 302 HTTP response code and the `path.redirect.example:8080/status/200` redirect location. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/get -H "host: path.redirect.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/get -H "host: path.redirect.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 302 Found - HTTP/1.1 302 Found - < location: http://path.redirect.example:8080/status/200 - location: http://path.redirect.example:8080/status/200 - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -3. Send another request to the httpbin app on the `path.redirect.example` domain. This time, you send the request to the `/get/headers` path. Verify that you get back a 302 HTTP response code and the redirect location `path.redirect.example:8080/status/200/headers`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/get/headers -H "host: path.redirect.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/get/headers -H "host: path.redirect.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 302 Found - HTTP/1.1 302 Found - < location: http://path.redirect.example:8080/status/200/headers - location: http://path.redirect.example:8080/status/200/headers - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -### Replace full path - -1. Create an HTTPRoute for the httpbin app. In the following example, requests to the `/get` path are redirected to the `/status/200` path, and a 302 HTTP response code is returned to the user. - - Because the `ReplaceFullPath` path modifier is used, requests to `http://path.redirect.example/get` and `http://path.redirect.example/get/headers` both receive `https://path.redirect.example/status/200` as the redirect location. - - ```yaml - kubectl apply -f- <}} - hostnames: - - path.redirect.example - rules: - - matches: - - path: - type: PathPrefix - value: /get - filters: - - type: RequestRedirect - requestRedirect: - path: - type: ReplaceFullPath - replaceFullPath: /status/200 - statusCode: 302 - EOF - ``` - - |Setting|Description| - |--|--| - |`spec.parentRefs.name`
`spec.parentRefs.namespace` |The name and namespace of the Gateway resource that serves the route. In this example, you use the Gateway that you created earlier. | - |`spec.hostnames`| The hostname for which you want to apply the redirect.| - |`spec.rules.matches.path`|The prefix path that you want to redirect. In this example, you want to redirect all requests to the `/get` path. | - |`spec.rules.filters.type`|The type of filter that you want to apply to incoming requests. In this example, the `RequestRedirect` is used.| - |`spec.rules.filters.requestRedirect.path.type`|The type of path modifier that you want to apply. In this example, you want to replace the full path.. | - |`spec.rules.filters.requestRedirect.path.replaceFullPath`|The path that you want to redirect to. In this example, all requests to the `/get` prefix path are redirected to the `/status/200` prefix path. | - |`spec.rules.filters.requestRedirect.statusCode`| The HTTP status code that you want to return to the client in case of a redirect. For non-permanent redirects, use the 302 HTTP response code. | - -2. Send a request to the httpbin app on the `path.redirect.example` domain. Verify that you get back a 302 HTTP response code and the redirect location `path.redirect.example:8080/status/200`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/get -H "host: path.redirect.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/get -H "host: path.redirect.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 302 Found - HTTP/1.1 302 Found - < location: http://path.redirect.example:8080/status/200 - location: http://path.redirect.example:8080/status/200 - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -3. Send another request to the httpbin app on the `path.redirect.example` domain. This time, you send the request to the `/get/headers` path. Verify that you get back a 302 HTTP response code and the same redirect location as in the previous example (`path.redirect.example:8080/status/200`). - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/get/headers -H "host: path.redirect.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/get/headers -H "host: path.redirect.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - * Mark bundle as not supporting multiuse - < HTTP/1.1 302 Found - HTTP/1.1 302 Found - < location: http://path.redirect.example:8080/status/200 - location: http://path.redirect.example:8080/status/200 - < server: envoy - server: envoy - < content-length: 0 - content-length: 0 - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-redirect -n httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/rewrite/host.md b/assets/docs/pages/traffic-management/rewrite/host.md deleted file mode 100644 index 24f5c810d..000000000 --- a/assets/docs/pages/traffic-management/rewrite/host.md +++ /dev/null @@ -1,191 +0,0 @@ -Replace the host header value before forwarding a request to a backend service by using the `URLRewrite` filter. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPURLRewriteFilter). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## In-cluster service host rewrites - -1. Create an HTTPRoute resource for the httpbin app that uses the `URLRewrite` filter to rewrite the hostname of th request. In this example, all incoming requests on the `rewrite.example` domain are rewritten to the `www.example.com` host. - ```yaml - kubectl apply -f- <}} - hostnames: - - rewrite.example - rules: - - filters: - - type: URLRewrite - urlRewrite: - hostname: "www.example.com" - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - - |Setting|Description| - |--|--| - |`spec.parentRefs`| The name and namespace of the Gateway that serves this HTTPRoute. In this example, you use the `http` gateway that was created as part of the get started guide. | - |`spec.rules.filters.type`| The type of filter that you want to apply to incoming requests. In this example, the `URLRewrite` filter is used.| - |`spec.rules.filters.urlRewrite.hostname`| The hostname that you want to rewrite requests to. | - |`spec.rules.backendRefs`|The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide. | - -2. Send a request to the httpbin app on the `rewrite.example` domain. Verify that you get back a 200 HTTP response code and that you see the `Host: www.example.com` header in your response. - - {{< callout type="info" >}} - The following request returns a 200 HTTP response code, because you set up an HTTPRoute for the httpbin app on the `www.example.com` domain as part of the getting started guide. If you chose a different domain for your example, make sure that you have an HTTPRoute that can be reached under the host you want to rewrite to. - {{< /callout >}} - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: rewrite.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: rewrite.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[7,8]} - ... - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com" - ], - "User-Agent": [ - "curl/7.77.0" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "ffc55a3e-60ae-4c90-9a5c-62c8a1ba1076" - ] - } - } - ``` - -## External service host rewrites - -1. Create a Backend that represents your external service. The following example creates a Backend for the `httpbin.org` domain. - ```yaml - kubectl apply -f- <}} - hostnames: - - external-rewrite.example - rules: - - filters: - - type: URLRewrite - urlRewrite: - hostname: "httpbin.org" - backendRefs: - - name: httpbin - kind: Backend - group: gateway.kgateway.dev - EOF - ``` - -2. Send a request to the `external-rewrite.example` domain. Verify that you get back a 200 HTTP response code and that you see the `Host: httpbin.org` header in your response. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: external-rewrite.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: external-rewrite.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[2,3,21]} - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < content-type: application/json - content-type: application/json - < content-length: 268 - content-length: 268 - < server: envoy - server: envoy - < access-control-allow-origin: * - access-control-allow-origin: * - < access-control-allow-credentials: true - access-control-allow-credentials: true - < x-envoy-upstream-service-time: 2416 - x-envoy-upstream-service-time: 2416 - < - - { - "headers": { - "Accept": "*/*", - "Host": "httpbin.org", - "User-Agent": "curl/8.7.1", - "X-Amzn-Trace-Id": "Root=1-6859932a-1fb1dc706dadcc183b407d4d", - "X-Envoy-Expected-Rq-Timeout-Ms": "15000", - "X-Envoy-External-Address": "10.0.15.215" - } - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-rewrite -n httpbin -kubectl delete httproute backend-rewrite -kubectl delete backend httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/rewrite/path.md b/assets/docs/pages/traffic-management/rewrite/path.md deleted file mode 100644 index bc0853491..000000000 --- a/assets/docs/pages/traffic-management/rewrite/path.md +++ /dev/null @@ -1,428 +0,0 @@ -Rewrite path prefixes in requests by using the `URLRewrite` filter. - -For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} documentation](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPURLRewriteFilter). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Rewrite prefix path - -Use the [HTTPPathModifier](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPPathModifierType) to rewrite path prefixes. - -### In-custer services - -1. Create an HTTPRoute resource for the httpbin app that configures an `URLRewrite` filter to rewrite prefix paths. In this example, all incoming requests that match the `/headers` prefix path on the `rewrite.example` domain are rewritten to the `/anything` prefix path. - - Because the `ReplacePrefixPath` path modifier is used, only the path prefix is replaced during the rewrite. For example, requests to `http://rewrite.example/headers` are rewritten to `https://rewrite.example/anything`. However, for longer paths, such as in `http://rewrite.example/headers/200`, only the prefix is replaced and the path is rewritten to `http://rewrite.example/anything/200`. - - ```yaml - kubectl apply -f- <}} - hostnames: - - rewrite.example - rules: - - matches: - - path: - type: PathPrefix - value: /headers - filters: - - type: URLRewrite - urlRewrite: - path: - type: ReplacePrefixMatch - replacePrefixMatch: /anything - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - - |Setting|Description| - |--|--| - |`spec.parentRefs`| The name and namespace of the Gateway that serves this HTTPRoute. In this example, you use the `http` gateway that was created as part of the get started guide. | - |`spec.rules.filters.type`| The type of filter that you want to apply to incoming requests. In this example, the `URLRewrite` filter is used.| - |`spec.rules.filters.urlRewrite.path.type`| The type of HTTPPathModifier that you want to use. In this example, `ReplacePrefixMatch` is used, which replaces only the path prefix. | - | `spec.rules.filters.urlRewrite.path.replacePrefixMatch` | The path prefix you want to rewrite to. In this example, you replace the prefix path with the `/anything` prefix path. | - |`spec.rules.backendRefs`|The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide. | - -2. Send a request to the httpbin app along the `/headers` path on the `rewrite.example` domain. Verify that you get back a 200 HTTP response code and that your request is rewritten to the `/anything` path. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: rewrite.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: rewrite.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[3]} - ... - "origin": "10.0.9.36:50660", - "url": "http://rewrite.example:8080/anything", - "data": "", - "files": null, - "form": null, - "json": null - ... - ``` - -3. Send another request to the httpbin app. This time, you send it along the `/headers/200` path on the `rewrite.example` domain. Verify that you get back a 200 HTTP response code and that your request path is rewritten to `/anything/200`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers/200 -H "host: rewrite.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers/200 -H "host: rewrite.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[3]} - ... - "origin": "10.0.9.36:50660", - "url": "http://rewrite.example:8080/anything/200", - "data": "", - "files": null, - "form": null, - "json": null - ... - ``` - -### External services - -1. Create a Backend that represents your external service. The following example creates a Backend for the `httpbin.org` domain. - ```yaml - kubectl apply -f- <}} - hostnames: - - external-rewrite.example - rules: - - matches: - - path: - type: PathPrefix - value: /headers - filters: - - type: URLRewrite - urlRewrite: - hostname: "httpbin.org" - path: - type: ReplacePrefixMatch - replacePrefixMatch: /anything - backendRefs: - - name: httpbin - kind: Backend - group: gateway.kgateway.dev - EOF - ``` - -2. Send a request to the `external-rewrite.example` domain on the `/headers` path. Verify that you get back a 200 HTTP response code and that the request was rewritten to `httpbin.org/anything`. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: external-rewrite.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: external-rewrite.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[2,3,25,34]} - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < content-type: application/json - content-type: application/json - < content-length: 268 - content-length: 268 - < server: envoy - server: envoy - < access-control-allow-origin: * - access-control-allow-origin: * - < access-control-allow-credentials: true - access-control-allow-credentials: true - < x-envoy-upstream-service-time: 2416 - x-envoy-upstream-service-time: 2416 - < - - { - "args": {}, - "data": "", - "files": {}, - "form": {}, - "headers": { - "Accept": "*/*", - "Host": "httpbin.org", - "User-Agent": "curl/8.7.1", - "X-Amzn-Trace-Id": "Root=1-68599cdc-5d3c0d9a1ac2aa482effb24b", - "X-Envoy-Expected-Rq-Timeout-Ms": "15000", - "X-Envoy-External-Address": "10.0.15.215", - "X-Envoy-Original-Path": "/" - }, - "json": null, - "method": "GET", - "url": "http://httpbin.org/anything" - } - ``` - - -## Rewrite full path - -Use the [HTTPPathModifier](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPPathModifierType) to rewrite full paths. - -### In-cluster services - -1. Create an HTTPRoute resource for the httpbin app that configures an `URLRewrite` filter to rewrite prefix paths. In this example, all incoming requests that match the `/headers` prefix path on the `rewrite.example` domain are rewritten to `/anything`. - - Because the `ReplaceFullPath` path modifier is used, requests to `http://rewrite.example/headers` and `http://rewrite.example/headers/200` both are rewritten to `https://rewrite.example/anything`. - - ```yaml - kubectl apply -f- <}} - hostnames: - - rewrite.example - rules: - - matches: - - path: - type: PathPrefix - value: /headers - filters: - - type: URLRewrite - urlRewrite: - path: - type: ReplaceFullPath - replaceFullPath: /anything - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - - |Setting|Description| - |--|--| - |`spec.parentRefs`| The name and namespace of the Gateway that serves this HTTPRoute. In this example, you use the `http` gateway that was created as part of the get started guide. | - |`spec.rules.filters.type`| The type of filter that you want to apply to incoming requests. In this example, the `URLRewrite` filter is used.| - |`spec.rules.filters.urlRewrite.path.type`| The type of HTTPPathModifier that you want to use. In this example, `ReplaceFullPath` is used, which replaces the full path prefix. | - | `spec.rules.filters.urlRewrite.path.replaceFullPath` | The path prefix you want to rewrite to. In this example, you replace the full prefix path with the `/anything` prefix path. | - |`spec.rules.backendRefs`|The backend destination you want to forward traffic to. In this example, all traffic is forwarded to the httpbin app that you set up as part of the get started guide. | - -3. Send a request to the httpbin app along the `/headers` path on the `rewrite.example` domain. Verify that you get back a 200 HTTP response code and that your request is rewritten to the `/anything` path. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2">}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: rewrite.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers -H "host: rewrite.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[3]} - ... - "origin": "10.0.9.36:50660", - "url": "http://rewrite.example:8080/anything", - "data": "", - "files": null, - "form": null, - "json": null - ... - ``` - -4. Send another request to the httpbin app. This time, you send it along the `/headers/200` path on the `rewrite.example` domain. Verify that you also get back a 200 HTTP response code and that the full path is rewritten to the `/anything` path. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/headers/200 -H "host: rewrite.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/headers/200 -H "host: rewrite.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[3]} - ... - "origin": "10.0.9.36:50660", - "url": "http://rewrite.example:8080/anything", - "data": "", - "files": null, - "form": null, - "json": null - ... - ``` - -### External services - -1. Create a Backend that represents your external service. The following example creates a Backend for the `httpbin.org` domain. - ```yaml - kubectl apply -f- <}} - hostnames: - - external-rewrite.example - rules: - - filters: - - type: URLRewrite - urlRewrite: - hostname: "httpbin.org" - path: - type: ReplaceFullPath - replaceFullPath: /anything - backendRefs: - - name: httpbin - kind: Backend - group: gateway.kgateway.dev - EOF - ``` - -2. Send a request to the `external-rewrite.example` domain on the `/header` path. Verify that you get back a 200 HTTP response code and that the request was rewritten to `httpbin.org/anything`. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/header -H "host: external-rewrite.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/header -H "host: external-rewrite.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[2,3,25,34]} - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < content-type: application/json - content-type: application/json - < content-length: 268 - content-length: 268 - < server: envoy - server: envoy - < access-control-allow-origin: * - access-control-allow-origin: * - < access-control-allow-credentials: true - access-control-allow-credentials: true - < x-envoy-upstream-service-time: 2416 - x-envoy-upstream-service-time: 2416 - < - - { - "args": {}, - "data": "", - "files": {}, - "form": {}, - "headers": { - "Accept": "*/*", - "Host": "httpbin.org", - "User-Agent": "curl/8.7.1", - "X-Amzn-Trace-Id": "Root=1-68599cdc-5d3c0d9a1ac2aa482effb24b", - "X-Envoy-Expected-Rq-Timeout-Ms": "15000", - "X-Envoy-External-Address": "10.0.15.215", - "X-Envoy-Original-Path": "/" - }, - "json": null, - "method": "GET", - "url": "http://httpbin.org/anything" - } - ``` - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute httpbin-rewrite -n httpbin -``` - - - diff --git a/assets/docs/pages/traffic-management/route-delegation/basic.md b/assets/docs/pages/traffic-management/route-delegation/basic.md deleted file mode 100644 index 1c10fcac5..000000000 --- a/assets/docs/pages/traffic-management/route-delegation/basic.md +++ /dev/null @@ -1,225 +0,0 @@ -Set up basic route delegation between a parent and two child HTTPRoute resources. - -## Configuration overview - -In this guide you walk through a basic route delegation example that demonstrates route delegation between a parent HTTPRoute resource and two child HTTPRoute resources that forward traffic to an httpbin sample app. The following image illustrates the resulting route delegation hierarchy: - -{{< reuse-image src="img/route-delegation-basic.svg" >}} -{{< reuse-image-dark srcDark="img/route-delegation-basic-dark.svg" >}} - -**`parent` HTTPRoute**: -* The parent HTTPRoute resource delegates traffic as follows: - * `/anything/team1` delegates traffic to the child HTTPRoute resource `child-team1` in namespace `team1`. - * `/anything/team2` delegates traffic to the child HTTPRoute resource `child-team2` in namespace `team2`. - -**`child-team1` HTTPRoute**: -* The child HTTPRoute resource `child-team1` matches incoming traffic for the `/anything/team1/foo` prefix path and routes that traffic to the httpbin app in namespace `team1`. - -**`child-team2` HTTPRoute**: -* The child HTTPRoute resource `child-team2` matches incoming traffic for the `/anything/team2/bar` exact prefix path and routes that traffic to the httpbin app in namespace `team2`. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-delegation.md" >}} - -## Setup - -1. Create the parent HTTPRoute resource that matches incoming traffic on the `delegation.example` domain. The HTTPRoute resource specifies two routes: - * `/anything/team1`: The routing decision is delegated to a child HTTPRoute resource in the `team1` namespace. - * `/anything/team2`: The routing decision is delegated to a child HTTPRoute resource in the `team2` namespace. - ```yaml - kubectl apply -f- <}} - spec: - hostnames: - - delegation.example - parentRefs: - - name: http - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team1 - - matches: - - path: - type: PathPrefix - value: /anything/team2 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team2 - EOF - ``` - -2. Create the child HTTPRoute resource for the `team1` namespace that matches traffic on the `/anything/team1/foo` prefix and routes traffic to the httpbin app in the `team1` namespace. The child HTTPRoute resource does not select a specific parent HTTPRoute resource. Because of that, the child HTTPRoute resource is automatically selected by all parent HTTPRoute resources that delegate traffic to this child. - ```yaml - kubectl apply -f- <}} - group: gateway.networking.k8s.io - kind: HTTPRoute - rules: - - matches: - - path: - type: Exact - value: /anything/team2/bar - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -4. Inspect the parent and child HTTPRoute resources. - ```sh - kubectl get httproute child-team1 -n team1 - kubectl get httproute child-team2 -n team2 - kubectl get httproute parent -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -5. Send a request to the `delegation.example` domain along the `/anything/team1/foo` path. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo -H "host: delegation.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -6. Send another request to the `delegation.example` domain along the `/anything/team1/bar` path. Verify that you get back a 404 HTTP response code, because this route is not specified in the child HTTPRoute resource `child-team1`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/anything/team1/bar -H "host: delegation.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/anything/team1/bar -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 404 Not Found - date: Mon, 06 May 2024 16:01:48 GMT - server: envoy - transfer-encoding: chunked - ``` - -7. Send another request to the `delegation.example` domain. This time, you use the `/anything/team2/bar` path that is configured on the `child-team2` HTTPRoute resource. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar -H "host: delegation.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/bar -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -8. Send another request along the `/anything/team2/bar/test` path. Because the `child-team2` HTTPRoute resource matches traffic only on the `anything/team2/bar` exact path, this request fails and a 404 HTTP response code is returned. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar/test -H "host: delegation.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/bar/test -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 404 Not Found - date: Mon, 06 May 2024 16:01:48 GMT - server: envoy - transfer-encoding: chunked - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute parent -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute child-team1 -n team1 -kubectl delete httproute child-team2 -n team2 -kubectl delete -n team1 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete namespaces team1 team2 -``` - diff --git a/assets/docs/pages/traffic-management/route-delegation/header-query.md b/assets/docs/pages/traffic-management/route-delegation/header-query.md deleted file mode 100644 index 25f5a06f9..000000000 --- a/assets/docs/pages/traffic-management/route-delegation/header-query.md +++ /dev/null @@ -1,353 +0,0 @@ -Use header and query matchers in a route delegation setup. - -## Configuration overview - -In this guide you walk through a route delegation example where headers and query parameters are added as matchers to the parent and child HTTPRoute resources. A routing hierarchy can be created only if the child defines the same header and query matchers that the parent HTTPResource defines. You can optionally define additional header or query matchers on the child HTTPRoute resource. - -For example, if the parent HTTPRoute resource specifies the `header` header, the child must specify the same header matcher. - -The following image illustrates the route delegation hierarchy: - -{{< reuse-image src="img/route-delegation-header-query.svg" width="800" >}} -{{< reuse-image-dark srcDark="img/route-delegation-header-query-dark.svg" width="800" >}} - -**`parent` HTTPRoute**: -* The parent HTTPRoute resource delegates traffic as follows: - * `/anything/team1` delegates traffic to the child HTTPRoute resource `child-team1` in namespace `team1` for requests that include the `header1; val1` request header and the `query1=val1` query parameter. - * `/anything/team2` delegates traffic to the child HTTPRoute resource `child-team2` in namespace `team2` for requests that include the `header2: val2` request header and the `query2=val2` query parameter. - -**`child-team1` HTTPRoute**: -* The child HTTPRoute resource `child-team1` matches incoming traffic for the `/anything/team1/foo` prefix path if the `header1: val1` and `headerX: valX` request headers and `query1=val1` and `queryX=valX` query parameters are present in the request. Requests that match these conditions are forwarded to the httpbin app in namespace `team1`. Note that the headers and query parameters are a superset of the headers and query parameters that the parent HTTPRoute resource defines. - -**`child-team2` HTTPRoute**: -* The child HTTPRoute resource `child-team2` matches incoming traffic for the `/anything/team2/bar` exact prefix path if the `headerX: valX` request header and `queryX=valX` query parameter are present in the request. Because the child HTTPRoute resource does not specify the same header and query parameters that the parent HTTPRoute specified, the route is considered invalid. -* You later apply a different version of the `child-team2` HTTPRoute that specifies the `delegation.kgateway.dev/inherit-parent-matcher: "true"` annotation. This annotation allows the HTTPRoute to inherit the matchers, headers, and query parameters from the parent. Because of that, the route is considered valid and traffic can be routed to the httpbin app in the team2 namespace. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-delegation.md" >}} - -## Setup - -1. Create the parent HTTPRoute resource that matches incoming traffic on the `delegation.example` domain. The HTTPRoute resource specifies two routes: - * Route 1 matches on the following conditions. If these conditions are met, the routing decision is delegated to a child HTTPRoute resource in the `team1` namespace. - * path prefix match on `/anything/team1` - * exact header match on `header1=val1` - * exact query parameter match on `query1=val1` - * Route 2 matches on the following conditions. If these conditions are met, the routing decision is delegated to a child HTTPRoute resource in the `team2` namespace. - * path prefix match on `/anything/team2` - * exact header match on `header2=val2` - * exact query parameter match on `query2=val2` - ```yaml - kubectl apply -f- <}} - spec: - hostnames: - - delegation.example - parentRefs: - - name: http - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - headers: - - type: Exact - name: header1 - value: val1 - queryParams: - - type: Exact - name: query1 - value: val1 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team1 - - matches: - - path: - type: PathPrefix - value: /anything/team2 - headers: - - type: Exact - name: header2 - value: val2 - queryParams: - - type: Exact - name: query2 - value: val2 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team2 - EOF - ``` - -2. Create the `child-team1` HTTPRoute resource in the `team1` namespace that matches traffic on the `/anything/team1/foo` path prefix if the `header1=val1` and `headerX=valX` request headers and the `query1=val1` and `queryX=valX` query parameters are present in the request. Requests that meet these conditions are forwarded to the httpbin app in the `team1` namespace. - ```yaml - kubectl apply -f- <}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i "http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo?query1=val1" \ - -H "host: delegation.example" -H "header1: val1" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i "localhost:8080/anything/team1/foo?query1=val1" \ - -H "host: delegation.example" -H "header1: val1" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 404 Not Found - date: Mon, 06 May 2024 16:01:48 GMT - server: envoy - transfer-encoding: chunked - ``` - -5. Send another request to the `delegation.example` domain along the `/anything/team1/foo` path. This time, you include all of the header and query parameters that the parent and child HTTPRoute resources defined. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i "http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo?query1=val1&queryX=valX" \ - -H "host: delegation.example" -H "header1: val1" -H "headerX: valX" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i "localhost:8080/anything/team1/foo?query1=val1&queryX=valX" \ - -H "host: delegation.example" -H "header1: val1" -H "headerX: valX" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -6. Send another request to the `delegation.example` domain along the `/anything/team2/bar` path that is configured on the `child-team2` HTTPRoute resource and include all of the header and query parameters that are defined on the parent and child HTTPRoute resources. Verify that you get back a 500 HTTP response code. Because the `child-team2` HTTPRoute resource does not specify the same header and query matchers as the parent HTTPRoute resource, the routing configuration is considered invalid. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i "http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar?queryX=valX&query2=val2" \ - -H "host: delegation.example" -H "headerX: valX" -H "header2: val2" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i "localhost:8080/anything/team2/bar?queryX=valX&query2=val2" \ - -H "host: delegation.example" -H "headerX: valX" -H "header2: val2" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 500 Internal Server Error - content-length: 73 - content-type: text/plain - date: Mon, 06 May 2024 16:01:48 GMT - server: envoy - - invalid route configuration detected and replaced with a direct response.% - ``` - -## Inherit parent attributes - -Instead of requiring the child HTTPRoutes to define the same matchers, headers, and query parameters as the parent HTTPRoute, you can use the `delegation.kgateway.dev/inherit-parent-matcher: "true"` annotation on the child HTTPRoute to inherit these attributes from the parent. This setting is useful if you want to use paths that are relative to the parent path, or augment the headers and query parameters that are set on the parent. - -1. Update the `child-team2` HTTPRoute to include the `delegation.kgateway.dev/inherit-parent-matcher: "true"` annotation. This annotation allows the `child-team2` HTTPRoute to inherit the matchers, headers, and query parameters that are defined on the parent. - - The following configuration specifies the `/` prefix path and therefore allows all paths that are relative to the parent's `/anything/team2` prefix matcher. In addition, you augment the header and query parameters from the parent with custom header and query parameters. Note that when you sent requests to the `child-team2` HTTPRoute earlier, these requests failed, because the HTTPRoute did not define the same header and query parameters as the `parent` in addition to the custom values. - ```yaml - kubectl apply -f- <}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i "http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar?queryX=valX&query2=val2" \ - -H "host: delegation.example" -H "headerX: valX" -H "header2: val2" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i "localhost:8080/anything/team2/bar?queryX=valX&query2=val2" \ - -H "host: delegation.example:8080" -H "headerX: valX" -H "header2: val2" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - content-length: 681 - x-envoy-upstream-service-time: 0 - server: envoy - - { - "args": { - "query2": [ - "val2" - ], - "queryX": [ - "valX" - ] - }, - "headers": { - "Accept": [ - "*/*" - ], - "Header2": [ - "val2" - ], - "Headerx": [ - "valX" - ], - "Host": [ - "delegation.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "30dfc350-d546-4f53-857d-cb3edab68ebd" - ] - }, - "origin": "10.0.64.27:50590", - "url": "http://delegation.example:8080/anything/team2/bar?queryX=valX&query2=val2", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute parent -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute child-team1 -n team1 -kubectl delete httproute child-team2 -n team2 -kubectl delete -n team1 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete namespaces team1 team2 -``` - diff --git a/assets/docs/pages/traffic-management/route-delegation/inheritance/kgateway-policies.md b/assets/docs/pages/traffic-management/route-delegation/inheritance/kgateway-policies.md deleted file mode 100644 index 03104e220..000000000 --- a/assets/docs/pages/traffic-management/route-delegation/inheritance/kgateway-policies.md +++ /dev/null @@ -1,362 +0,0 @@ -Learn how policy inheritance and overrides work for kgateway-native policies in a route delegation setup. - -{{< callout type="info" >}} -Want to learn more about policy inheritance and overrides for Kubernetes Gateway API-native policies? See [Native Gateway API policies](../native-policies/). -{{< /callout >}} - -## About policy inheritance - -{{< reuse "agw-docs/snippets/policy-inheritance.md" >}} - -## Configuration overview - -In this guide you walk through a route delegation example where a child HTTPRoute inherits or overrides policies that are set on a parent HTTPRoute. - -The following image illustrates the route delegation hierarchy and policy inheritance: - -{{< reuse-image src="img/route-delegation-inheritance-kgateway.svg" >}} -{{< reuse-image-dark srcDark="img/route-delegation-inheritance-kgateway-dark.svg" >}} - - -**Parent HTTPRoutes**: - -| HTTPRoute | Delegation | Policy merge strategy | -| --- | --- | --- | -| `parent1` | Delegates to the `child-team1` HTTPRoute in `team1` namespace on the `/anything/team1` prefix path for the `delegation-parent1.example` domain. | `ShallowMergePreferParent`, so that policies of the parent HTTPRoute override the policies of the child HTTPRoute. | -| `parent2` | Delegates to the `child-team1` HTTPRoute in `team1` namespace on the `/anything/team1` prefix path for the `delegation-parent2.example` domain. | `ShallowMergePreferChild`, (the default behavior) so that policies of the child HTTPRoute override the policies of the parent HTTPRoute. | - -**Child HTTPRoute**: - -| HTTPRoute | Delegation | Policy merge strategy | -| --- | --- | --- | -| `child-team1` | Matches incoming traffic for the `/anything/team1/foo` prefix path and routes that traffic to the httpbin app in the `team1` namespace. | Policies are merged depending on the parent HTTPRoute's policy merge strategy for the delegated route. | - -**TrafficPolicies**: - -| TrafficPolicy | TargetRefs | Description | -| --- | --- | --- | -| Transformation Policy 1 | `parent1` and `parent2` HTTPRoutes | Policy 1 is inherited for the `delegation-parent1.example` domain, but overridden by the child policy for the `delegation-parent2.example` domains. | -| Local rate limit Policy 2 | `parent1` and `parent2` HTTPRoutes | Policy 2 is inherited by both delegated routes because the child does not override the parent policy. | -| Transformation Policy 3 | `child-team1` HTTPRoute | Policy 3 does not apply to the `delegation-parent1.example` domain because that route's annotation overrides the default child inheritance with the `ShallowMergePreferParent` annotation. However, Policy 3 applies to the `delegation-parent2.example` domain because the child policy merge strategy is the default `ShallowMergePreferChild`. | - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-delegation.md" >}} - -## Setup - -1. Create the `parent1` HTTPRoute resource that matches incoming traffic on the `delegation-parent1.example` domain. The HTTPRoute resource specifies the following route: - * `/anything/team1`: The routing decision is delegated to a child HTTPRoute resource in the `team1` namespace. - * `kgateway.dev/inherited-policy-priority: ShallowMergePreferParent`: Overrides the default policy inheritance behavior so that parent policies take precedence over child policies. - - ```yaml - kubectl apply -f- <}} - annotations: - kgateway.dev/inherited-policy-priority: ShallowMergePreferParent - spec: - parentRefs: - - name: http - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - hostnames: - - "delegation-parent1.example" - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team1 - EOF - ``` - -2. Create the `parent2` HTTPRoute resource that matches incoming traffic on the `delegation-parent2.example` domain. - * `anything/team1`: The routing decision is delegated to the same child HTTPRoute resource in the `team1` namespace. - * `kgateway.dev/inherited-policy-priority: ShallowMergePreferChild`: Keeps the default behavior, so that policies of the child HTTPRoute override the policies of the parent HTTPRoute. - - ```yaml - kubectl apply -f- <}} - annotations: - delegation.kgateway.dev/inherited-policy-priority: PreferChild - spec: - parentRefs: - - name: http - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - hostnames: - - "delegation-parent2.example" - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team1 - EOF - ``` - -3. Create a TrafficPolicy that defines the following policies: - * **Transformation policy**: The `x-parent-policy: This policy is inherited from the parent.` header is set on any request. - * **Local rate limiting**: Requests to the routes are limited to 1 request per minute. - - The TrafficPolicy is applied to the `parent1` and `parent2` HTTPRoutes by using the `targetRefs` option. - ```yaml - kubectl apply -f- <}} - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: parent1 - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: parent2 - transformation: - request: - set: - - name: x-parent-policy - value: This policy is inherited from the parent. - rateLimit: - local: - tokenBucket: - maxTokens: 1 - tokensPerFill: 1 - fillInterval: 60s - EOF - ``` - -4. Create the child HTTPRoute resource for the `team1` namespace that matches traffic on the `/anything/team1/foo` prefix and routes traffic to the httpbin app in the `team1` namespace. - ```yaml - kubectl apply -f- <}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \ - -H "host: delegation-parent1.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo \ - -H "host: delegation-parent1.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[20,21]} - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - ... - - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "delegation-parent1.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - ... - "X-Parent-Policy": [ - "This policy is inherited from the parent." - ], - "X-Request-Id": [ - "db2affa4-2d03-4ee7-8624-75c3f9b40889" - ] - }, - "origin": "10.X.XX.XXX", - "url": "http://delegation-parent1.example:8080/anything/team1/foo", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -7. Send another request to the `delegation.parent1.example` domain. Verify that this time the request is rate limited and a 429 HTTP response is returned, because only 1 request is allowed in a 60 second timeframe. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \ - -H "host: delegation-parent1.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo \ - -H "host: delegation-parent1.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console - HTTP/1.1 429 Too Many Requests - content-length: 18 - content-type: text/plain - date: Fri, 06 Jun 2025 15:43:43 GMT - server: envoy - - local_rate_limited% - ``` - -8. Send a request to the `delegation.parent2.example` domain. Because the `parent2` HTTPRoute annotation keeps the default policy merging behavior, the child HTTPRoute overrides any top-level policies that are defined on `parent2`. Policies that are not overridden are still inherited from the parent and applied to the child HTTPRoute. - - Verify that you see the custom `X-Child-Team1` header in your response. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \ - -H "host: delegation-parent2.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo \ - -H "host: delegation-parent2.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[18,19]} - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - ... - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "delegation-parent2.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Child-Team1": [ - "This is the child-team1 policy." - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - ... - "origin": "10.X.X.XXX", - "url": "http://delegation-parent2.example:8080/anything/team1/foo", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -9. Send another request to the `delegation.parent2.example` domain. Because the child HTTPRoute does not define any rate limiting policies, it inherits the rate limiting policy of `parent2`. Verify that the request is rate limited and a 429 HTTP response is returned, because only 1 request is allowed in a 60 second timeframe. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \ - -H "host: delegation-parent2.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo \ - -H "host: delegation-parent2.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console - HTTP/1.1 429 Too Many Requests - content-length: 18 - content-type: text/plain - date: Fri, 06 Jun 2025 15:43:43 GMT - server: envoy - - local_rate_limited% - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute parent1 -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute parent2 -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute child-team1 -n team1 -kubectl delete trafficpolicy parent-policy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete trafficpolicy child-policy -n team1 -kubectl delete -n team1 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete namespaces team1 team2 -``` - diff --git a/assets/docs/pages/traffic-management/route-delegation/inheritance/native-policies.md b/assets/docs/pages/traffic-management/route-delegation/inheritance/native-policies.md deleted file mode 100644 index c8638dd7e..000000000 --- a/assets/docs/pages/traffic-management/route-delegation/inheritance/native-policies.md +++ /dev/null @@ -1,256 +0,0 @@ -Learn how policy inheritance and overrides work for Kubernetes Gateway API-native policies in a route delegation setup. - -{{< callout type="info" >}} -Want to learn more about policy inheritance and overrides for {{< reuse "/agw-docs/snippets/kgateway.md" >}} policies? See [{{< reuse "/agw-docs/snippets/kgateway.md" >}} policies](../kgateway-policies/). -{{< /callout >}} - -## About policy inheritance - -{{< reuse "agw-docs/snippets/policy-inheritance-native.md" >}} - -## Configuration overview - -In this guide you walk through a route delegation example where a child HTTPRoute inherits or overrides policies that are set on a parent HTTPRoute. - -The following image illustrates the route delegation hierarchy and policy inheritance: - -{{< reuse-image src="img/route-delegation-inheritance-native.svg" width="700px" >}} -{{< reuse-image-dark srcDark="img/route-delegation-inheritance-native-dark.svg" width="700px" >}} - - -**`parent` HTTPRoute**: -* The `parent` HTTPRoute resource delegates traffic as follows: - * Requests to`/anything/team1` are delegated to the child HTTPRoute resource `child-team1` in namespace `team1`. A timeout policy of 10s is defined on this route. - * Requests to `/anything/team2` are delegated to the child HTTPRoute resource `child-team2` in namespace `team2`. A timeout policy of 20s is defined on this route. - -**`child-team1` HTTPRoute**: -* The child HTTPRoute resource `child-team1` matches incoming traffic for the `/anything/team1/foo` prefix path and routes that traffic to the httpbin app in the `team1` namespace. -* The `child-team1` resource does not define any custom timeout policies. Because of that, the timeout policy that is set on the parent is automatically inherited and enforced. - -**`child-team2` HTTPRoute**: -* The child HTTPRoute resource `child-team2` delegates traffic on the `/anything/team2/bar` path to a grandchild HTTPRoute resource in the `team2` namespace. -* The `child-team2` resource defines a custom timeout policy. Because of that, the timeout policy on the parent is ignored and only the timeout policy on the `child-team2` resource is enforced. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-delegation.md" >}} - -## Setup - -1. Create the parent HTTPRoute resource that matches incoming traffic on the `delegation.example` domain. The HTTPRoute resource specifies two routes and defines a timeout policy for each of the routes: - * `/anything/team1`: The routing decision is delegated to a `child-team1` HTTPRoute resource in the `team1` namespace. A timeout policy of 10s is defined on this route. - * `/anything/team2`: The routing decision is delegated to a `child-team2` HTTPRoute resource in the `team2` namespace. A timeout policy of 20s is defined on this route. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: http - hostnames: - - "delegation.example" - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team1 - timeouts: - request: 10s - - matches: - - path: - type: PathPrefix - value: /anything/team2 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team2 - timeouts: - request: 20s - EOF - ``` - -2. Create the `child-team1` HTTPRoute resource in the `team1` namespace that matches traffic on the `/anything/team1/foo` prefix and routes traffic to the httpbin app in the `team1` namespace. The child HTTPRoute resource does not define any timeout policies. Because of that, the HTTPRoute inherits the timeout setting of the `parent`. - ```yaml - kubectl apply -f- <}} - group: gateway.networking.k8s.io - kind: HTTPRoute - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team2/bar - backendRefs: - - name: httpbin - port: 8000 - timeouts: - request: 30s - EOF - ``` - -4. Send a request to the `delegation.example` domain along the `/anything/team1/foo` path. Verify that you get back a 200 HTTP response code and that the `X-Envoy-Expected-Rq-Timeout-Ms` header is set to 10000 milliseconds (10s) as defined on the `parent` HTTPRoute. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[21,22]} - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - content-length: 509 - x-envoy-upstream-service-time: 0 - server: envoy - - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "delegation.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "10000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "65927858-2c6b-42ae-9278-8ff9d8bba3f8" - ] - }, - "origin": "10.0.64.27:49526", - "url": "http://delegation.example:8080/anything/team1/foo", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -5. Send a request to the `delegation.example` domain along the `/anything/team2/bar` path. Verify that you get back a 200 HTTP response code and that the `X-Envoy-Expected-Rq-Timeout-Ms` header is set to 30000 milliseconds (30s) as defined on the `child-team2` HTTPRoute. The timeout setting of 20s that was defined on the `parent` was not applied and overridden by the timeout setting of 30s on the `child-team2` HTTPRoute. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/bar \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[21,22]} - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - content-length: 509 - x-envoy-upstream-service-time: 1 - server: envoy - - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "delegation.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "30000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "d645dc37-5326-4b69-8c2c-4060e12ca4ff" - ] - }, - "origin": "10.0.64.27:53026", - "url": "http://delegation.example:8080/anything/team2/bar", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute parent -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute child-team1 -n team1 -kubectl delete httproute child-team2 -n team2 -kubectl delete -n team1 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete namespaces team1 team2 -``` - diff --git a/assets/docs/pages/traffic-management/route-delegation/label.md b/assets/docs/pages/traffic-management/route-delegation/label.md deleted file mode 100644 index d6ca83211..000000000 --- a/assets/docs/pages/traffic-management/route-delegation/label.md +++ /dev/null @@ -1,450 +0,0 @@ -In this example, you learn how to use labels to delegate traffic. The parent HTTPRoute defines the labels that must be present on the child HTTPRoute to allow traffic to be forwarded. - -You typically configure the parent to find an HTTPRoute with a specific label in a specific namespace. However, you can also use a wildcard for the namespace when you have multiple HTTPRoutes in different namespaces that can all receive delegated traffic. This configuration can significantly simplify your route delegation setup, as it allows you to quickly add new child HTTPRoutes to the delegation chain without changing the parent HTTPRoute configuration. - -{{< tabs items="Specific namespace,Wildcard namespace" tabTotal="2" >}} -{{% tab tabName="Specific namespace" %}} - -Explore an example for delegating traffic to an HTTPRoute with a specific label in a specific namespace. To try out this example, see the [Before you begin](#before-you-begin) section and then continue with [HTTPRoutes in specific namespaces](#specific-namespace). - -{{< reuse-image src="img/route-delegation-labels.svg" >}} -{{< reuse-image-dark srcDark="img/route-delegation-labels-dark.svg" >}} - -`parent` HTTPRoute:
-* The parent HTTPRoute resource delegates traffic as follows: - * Requests to `/anything/team1` are delegated to the child HTTPRoute resource `child-team1` in namespace `team1` with the `delegation.kgateway.dev/label: team1` label. - * Requests to `/anything/team2` are delegated to the child HTTPRoute resource `child-team2` in namespace `team2` with the `delegation.kgateway.dev/label: team2` label. - -`child-team1` HTTPRoute:
- -* The child HTTPRoute resource `child-team1` matches incoming traffic for the `/anything/team1/foo` prefix path and routes that traffic to the httpbin app in the `team1` namespace. - -`child-team2` HTTPRoute: - -* The child HTTPRoute resource `child-team2` matches incoming traffic for the `/anything/team1/bar` prefix path and routes that traffic to the httpbin app in the `team2` namespace. - -{{% /tab %}} -{{% tab tabName="Wildcard namespace" %}} - -Learn how to use a wildcard for the namespace to streamline your route delegation setup. To try out this example, see the [Before you begin](#before-you-begin) section and then continue with [Use wildcard namespaces](#wildcard). - -{{< reuse-image src="img/route-delegation-labels-wildcard.svg" >}} -{{< reuse-image-dark srcDark="img/route-delegation-labels-wildcard-dark.svg" >}} - -`parent` HTTPRoute:
-* The parent HTTPRoute resource delegates traffic as follows: - * Requests to `/` are delegated to all child HTTPRoute resources with the `delegation.kgateway.dev/label: wildcard` label. The `/` matcher is used so that the child HTTPRoutes can define any path prefix that they want to match traffic on. - -`child-team1` HTTPRoute:
- -* The child HTTPRoute resource `child-team1` matches incoming traffic for the `/anything/team1/foo` prefix path and routes that traffic to the httpbin app in the `team1` namespace. The HTTPRoute is configured with the `delegation.kgateway.dev/label: wildcard` label so that it can receive delegated traffic from the `parent`. - -`child-team2` HTTPRoute: - -* The child HTTPRoute resource `child-team2` matches incoming traffic for the `/anything/team1/bar` prefix path and routes that traffic to the httpbin app in the `team2` namespace. The HTTPRoute is configured with the `delegation.kgateway.dev/label: wildcard` label so that it can receive delegated traffic from the `parent`. -{{% /tab %}} - -{{< /tabs >}} - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-delegation.md" >}} - -## HTTPRoutes in specific namespaces {#specific-namespace} - -1. Create the parent HTTPRoute resource that matches incoming traffic on the `delegation.example` domain. The HTTPRoute resource specifies two routes: - * Route 1 matches traffic on the path prefix `/anything/team1` and delegates traffic to the HTTPRoute with the `delegation.kgateway.dev/label: team1` label. - * Route 2 matches traffic on the path prefix `/anything/team2` and delegates traffic to the HTTPRoute with the `delegation.kgateway.dev/label: team2` label. - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: http - hostnames: - - delegation.example - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - backendRefs: - # Delegate to routes with the label delegation.kgateway.dev/label:team1 - # in the team1 namespace - - group: delegation.kgateway.dev - kind: label - name: team1 - namespace: team1 - - matches: - - path: - type: PathPrefix - value: /anything/team2 - backendRefs: - # Delegate to routes with the label delegation.kgateway.dev/label:team2 - # in the team2 namespace - - group: delegation.kgateway.dev - kind: label - name: team2 - namespace: team2 - EOF - ``` - -2. Create the `child-team1` HTTPRoute resource in the `team1` namespace that matches traffic on the `/anything/team1/foo` path prefix. To delegate traffic to this HTTPRoute, you must label the route with the `delegation.kgateway.dev/label: team1` label that you defined on the `parent` HTTPRoute. - ```yaml - kubectl apply -f- <}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - content-length: 509 - x-envoy-upstream-service-time: 0 - server: envoy - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "delegation.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "65927858-2c6b-42ae-9278-8ff9d8bba3f8" - ] - }, - "origin": "10.0.64.27:49526", - "url": "http://delegation.example:8080/anything/team1/foo", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -6. Send a request to the `delegation.example` domain along the `/anything/team2/bar` path. Verify that you also get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/bar \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - content-length: 509 - x-envoy-upstream-service-time: 1 - server: envoy - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "delegation.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "d645dc37-5326-4b69-8c2c-4060e12ca4ff" - ] - }, - "origin": "10.0.64.27:53026", - "url": "http://delegation.example:8080/anything/team2/bar", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -## Use wildcard namespaces {#wildcard} - -Instead of routing to an HTTPRoute with a specific label in a specific namespace, you can use a wildcard for the namespace. This configuration can streamline your route delegation setup, as it allows you to easily add new child HTTPRoutes to the delegation chain. - -1. Update the `parent` HTTPRoute to delegate traffic to all child HTTPRoutes with the `wildcard` label. - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: http - hostnames: - - delegation.example - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - group: delegation.kgateway.dev - kind: label - name: wildcard - namespace: all - EOF - ``` - -2. Update the `child-team1` HTTPRoute to add the `delegation.kgateway.dev/label: wildcard` label so that the `parent` HTTPRoute can delegate traffic to this route. - ```yaml - kubectl apply -f- <}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - content-length: 509 - x-envoy-upstream-service-time: 0 - server: envoy - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "delegation.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "65927858-2c6b-42ae-9278-8ff9d8bba3f8" - ] - }, - "origin": "10.0.64.27:49526", - "url": "http://delegation.example:8080/anything/team1/foo", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -5. Send a request to the `delegation.example` domain along the `/anything/team2/bar` path. Verify that you also get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/bar \ - -H "host: delegation.example:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - content-length: 509 - x-envoy-upstream-service-time: 1 - server: envoy - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "delegation.example:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "d645dc37-5326-4b69-8c2c-4060e12ca4ff" - ] - }, - "origin": "10.0.64.27:53026", - "url": "http://delegation.example:8080/anything/team2/bar", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete httproute parent -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute child-team1 -n team1 -kubectl delete httproute child-team2 -n team2 -kubectl delete -n team1 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete namespaces team1 team2 -``` - diff --git a/assets/docs/pages/traffic-management/route-delegation/multi-level-delegation.md b/assets/docs/pages/traffic-management/route-delegation/multi-level-delegation.md deleted file mode 100644 index bba1f93a8..000000000 --- a/assets/docs/pages/traffic-management/route-delegation/multi-level-delegation.md +++ /dev/null @@ -1,251 +0,0 @@ -Create a 3-level route delegation hierarchy with a parent, child, and grandchild HTTPRoute resource. - -## Configuration overview - -In this guide you walk through a route delegation example that demonstrates route delegation from a parent HTTPRoute resource to a child HTTPRoute resource, and from a child HTTPRoute resource to a grandchild HTTPRoute resource. The following image illustrates the route delegation hierarchy: - -{{< reuse-image src="img//route-delegation-multi-level.svg" >}} -{{< reuse-image-dark srcDark="img//route-delegation-multi-level-dark.svg" >}} - -**`parent` HTTPRoute**: -* The parent HTTPRoute resource `parent` delegates traffic as follows: - * `/anything/team1` delegates traffic to the child HTTPRoute resource `child-team1` in namespace `team1`. - * `/anything/team2` delegates traffic to the child HTTPRoute resource `child-team2` in namespace `team2`. - -**`child-team1` HTTPRoute**: -* The child HTTPRoute resource `child-team1` matches incoming traffic for the `/anything/team1/foo` prefix path and routes that traffic to the httpbin app in the `team1` namespace. - -**`child-team2` HTTPRoute**: -* The child HTTPRoute resource `child-team2` delegates traffic on the `/anything/team2/grandchild` to a grandchild HTTPRoute resource in the `team2` namespace. - -**`grandchild` HTTPRoute**: -* The grandchild HTTPRoute resource `grandchild-team2` matches incoming traffic for the `/anything/team2/grandchild/.*` regex path and routes that traffic to the httpbin app in the `team2` namespace. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-delegation.md" >}} - -## Setup - -1. Create the parent HTTPRoute resource that matches incoming traffic on the `delegation.example` domain. The HTTPRoute resource specifies two routes: - * `/route1/team1`: The routing decision is delegated to a child HTTPRoute resource in the `team1` namespace. - * `/route2/team2`: The routing decision is delegated to a child HTTPRoute resource in the `team2` namespace. - ```yaml - kubectl apply -f- <}} - spec: - hostnames: - - delegation.example - parentRefs: - - name: http - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team1 - - matches: - - path: - type: PathPrefix - value: /anything/team2 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team2 - EOF - ``` - -2. Create the `child-team1` HTTPRoute resource in the `team1` namespace that matches traffic on the `/anything/team1/foo` prefix and routes traffic to the httpbin app in the `team1` namespace. The child HTTPRoute resource does not select a specific parent HTTPRoute resource. Because of that, the child HTTPRoute resource is automatically selected by all parent HTTPRoute resources that delegate traffic to this child. - ```yaml - kubectl apply -f- <}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -7. Send another request to the `delegation.example` domain along the `/anything/team1/bar` path. Verify that you get back a 404 HTTP response code, because this route is not specified in the child HTTPRoute resource `child-team1`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/bar \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/bar \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 404 Not Found - date: Mon, 06 May 2024 16:01:48 GMT - server: envoy - transfer-encoding: chunked - ``` - -8. Send another request to the `delegation.example` domain. This time, you use the `/anything/team2/grandchild/bar` path that is configured on the `grandchild` HTTPRoute resource. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/grandchild/bar \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/grandchild/bar \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -9. Send another request to the `delegation.example` domain along the `/anything/team2/grandchild/foo` path. Because the grandchild HTTPRoute resource uses a regular expression to match incoming traffic, you can use any valid endpoint in the httpbin app to route traffic to the httpbin app in the `team2` namespace. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/grandchild/foo \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/grandchild/foo \ - -H "host: delegation.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute parent -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute child-team1 -n team1 -kubectl delete httproute child-team2 -n team2 -kubectl delete httproute grandchild -n team2 -kubectl delete -n team1 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete namespaces team1 team2 -``` - diff --git a/assets/docs/pages/traffic-management/route-delegation/multi-parent.md b/assets/docs/pages/traffic-management/route-delegation/multi-parent.md deleted file mode 100644 index e4dbd6808..000000000 --- a/assets/docs/pages/traffic-management/route-delegation/multi-parent.md +++ /dev/null @@ -1,264 +0,0 @@ -Set up route delegation for a child HTTPRoute resource that can receive traffic from one or more parent HTTPRoute resources. - -## Configuration overview - -In this guide you walk through a route delegation example that demonstrates route delegation between two parent HTTPRoute and two child HTTPRoute resources that forward traffic to an httpbin sample app. The following image illustrates the route delegation hierarchy: - -{{< reuse-image src="img/route-delegation-multi-parent.svg" >}} -{{< reuse-image-dark srcDark="img/route-delegation-multi-parent-dark.svg" >}} - -**`parent1` and `parent2` HTTPRoutes**: -* The parent HTTPRoute resource `parent1` serves traffic for the `delegation-parent1.example` domain. -* The parent HTTPRoute resource `parent2` serves traffic for the `delegation-parent2.example` domain. -* Both parent HTTPRoute resources have routes that delegate traffic as follows: - * `/anything/team1` delegates traffic to the child HTTPRoute resource `child-team1` in namespace `team1`. - * `/anything/team2` delegates traffic to the child HTTPRoute resource `child-team2` in namespace `team2`. - -**`child-team1` HTTPRoute**: -* The child HTTPRoute resource `child-team1` matches incoming traffic for the `/anything/team1/foo` prefix path and routes that traffic to the httpbin app in namespace `team1`. The resource does not select any parent HTTPRoute resource in the `parentRef` section. Both parent HTTPRoute resources can therefore delegate traffic to this child HTTPRoute resource. - -**`child-team2` HTTPRoute**: -* The child HTTPRoute resource `child-team2` matches incoming traffic for the `/anything/team2/bar` exact prefix path and routes that traffic to the httpbin app in namespace `team2`. The resource selects the `parent1` HTTPRoute resource in the `parentRef` section. Because of that, only the `parent1` HTTPRoute resource can delegate traffic to this child HTTPRoute resource. The `parent2` HTTPRoute resource cannot delegate traffic to this child. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-delegation.md" >}} - -## Setup - -1. Create the `parent1` HTTPRoute resource that matches incoming traffic on the `delegation-parent1.example` domain. The HTTPRoute resource specifies two routes: - * `/anything/team1`: The routing decision is delegated to a child HTTPRoute resource in the `team1` namespace. - * `/anything/team2`: The routing decision is delegated to a child HTTPRoute resource in the `team2` namespace. - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: http - hostnames: - - "delegation-parent1.example" - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team1 - - matches: - - path: - type: PathPrefix - value: /anything/team2 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team2 - EOF - ``` - -2. Create the second `parent2` HTTPRoute resource that serves traffic for the `delegation-parent2.example` domain. The HTTPRoute resource specifies two routes: - * `/anything/team1`: The routing decision is delegated to a child HTTPRoute resource in the `team1` namespace. - * `/anything/team2`: The routing decision is delegated to a child HTTPRoute resource in the `team2` namespace. - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: http - hostnames: - - "delegation-parent2.example" - rules: - - matches: - - path: - type: PathPrefix - value: /anything/team1 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team1 - - matches: - - path: - type: PathPrefix - value: /anything/team2 - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: team2 - EOF - ``` - -3. Create the child HTTPRoute resource `child-team1` in the `team1` namespace that matches traffic on the `/anything/team1/foo` prefix and routes traffic to the httpbin app in the `team1` namespace. The child HTTPRoute resource does not select a specific parent HTTPRoute resource. Because of that, the child HTTPRoute resource is automatically selected by all parent HTTPRoute resources that delegate traffic to this child. - ```yaml - kubectl apply -f- <}} - group: gateway.networking.k8s.io - kind: HTTPRoute - rules: - - matches: - - path: - type: Exact - value: /anything/team2/bar - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` - -6. Send a request to the `delegation-parent1.example` domain along the `/anything/team1/foo` path. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo -H "host: delegation-parent1.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo -H "host: delegation-parent1.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -7. Send another request to the `delegation-parent1.example` domain along the `/anything/team2/bar` path. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar -H "host: delegation-parent1.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/bar -H "host: delegation-parent1.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -8. Now, send a request to the `delegation-parent2.example` domain along the `/anything/team1/foo` path. Verify that you get back a 200 HTTP response code. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo -H "host: delegation-parent2.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team1/foo -H "host: delegation-parent2.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Mon, 06 May 2024 15:59:32 GMT - x-envoy-upstream-service-time: 0 - server: envoy - transfer-encoding: chunked - ``` - -9. Send another request to the `delegation-parent2.example` domain. This time, you send traffic along the `/anything/team2/bar` path. Notice that although the `parent2` HTTPRoute resource delegates traffic to the `child-team2` HTTPRoute resource, the child resource allows traffic from the `parent1` HTTPRoute resource only. Because of that, the route is considered invalid and replaced with a 500 HTTP direct response. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar -H "host: delegation-parent2.example" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i localhost:8080/anything/team2/bar -H "host: delegation-parent2.example" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 500 Internal Server Error - content-length: 73 - content-type: text/plain - server: envoy - - invalid route configuration detected and replaced with a direct response - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute parent1 -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute parent2 -n {{< reuse "agw-docs/snippets/namespace.md" >}} -kubectl delete httproute child-team1 -n team1 -kubectl delete httproute child-team2 -n team2 -kubectl delete -n team1 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete -n team2 -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml -kubectl delete namespaces team1 team2 -``` - diff --git a/assets/docs/pages/traffic-management/route-delegation/overview.md b/assets/docs/pages/traffic-management/route-delegation/overview.md deleted file mode 100644 index 73a77ec8f..000000000 --- a/assets/docs/pages/traffic-management/route-delegation/overview.md +++ /dev/null @@ -1,133 +0,0 @@ -Delegate routing decisions to another HTTPRoute resource. - -## What is route delegation - -As your environment grows, your gateways manage traffic for more and more routes. These routes typically belong to many different apps that are owned by different individuals or teams. Managing the routing rules for all of these routes can be cumbersome and route updates can easily impact the behavior of other routes. - -Route delegation allows you to split up big and complex routing configurations into smaller routing configurations that are easier to maintain. The ownership for these routing configurations are then delegated to the teams that own the app or domain. - -For example, let's assume you have three apps (`app-a`, `app-b`, and `app-c`) that are owned by three different teams (`team-a`, `team-b`, and `team-c`). Instead of creating one routing configuration that includes the routing rules for all apps, you create a routing configuration for each app and delegate ownership for this configuration to the team that is responsible for that app. Each team can then further delegate routing decisions to other teams. - -Each set of routing rules is defined in a dedicated HTTPRoute resource. These HTTPRoute resources are then organized into a routing hierarchy that consists of the following elements: - -| Element in routing hierarchy | Resource | Description| -|----------------|---|--| -|Parent|HTTPRoute| The parent HTTPRoute resource specifies the main domain under which all of the routes that are defined in the parent, child, or grandchild HTTPRoute resources are exposed on. The parent HTTPRoute resource also references the gateway that you want to use to fulfill the routing configuration in the `parentRef` section. To delegate traffic to a child HTTPRoute resource, a `PathPrefix` matcher must be used. | -|Child |HTTPRoute|The child HTTPRoute resource receives traffic from the parent HTTPRoute resource and can either forward traffic to the backing service, or delegate traffic decisions to grandchild HTTPRoute resources. To receive delegated traffic from a parent, the child HTTPRoute must match on a path that contains the path prefix for which the parent delegated traffic for. For example, if the parent delegates traffic for `/route`, the child must define a route that includes this prefix, such as `/route/a`. If traffic is further delegated to a grandchild HTTPRoute resource, a `PathPrefix` matcher must be used. | -|Grandchild|HTTPRoute|A grandchild HTTPRoute resource receives traffic from a child HTTPRoute resource and can either bind to a specific child by using the `parentRef` section or be selected by all child HTTPRoute resources that want to delegate traffic to this grandchild. To receive traffic from a child, the grandchild must match on a path that contains the path prefix for which the child delegated traffic for. For example, if the child delegates traffic for `/route/a`, the grandchild must define a route that includes this prefix, such as `/route/a/myservice`. If traffic is further delegated to a great-grandchild HTTPRoute resource, a `PathPrefix` matcher must be used. Note that great-grandchild or great-great-grandchild behave similar to a grandchild HTTPRoute resource. | - -{{< callout type="info" >}} -For an example route delegation setup with a parent, child, and grandchild HTTPRoute resource, see [Multi-level delegation]({{< link-hextra path="/traffic-management/route-delegation/multi-level-delegation/" >}}). -{{< /callout >}} - -## Benefits and use cases - -Route delegation is often used as a security and risk mitigation strategy to allow multiple teams to own, add, remove, and update routes on a gateway without impacting the routing rules that other teams configured and requiring access to the entire routing configuration. - -Review some of the benefits that you can achieve with route delegation: - -|Benefit| Description| -|--|--| -|Organize routing rules by user groups|With route delegation, you can break up large routing configurations into smaller routing configurations which makes them easier to maintain and to assign ownership to. Each routing configuration in the routing hierarchy contains the routing rules and policies for only a subset of routes. | -|Restrict access to routing configuration| Because route delegation lets you break up large routing configurations into smaller, manageable pieces, you can easily assign ownership and restrict access to the smaller routing configurations to the individual or teams that are responsible for a specific app or domain. For example, the network administrator can configure the top level routing rules, such as the hostname and main route match, and delegate the individual routing rules to other teams. | -|Simplify blue-green route testing|To test new routing configuration, you can easily delegate a specific number of traffic to the new set of routes.| -| Optimize traffic flows| Route delegation can be used to distribute traffic load across multiple paths or nodes in the cluster, which can improve network performance and reliability. | -|Easier updates with limited blast radius| Individual teams can easily update the routing configuration for their apps and manage the policies for their routes. If errors are introduced, the blast radius is limited to the set of routes that were changed. | - -## Policy inheritance - -Review how policies are inherited along the route delegation chain. - -For more information, see the [Policy inheritance]({{< link-hextra path="/traffic-management/route-delegation/inheritance/" >}}) guides. - -### Native Gateway API policies - -{{< reuse "agw-docs/snippets/policy-inheritance-native.md" >}} - -### Kgateway policies - -{{< reuse "agw-docs/snippets/policy-inheritance.md" >}} - -## Automatic route replacement - -If a destination that is defined in the HTTPRoute's `backendRefs` section cannot be found, such as when a parent HTTPRoute routes traffic to a child HTTPRoute that does not exist, the route is automatically replaced with a 500 HTTP direct response. However, valid routes are not replaced and continue to work. - -## Weighted routing - -You can use delegated routes together with [weighted routes](../../weighted-routes/). Make sure to enable the weighted routing feature. Then, add the `kgateway.dev/route-weight` annotation to the child HTTPRoute that you want to weight. Children **do not** inherit the weight of their parent HTTPRoute. - -## Limitations - -The current route delegation model imposes a few restrictions on how routes can be delegated. If a rule is violated, the corresponding rule is removed from the route. - -### Hostnames - -Only parent HTTPRoutes can specify the `spec.hostnames` field. All child and grandchild HTTPRoute resources inherit the parent's hostname. - -### Route matchers -Parent HTTPRoute resources that delegate to child HTTPRoute resources _must_ use `PathPrefix` matchers as shown in the following example: - -```yaml {linenos=table,hl_lines=[2,3,4,5],linenostart=1},filename="route-matcher.yaml" - rules: - - matches: - - path: - type: PathPrefix - value: /a - backendRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: "*" - namespace: abc -``` - -Child HTTPRoute resources can use prefix, exact, or regex path matchers in their matching rules as shown in the following example. Each path matcher must start with the prefix path that the parent HTTPRoute delegates traffic for, in this case `/a`. The child HTTPRoute in the following example defines three route matchers along the `/a` path: `/1`, `/1/foo`, and `/1/.*`. -```yaml {linenos=table,hl_lines=[5,8,11],linenostart=1},filename="route-matcher.yaml" - rules: - - matches: - - path: - type: PathPrefix - value: /a/1 - - path: - type: Exact - value: /a/1/foo - - path: - type: RegularExpression - value: /a/1/.* - backendRefs: - - name: svc-a - port: 8080 -``` - -{{< callout type="info" >}} -Keep in mind that if a child HTTPRoute delegates routing decisions to a grandchild or great-grandchild HTTPRoute, a `PathPrefix` matcher must be used for that route. Check out the [Multi-level delegation]({{< link-hextra path="/traffic-management/route-delegation/multi-level-delegation/" >}}) guide for an example of how to set up route delegation between a parent, child, and grandchild HTTPRoute. -{{< /callout >}} - -{{< callout type="info" >}} -You can optionally set the `delegation.kgateway.dev/inherit-parent-matcher: "true"` annotation on the child HTTPRoute to inherit all the matchers, headers, and query parameters from the parent. To find an example, see [Header and query match]({{< link-hextra path="/traffic-management/route-delegation/header-query/" >}}). -{{< /callout >}} - - -### Headers, query parameters, HTTP methods - -You can specify headers, query parameters, and HTTP method matchers on the parent HTTPRoute resource. However, any child HTTPRoute resource that you delegate traffic to must specify the same header, query parameters, or HTTP method matchers to be considered a valid configuration. You can optionally define additional header, query parameter, or HTTP method matchers on the child. - -{{< callout type="info" >}} -You can optionally set the `delegation.kgateway.dev/inherit-parent-matcher: "true"` annotation on the child HTTPRoute to inherit all the matchers, headers, and query parameters from the parent. That way, the headers and query parameters do not need to be defined on the child HTTPRoute. -{{< /callout >}} - -For example, let's say you define the following parent and child HTTPRoute resources: - -| Example configuration | Valid route delegation configuration?| -|-------------|---| -|
  • parent
    • match on /anything/team1 and delegate traffic to the child HTTPRoute
    • header1: val1
    • query1=val1
  • child
    • match on /anything/team1/foo and route traffic to the httpbin app
    • header1: val1
    • headerX: valX
    • query1=val1
    • queryX=valX
| ✅

The headers and query parameters that are specified on the child HTTPRoute are a superset of the header and query parameters that are specified on the parent. | -|
  • parent
    • match on /anything/team1 and delegate traffic to the child HTTPRoute
    • header1: val1
    • query1=val1
  • child
    • match on /anything/team1/foo and route traffic to the httpbin app
    • headerX: valX
    • queryX=valX
| ❌

The headers and query parameters that are specified on the child HTTPRoute do not include the header and query parameters that are specified on the parent. | -|
  • parent
    • match on /anything/team1 and delegate traffic to the child HTTPRoute
    • header1: val1
    • query1=val1
  • child
    • match on /anything/team1/foo and route traffic to the httpbin app
    • headerX: valX
    • queryX=valX
    • delegation.kgateway.dev/inherit-parent-matcher: "true"
| ✅

The headers and query parameters that are specified on the child HTTPRoute do not include the header and query parameters that are specified on the parent. However, the `delegation.kgateway.dev/inherit-parent-matcher: "true"` annotation is set and allows the child HTTPRoute to inherit the matchers, headers, and query parameters from the parent. | - -{{< callout type="info" >}} -For an example route delegation setup that uses header and query parameters, see [Header and query match]({{< link-hextra path="/traffic-management/route-delegation/header-query/" >}}). -{{< /callout >}} - -### Cyclic delegation - -Cyclic route delegations, such as where HTTPRoute A delegates to B, B delegates to C, and C delegates back to A are not allowed as no proper backend is specified that fulfills the request. If cyclic route delegation is detected, the route that is part of the cycle is automatically replaced with a 500 HTTP direct response. - diff --git a/assets/docs/pages/traffic-management/session-affinity/consistent-hashing.md b/assets/docs/pages/traffic-management/session-affinity/consistent-hashing.md deleted file mode 100644 index 2f6e3edb0..000000000 --- a/assets/docs/pages/traffic-management/session-affinity/consistent-hashing.md +++ /dev/null @@ -1,405 +0,0 @@ -Set up soft session affinity between a client and a backend service by using consistent hashing algorithms. - -## About session affinity - -Session affinity allows you to route requests for a particular session to the same backend service instance that served the initial request. This setup is particularly useful if you have a backend service that performs expensive operations and caches the output or data for subsequent requests. With session affinity, you make sure that the expensive operation is performed once and that subsequent requests can be served from the backend's cache, which can significantly improve operational cost and response times for your clients. - -## About consistent hashing - -{{< reuse "agw-docs/snippets/kgateway-capital.md" >}} allows you to set up soft session affinity between a client and a backend service by using the [Ringhash](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto.html) or [Maglev](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/load_balancers#maglev) consistent hashing algorithm. The hashing algorithm uses a property of the request, such as a cookie, header, or source IP address, and hashes this property with the address of a backend service instance that served the initial request. In subsequent requests, as long as the client sends the same request property, the request is routed to the same backend service instance. - -Request properties are configured in the `loadBalancer.hashPolicies` section of a BackendConfigPolicy. The header, cookie, and sourceIP hash policies are mutually exclusive, in that a request can only have one property that the algorithm uses for hashing. However, you can define multiple different hash policies within one BackendConfigPolicy by using the `terminal` field for each hash policy. If a policy has the `terminal: true` setting and the policy is matched, any subsequent hash policies are skipped. This field is useful for defining fallback policies, and limiting the amount of time spent generating hash keys. - -{{< callout type="info" >}} -Consistent hashing is less reliable than a "strong" or "sticky" session affinity implementation, such as session persistence, in which the backend service is encoded in a cookie or header and affinity can be maintained for as long as the backend service is available. With consistent hashing, affinity might be lost when an instance is added or removed from the backend service's pool, or if the gateway proxy restarts. To set up strong stickiness, see the [Session persistence](../session-persistence) docs. -{{< /callout >}} - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up consistent hashing - -See the following links to get started: -* [Ringhash](#ringhash) -* [Maglev](#maglev) - -### Ringhash - -Ringhash allows you to tune the ring size to balance memory usage vs load distribution precision. This way, you get more fine-grained control over how traffic is distributed across endpoint. However, this configurability might come at a performance cost, depending on your setup. To learn more about Ringhash, see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto.html). - -1. Create a BackendConfigPolicy that uses the request property of your choice. - {{< tabs tabTotal="3" items="Headers,Cookies,Source IP address" >}} - {{% tab tabName="Headers" %}} - - Create a consistent hash by using a specific request header. - - ```yaml - kubectl apply -f- <}} - - | Setting | Description | - | -- | -- | - | `ringHash.minimumRingSize` | The minimum ring size. The size of the ring determines the number of hashes that can be assigned for each host and placed on the ring. The ring number is divided by the number of hosts that serve the request. For example, if you have 2 hosts and the minimum ring size is 1000, each host gets approximately 500 hashes in the ring. When a request is received, the request is assigned a hash in the ring, and therefore assigned to a particular host. Generally speaking, the larger the ring size is, the better distribution between hosts can be achieved. If not set, the minimum ring size defaults to 1024. | - | `ringHash.maximumRingSize` | The maximum ring size. If not set, the maximum ring size defaults to 8 million. | - | `useHostnameForHashing` | If set to true, the gateway proxy uses the hostname as the key to consistently hash to a backend host. If not set, defaults to using the resolved address of the hostname as the key. | - | `header.name` | The expected header name to create the hash with. | - | `terminal` | If you define multiple `hashPolicies` in one BackendConfigPolicy, you can use the `terminal` field to determine which policy is the priority. For example, in this policy, the `x-user-id` header has the `terminal: true` setting. This indicates that if the request has the `x-user-id` header, any subsequent policies (such as the `x-session-id` header in this example) are skipped. This field is useful for defining fallback policies, and limiting the amount of time spent generating hash keys. | - | `closeConnectionsOnHostSetChange` | If set to true, the proxy drains all existing connections to a backend host whenever hosts are added or removed for a backend pool. | - - - {{% /tab %}} - {{% tab tabName="Cookies" %}} - - Create a consistent hash by using a cookie. - - ```yaml - kubectl apply -f- <}} - - | Setting | Description | - | -- | -- | - | `ringHash.minimumRingSize` | The minimum ring size. The size of the ring determines the number of hashes that can be assigned for each host and placed on the ring. The ring number is divided by the number of hosts that serve the request. For example, if you have 2 hosts and the minimum ring size is 1000, each host gets approximately 500 hashes in the ring. When a request is received, the request is assigned a hash in the ring, and therefore assigned to a particular host. Generally speaking, the larger the ring size is, the better distribution between hosts can be achieved. If not set, the minimum ring size defaults to 1024. | - | `ringHash.maximumRingSize` | The maximum ring size. If not set, the maximum ring size defaults to 8 million. | - | `cookie.name` | The expected cookie name to create the hash with. In this example, the cookie is named `session-id`. | - | `cookie.path` | The name of the path for the cookie, such as `/api` in this example. | - | `cookie.ttl` | If the cookie is not present, a cookie with this duration of time for validity is generated, such as 30 minutes in this example. | - | `cookie.attributes` | Define additional attributes for an HTTP cookie. This example sets three additional attirbutes: `httpOnly: true`, `secure: true`, and `sameSite: Strict`. | - | `terminal` | If you define multiple `hashPolicies` in one BackendConfigPolicy, you can use the `terminal: true` setting to indicate the priority policy. | - - - {{% /tab %}} - {{% tab tabName="Source IP" %}} - - Create a consistent hash by using the source IP address. - - ```yaml - kubectl apply -f- <}} - -2. Continue with [Verify consistent hashing](#verify). - - -### Maglev - -With Maglev, you use a fixed lookup table of 65,357 entries that is optimized for fast request routing with deterministic performance. This option is well-suited for general-purpose workloads that do not require custom tuning. For more information, see the [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/load_balancers#maglev). - -1. Create a BackendConfigPolicy that uses the request property of your choice. - {{< tabs items="Headers,Cookies,Source IP address" tabTotal="3" >}} - {{% tab tabName="Headers" %}} - - ```yaml - kubectl apply -f- <}} - - | Setting | Description | - | -- | -- | - | `header.name` | The expected header name to create the hash with. | - | `terminal` | If you define multiple `hashPolicies` in one BackendConfigPolicy, you can use the `terminal` field to determine which policy is the priority. For example, in this policy, the `x-user-id` header has the `terminal: true` setting. This indicates that if the request has the `x-user-id` header, any subsequent policies (such as the `x-session-id` header in this example) are skipped. This field is useful for defining fallback policies, and limiting the amount of time spent generating hash keys. | - | `useHostnameForHashing` | If set to true, the gateway proxy uses the hostname as the key to consistently hash to a backend host. If not set, defaults to using the resolved address of the hostname as the key. | - | `closeConnectionsOnHostSetChange` | If set to true, the proxy drains all existing connections to a backend host whenever hosts are added or removed for a backend pool. | - - {{% /tab %}} - {{% tab tabName="Cookies" %}} - - ```yaml - kubectl apply -f- <}} - - | Setting | Description | - | -- | -- | - | `cookie.name` | The expected cookie name to create the hash with. In this example, the cookie is named `session-id`. | - | `cookie.path` | The name of the path for the cookie, such as `/api` in this example. | - | `cookie.ttl` | If the cookie is not present, a cookie with this duration of time for validity is generated, such as 30 minutes in this example. | - | `cookie.attributes` | Define additional attributes for an HTTP cookie. This example sets three additional attirbutes: `httpOnly: true`, `secure: true`, and `sameSite: Strict`. | - | `terminal` | If you define multiple `hashPolicies` in one BackendConfigPolicy, you can use the `terminal: true` setting to indicate the priority policy. | - - {{% /tab %}} - {{% tab tabName="Source IP" %}} - - ```yaml - kubectl apply -f- <}} - -2. Continue with [Verify consistent hashing](#verify). - - -## Verify consistent hashing {#verify} - -Send a few requests to the httpbin app and verify that the request is served by the same backend instance. - -1. Scale the httpbin app up to two instances. - ```sh - kubectl scale deployment httpbin -n httpbin --replicas=2 - ``` - -2. Verify that another instance of the httpbin app is created. - ```sh - kubectl get pods -n httpbin - ``` - - Example output: - ``` - NAME READY STATUS RESTARTS AGE - httpbin-8d557795f-86hzg 3/3 Running 0 54s - httpbin-8d557795f-h8ks9 3/3 Running 0 26m - ``` - -3. Test consistent hashing by sending multiple requests to the httpbin app and verifying that all requests are served by the same backend instance. Note that the verification steps vary depending on the hashing policy that you defined. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - - * **Headers**: - ```sh - for i in {1..10}; do curl -vik http://$INGRESS_GW_ADDRESS:8080/headers \ - -H "x-user-id: me" \ - -H "host: www.example.com"; done - ``` - - * **Source IP address**: - ```sh - for i in {1..10}; do curl -vik http://$INGRESS_GW_ADDRESS:8080/headers \ - -H "host: www.example.com"; done - ``` - - * **Cookies**: - 1. Send a request to the httpbin app and verify that you get back a `set-cookie` header with a `session-id`. - ```sh - curl -i -c cookie-jar -k http://$INGRESS_GW_ADDRESS:8080/headers \ - -H "host: www.example.com" - ``` - - Example output: - ```console - set-cookie: session-id="76fe9617cf960748"; Max-Age=1800; Path=/api; Secure=true; HttpOnly=true; SameSite=Strict; HttpOnly - ``` - - 2. Send a few more requests to the httpbin app and include the session ID from the previous step. - ```sh - for i in {1..10}; do - curl -i -b session-id="" -k http://$INGRESS_GW_ADDRESS:8080/headers \ - -H "host: www.example.com"; done - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - - * **Headers** - ```sh - for i in {1..10}; do curl -vik localhost:8080/headers \ - -H "x-user-id: me" \ - -H "host: www.example.com"; done - ``` - - * **Source IP address** - ```sh - for i in {1..10}; do curl -vik localhost:8080/headers \ - -H "host: www.example.com"; done - ``` - - * **Cookies**: - 1. Send a request to the httpbin app and verify that you get back a `set-cookie` header with a `session-id`. - ```sh - curl -i -c -k localhost:8080/headers \ - -H "host: www.example.com" - ``` - - Example output: - ```console - set-cookie: session-id="76fe9617cf960748"; Max-Age=1800; Path=/api; Secure=true; HttpOnly=true; SameSite=Strict; HttpOnly - ``` - - 2. Send a few more requests to the httpbin app and include the session ID from the previous step. - ```sh - for i in {1..10}; do - curl -i -b session-id="" -k localhost:8080/headers \ - -H "host: www.example.com"; done - ``` - {{% /tab %}} - {{< /tabs >}} - -7. Check the logs of each httpbin instance. Verify that only one of the instances served all 10 of the subsequent requests that you made. - ```sh - kubectl logs -n httpbin - ``` - - Example output for one pod, in which all 10 subsequent requests (timestamps at `17:20`) are served after the previous 1 request (timestamp at `17:17`): - ``` - Defaulted container "httpbin" out of: httpbin, curl - go-httpbin listening on http://0.0.0.0:8080 - time="2025-07-16T17:17:09.8479" status=200 method="GET" uri="/headers" size_bytes=440 duration_ms=0.10 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:20:32.1077" status=200 method="GET" uri="/headers" size_bytes=445 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:20:40.7017" status=200 method="GET" uri="/headers" size_bytes=445 duration_ms=0.05 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:20:49.5744" status=200 method="GET" uri="/headers" size_bytes=515 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.244.0.7 - ... - ``` - - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Scale the httpbin app back down. - ```sh - kubectl scale deployment httpbin -n httpbin --replicas=1 - ``` - -2. Delete the resources that you created. - ```sh - kubectl delete BackendConfigPolicy httpbin-hash -n httpbin - ``` - - diff --git a/assets/docs/pages/traffic-management/session-affinity/loadbalancing.md b/assets/docs/pages/traffic-management/session-affinity/loadbalancing.md deleted file mode 100644 index 8619fed46..000000000 --- a/assets/docs/pages/traffic-management/session-affinity/loadbalancing.md +++ /dev/null @@ -1,184 +0,0 @@ -Decide how to load balance incoming requests to backend services. - -## About simple load balancing - -{{< reuse "agw-docs/snippets/kgateway-capital.md" >}} supports multiple load balancing algorithms for selecting backend services to forward incoming requests to. By default, incoming requests are forwarded to the instance with the least requests. You can change this behavior and instead use a round robin algorithm to forward the request to a backend service. - -### Least request - -The [least request load balancer algorithm](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/load_balancers#weighted-least-request) generally selects the host with the fewest requests. The following rules apply: - -* If no `localityType` is set, send the request to the host with the fewest requests. -* If `localityType` is set, a weighted round robin approach is used, in which higher weighted endpoints are considered more often in the round robin rotation to achieve the selected weight. - -### Round robin - -The [round robin load balancer algorithm](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/load_balancers#weighted-least-request) selects a backend host in a round robin order. If a `localityType` is also defined, a weighted round robin algorithm is used, in which higher weighted endpoints are considered more often in the round robin rotation to achieve the selected weight. - -### Random - -The [random load balancer algorithm](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/load_balancers#weighted-least-request) selects a random host that is available. This load balancing algorithm usually performs better than the round robin algorithm if no health checks are configured for the backend host. - -## Other load balancing options - -Learn about other load balancing options that you can set in the load balancer policy. - -{{< callout type="info" >}} -All settings in this section can be set only in conjunction with a simple load balancing mode or consistent hash algorithm. -{{< /callout >}} - -### Healthy panic threshold - -By default, {{< reuse "agw-docs/snippets/kgateway.md" >}} only considers services that are healthy and available when load balancing incoming requests among backend services. In the case that the number of healthy backend services becomes too low, you can instruct {{< reuse "agw-docs/snippets/kgateway.md" >}} to disregard the backend health status and either load balance requests among all or no hosts by using the `healthy_panic_threshold` setting. If not set, the threshold defaults to 50%. To disable panic mode, set this field to 0. - -To learn more about this setting and when to use it, see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/panic_threshold#arch-overview-load-balancing-panic-threshold). - -### Update merge window - -Sometimes, your deployments might have health checks and metadata updates that use a lot of CPU and memory. In such cases, you can use the `update_merge_window` setting. This way, {{< reuse "agw-docs/snippets/kgateway.md" >}} merges all updates together within a specific timeframe. For more information about this setting, see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-commonlbconfig). If not set, the update merge window defaults to 1000ms. To disable the update merge window, set this field to 0s. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up a load balancing algorithm - -Define the load balancing algorithm that you want to use for your backend app in a BackendConfigPolicy. - -1. Create a BackendConfigPolicy to configure your load balancing algorithm for the httpbin app. - {{< tabs tabTotal="3" items="Least requests,Round robin,Random" >}} - {{% tab tabName="Least requests" %}} - ```yaml - kubectl apply -f- <}} - - | Setting | Description | - | -- | -- | - | `choiceCount` | The number of random available backend hosts to consider when choosing the host with the fewest requests. Deafults to 2. | - | `slowStart` | When you add new backend hosts to the pool of endpoints to route to, slow start mode progressively increases the amount of traffic that is routed to those backends. This can be useful for services that require warm-up time to serve full production loads, to prevent request timeouts, loss of data, and deteriorated user experience. | - | `slowStart.window` | The duration of the slow start window. If set, a newly-created backend endpoint remains in slow start mode from its creation time until the duration of the slow start window has elapsed. | - | `slowStart.aggression` | The rate of traffic increase over the duration of the slow start window. Defaults to 1.0, so that the endpoint receives a linearly-increasing amount of traffic. For more information about fine-tuning this value, see the [API docs](../../../../reference/api/#slowstart). | - | `slowStart.minWeightPercent` | The minimum percentage of weight that an endpoint must have in the caluclation of aggression. This helps prevent weights that are so small that endpoints receive no traffic during the slow start window. Defaults to 10%. | - {{% /tab %}} - {{% tab tabName="Round robin" %}} - ```yaml - kubectl apply -f- <}} - - | Setting | Description | - | -- | -- | - | `slowStart` | When you add new backend hosts to the pool of endpoints to route to, slow start mode progressively increases the amount of traffic that is routed to those backends. This can be useful for services that require warm-up time to serve full production loads, to prevent request timeouts, loss of data, and deteriorated user experience. | - | `slowStart.window` | The duration of the slow start window. If set, any newly-created backend endpoints remain in slow start mode from its creation time until the duration of the slow start window has elapsed. | - | `slowStart.aggression` | The rate of traffic increase over the duration of the slow start window. Defaults to 1.0, so that the endpoint receives a linearly-increasing amount of traffic. For more information about fine-tuning this value, see the [API docs](../../../../reference/api/#slowstart). | - | `slowStart.minWeightPercent` | The minimum percentage of weight that an endpoint must have in the caluclation of aggression. This helps prevent weights that are so small that endpoints receive no traffic during the slow start window. Defaults to 10%. | - {{% /tab %}} - {{% tab tabName="Random" %}} - Note that no further settings are required because the load balancing is random. - ```yaml - kubectl apply -f- <}} - -2. Verify that your configuration is applied by reviewing the Envoy configuration. - 1. Port forward the `http` deployment on port 19000. - ```sh - kubectl port-forward deploy/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000 & - ``` - 2. Open the `config_dump` endpoint. - ```sh - open http://localhost:19000/config_dump - ``` - 3. Search for the `load_balancing_policy` field, and verify that the policy that you set is listed, along with your other load balancing settings. For example, the following output shows the `LEAST_REQUEST` policy, with the `choice_count` field set to `3`, and settings for the slow start window. - ```json - ... - "load_balancing_policy": { - "policies": [ - { - "typed_extension_config": { - "name": "envoy.load_balancing_policies.least_request", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest", - "choice_count": 3, - "slow_start_config": { - "slow_start_window": "10s", - "aggression": { - "default_value": 1.5, - "runtime_key": "httpbin-lb-policy.httpbin.slowStart.aggression" - }, - "min_weight_percent": { - "value": 10 - } - } - } - } - } - } - ... - ``` - 4. Stop port-forwarding the `http` deployment. - ```sh - lsof -ti:19000 | xargs kill -9 - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete BackendConfigPolicy httpbin-lb-policy -n httpbin -``` - - diff --git a/assets/docs/pages/traffic-management/session-affinity/session-persistence.md b/assets/docs/pages/traffic-management/session-affinity/session-persistence.md deleted file mode 100644 index 7a59743cc..000000000 --- a/assets/docs/pages/traffic-management/session-affinity/session-persistence.md +++ /dev/null @@ -1,289 +0,0 @@ -Ensure that traffic from a client is always routed to the same backend instance for the duration of a session. - -{{< callout type="warning" >}} -{{< reuse "agw-docs/versions/warn-1-3-only-experimental.md" >}} -{{< /callout >}} - -## About - -HTTPRoutes support `sessionPersistence`, also known as "strong" session affinity or sticky sessions. Session persistence ensures that traffic is always routed to the same backend instance for the duration of the session, which can improve request latency and the user experience. - -In session persistence, a client directly provides information, such as a header or a cookie, that the gateway proxy uses as a reference to direct traffic to a specific backend server. The persistent client request bypasses the proxy's load balancing algorithm and is routed directly to the backend that it previously established a session with. - -**Cookie**: When you use cookie-based persistence, a client sends a request to your app, and receives a `set-cookie` response header. The client then reuses that value in a cookie request header in subsequent requests. The gateway proxy uses this cookie to maintain a persistent connection to a single backend server on behalf of the client. - -**Header**: When you use cookie-based persistence, a client sends a request to your app, and receives an HTTP response header. The client then reuses that value in the same header in subsequent HTTP requests. The gateway proxy uses this header to maintain a persistent connection to a single backend server on behalf of the client. - -### Session persistence versus session affinity - -In session persistence, the backend service is encoded in a cookie or header and affinity can be maintained for as long as the backend service is available. This makes session persistence more reliable than [session affinity through consistent hashing](../consistent-hashing), or "weak" session affinity, in which affinity might be lost when a backend service is added or removed, or if the gateway proxy restarts. - -However, note that session persistence and session affinity can functionally work together in your {{< reuse "/agw-docs/snippets/kgateway.md" >}} setup. If you define both session persistence and session affinity through consistent hashing, the gateway proxy makes the following routing decisions for incoming requests: -- If the request contains a session persistence identity in a cookie or header, route the request directly to the backend that it previously established a session with. -- If no session persistence identity is present, load balance the request according to the defined session affinity configuration, along with any [load balancing configuration](../loadbalancing). - -For more information about session peristence, see the [Kubernetes Gateway API enhancement doc](https://gateway-api.sigs.k8s.io/geps/gep-1619/). - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq-1-3-channel-experimental.md" >}} - -## Configure session persistence - -Define session persistence based on either a request cookie or header in the `sessionPersistence` section of an HTTPRoute. This example defines session persistence for requests to `/path-A` by using cookies, and session persistence for requests to `/path-B` by using headers. - -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: example-route - namespace: default -spec: - parentRefs: - - name: example-gateway - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - rules: - - matches: - - path: - type: PathPrefix - value: /path-A - backendRefs: - - name: backend - port: 3000 - sessionPersistence: - sessionName: Session-A - type: Cookie - absoluteTimeout: 10s - cookieConfig: - lifetimeType: Permanent - - matches: - - path: - type: PathPrefix - value: /path-B - backendRefs: - - name: backend - port: 3000 - sessionPersistence: - sessionName: Session-B - type: Header - idleTimeout: 10s -``` - -{{< callout type="info" >}} -Note that `sessionPersistence.idleTimeout` is currently not supported in Envoy-based gateway proxies. Setting this value has no effect on the gateway proxy. -{{< /callout >}} - -{{< reuse "/agw-docs/snippets/review-table.md" >}} - -| Setting | Description | -| -- | -- | -| `sessionName` | The name of the persistent session, which is reflected in the cookie or the header that the proxy sends in response to the client and the client reuses in subsequent requests. To prevent unpredictable behavior or rejection, do not reuse session names. | -| `type` | The request property, either `Header` or `Cookie`, to base session persistence on. Defaults to `Cookie`. | -| `idleTimeout` | The idle timeout of the persistent session. Once the session has been idle for more than the specified duration, the session becomes invalid. | -| `absoluteTimeout` | The absolute timeout of the persistent session. Once the duration has elapsed, the session becomes invalid. | -| `cookieConfig.lifetimeType` | If the `type` is `Cookie`, the `lifetimeType` determines whether the session cookie has a `Permanent` or `Session`-based lifetime. A permanent cookie persists until its specified expiry time, while a session cookie is deleted when the current session ends. When set to `Permanent`, `absoluteTimeout` indicates the cookie's lifetime as defined by either the `Expires` or `Max-Age` cookie attributes, and is required. When set to `Session`, `absoluteTimeout` indicates the absolute lifetime of the cookie that is tracked by the gateway, and is optional. **Note**: To maintain affinity even when the gateway proxy restarts, you must set this field to `Permanent`. Defaults to `Session`. | - -## Verify the session persistence configuration {#verify} - -To try out session persistence, you can follow these steps to define cookie-based session persistence in the HTTPRoute for the httpbin sample app. - -1. Scale the httpbin app up to two instances. - ```sh - kubectl scale deployment httpbin -n httpbin --replicas=2 - ``` - -2. Verify that another instance of the httpbin app is created. - ```sh - kubectl get pods -n httpbin - ``` - - Example output: - ``` - NAME READY STATUS RESTARTS AGE - httpbin-8d557795f-86hzg 3/3 Running 0 54s - httpbin-8d557795f-h8ks9 3/3 Running 0 26m - ``` - -3. Modify the sample HTTPRoute resource for the httpbin app to add the following `sessionPersistence` section. These settings instruct the gateway proxy to create a persistent session cookie called `Session-A` for any new client connections to the httpbin app. Each created session has an absolute timeout of 30 minutes, and the cookie for each session is deleted only when that timeout ends. - ```yaml - kubectl apply -f- <}} - hostnames: - - "www.example.com" - rules: - - backendRefs: - - name: httpbin - port: 8000 - sessionPersistence: - sessionName: Session-A - type: Cookie - absoluteTimeout: 30m - cookieConfig: - lifetimeType: Permanent - EOF - ``` - -4. Send a request to the httpbin app and verify that you see the `Session-A` cookie in the `set-cookie` header of your response. The `-c` option stores the cookie in a local file on your machine so that you can use it in subsequent requests. - {{< tabs tabTotal="2" items="LoadBalancer IP address or hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address or hostname" %}} - ```sh - curl -i -c cookie-jar -k http://$INGRESS_GW_ADDRESS:8080/headers \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -i -c cookie-jar -k localhost:8080/headers \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[8]} - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Wed, 16 Jul 2025 17:20:40 GMT - content-length: 445 - x-envoy-upstream-service-time: 0 - set-cookie: Session-A="Cg8xMC4yNDQuMC42OjgwODA="; HttpOnly - server: envoy - ... - ``` - -5. Repeat the request a few more times. Include the cookie that you stored in the local file by using the `-b` option. Make sure to send these requests within the 30 minute cookie validity period. - {{< tabs tabTotal="2" items="LoadBalancer IP address or hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address or hostname" %}} - ```sh - for i in {1..10}; do - curl -i -b cookie-jar -k http://$INGRESS_GW_ADDRESS:8080/headers \ - -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - for i in {1..10}; do - curl -i -b cookie-jar -k localhost:8080/headers \ - -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{< /tabs >}} - -6. Check the logs of each httpbin instance. Verify that only one of the instances served all 10 of the subsequent requests that you made. - ```sh - kubectl logs -n httpbin - ``` - - Example output for one pod, in which all 10 subsequent requests (timestamps at `17:20`) are served after the previous 1 request (timestamp at `17:17`): - ``` - Defaulted container "httpbin" out of: httpbin, curl - go-httpbin listening on http://0.0.0.0:8080 - time="2025-07-16T17:17:09.8479" status=200 method="GET" uri="/headers" size_bytes=440 duration_ms=0.10 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:20:32.1077" status=200 method="GET" uri="/headers" size_bytes=445 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:20:40.7017" status=200 method="GET" uri="/headers" size_bytes=445 duration_ms=0.05 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:20:49.5744" status=200 method="GET" uri="/headers" size_bytes=515 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.244.0.7 - ... - ``` - -7. Optional: Verify the permanence of the session cookie by restarting the http gateway. The session cookie persists after the gateway restarts due to the `cookieConfig.lifetimeType: Permanent` setting. - 1. Restart the http gateway proxy. - ```sh - kubectl rollout restart deploy/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - 2. Verify that the gateway proxy pod is running. - ```sh - kubectl get po -n kgateway-system -l gateway.networking.k8s.io/gateway-name=http - ``` - Example output: - ``` - NAME READY STATUS RESTARTS AGE - http-7dd94b74-k26j6 3/3 Running 0 8s - ``` - 3. Get the new external address that is assigned to the gateway, or restart local port forwarding. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - {{% /tab %}} - {{< /tabs >}} - 4. Repeat the same request with the session cookie. Make sure to send this request within the 30 minute cookie validity period. - {{< tabs tabTotal="2" items="LoadBalancer IP address or hostname,Port-forward for local testing" >}} - {{% tab tabName="LoadBalancer IP address or hostname" %}} - ```sh - for i in {1..10}; do - curl -i -b cookie-jar -k http://$INGRESS_GW_ADDRESS:8080/headers \ - -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - for i in {1..10}; do - curl -i -b cookie-jar -k localhost:8080/headers \ - -H "host: www.example.com:8080"; done - ``` - {{% /tab %}} - {{< /tabs >}} - 5. Check the logs again of the httpbin instance that served the previous requests. Verify that your most recent request continued to be served by the same instance, even after the http gateway restarted. - ```sh - kubectl logs -n httpbin - ``` - - Example output for one pod, in which all 10 new requests (timestamps at `17:24`) are served after the previous 10 requests (timestamps at `17:20`): - ``` - ... - time="2025-07-16T17:20:40.7017" status=200 method="GET" uri="/headers" size_bytes=445 duration_ms=0.05 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:20:41.5744" status=200 method="GET" uri="/headers" size_bytes=515 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:24:06.5744" status=200 method="GET" uri="/headers" size_bytes=515 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:24:06.6013" status=200 method="GET" uri="/headers" size_bytes=515 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.244.0.7 - time="2025-07-16T17:24:06.631" status=200 method="GET" uri="/headers" size_bytes=515 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.244.0.7 - ... - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Scale the httpbin app back down. - ```sh - kubectl scale deployment httpbin -n httpbin --replicas=1 - ``` - -2. Remove the session persistence settings from the httpbin HTTPRoute. - ```yaml - kubectl apply -f- <}} - -## HTTP static backend {#http} - -1. Create a static Backend resource that routes requests to the [JSON testing API](http://jsonplaceholder.typicode.com/). - - ```yaml - kubectl apply -f- <}} - Do not specify a port in the `spec.backendRefs.port` field when referencing your Backend. The port is defined in your Backend resource and ignored if set on the HTTPRoute resource. - {{< /callout >}} - - ```yaml - kubectl apply -f- <}} - hostnames: - - static.example - rules: - - backendRefs: - - name: json-backend - kind: Backend - group: gateway.kgateway.dev - filters: - - type: URLRewrite - urlRewrite: - hostname: jsonplaceholder.typicode.com - EOF - ``` - -3. Send a request to your Backend and verify that you get back a 200 HTTP response code and a list of posts. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/posts -H "host: static.example:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/posts -H "host: static.example:8080" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```console - * Connected to (::1) port 8080 - > GET /posts HTTP/1.1 - > Host: static.example:8080 - > User-Agent: curl/8.7.1 - > Accept: */* - > - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - < - [ - { - "userId": 1, - "id": 1, - "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", - "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" - }, - { - "userId": 1, - "id": 2, - "title": "qui est esse", - "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" - }, - { - "userId": 1, - "id": 3, - "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut", - "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut" - }, - { - "userId": 1, - "id": 4, - "title": "eum et est occaecati", - "body": "ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit" - }, - ... - ``` - -## HTTPS static backend {#https} - -1. [Create an HTTPS listener for your Gateway]({{< link-hextra path="/setup/listeners/https/" >}}). - -2. Create a static Backend resource that routes requests to the [JSON testing API](https://jsonplaceholder.typicode.com/). - - ```yaml - kubectl apply -f- <}} - Do not specify a port in the `spec.backendRefs.port` field when referencing your Backend. The port is defined in your Backend resource and ignored if set on the HTTPRoute resource. - {{< /callout >}} - - ```yaml - kubectl apply -f- <}} - hostnames: - - static.example.com - rules: - - backendRefs: - - name: json-backend - kind: Backend - group: gateway.kgateway.dev - filters: - - type: URLRewrite - urlRewrite: - hostname: jsonplaceholder.typicode.com - EOF - ``` - -4. Set up a BackendConfigPolicy or BackendTLSPolicy, such as the following examples. This way, the Gateway can initiate a TLS connection to the secured backend. For more information, see the [Backend TLS]({{< link-hextra path="/security/backend-tls/" >}}) guide. - - {{< callout type="info" >}} - If you generated a self-signed certificate when setting up the HTTPS listener, make sure the certificate contains Subject Alternative Name (SAN) entries for the hostname you configured (for example, both `example.com` and `*.example.com` for wildcard coverage) and install the root certificate into your local trust store of your system or pass it to your client. For example, for a `curl` client, add the `--cacert example_certs/root.crt` option (update the path to match where you stored the certificate). - {{< /callout >}} - - {{< tabs tabTotal="2" items="BackendConfigPolicy, BackendTLSPolicy" >}} - {{% tab tabName="BackendConfigPolicy" %}} - ```yaml - kubectl apply -f- <}} - -5. Send a request to your Backend and verify that you get back a 200 HTTP response code and a list of posts. Note that you can remove the `--cacert example_certs/root.crt` if you stored the certificates in the local trust store of your system. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi --cacert example_certs/root.crt --resolve "static.example.com:443:${INGRESS_GW_ADDRESS}" https://static.example.com:443/posts - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi --cacert example_certs/root.crt --connect-to static.example.com:443:localhost:8443 https://static.example.com:443/posts - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```console - * Connecting to hostname: localhost - * Connecting to port: 8443 - * Host localhost:8443 was resolved. - * IPv6: ::1 - * IPv4: 127.0.0.1 - * Trying [::1]:8443... - * Connected to localhost (::1) port 8443 - * ALPN: curl offers h2,http/1.1 - * (304) (OUT), TLS handshake, Client hello (1): - * CAfile: example_certs/root.crt - * CApath: none - * (304) (IN), TLS handshake, Server hello (2): - * (304) (IN), TLS handshake, Unknown (8): - * (304) (IN), TLS handshake, Certificate (11): - * (304) (IN), TLS handshake, CERT verify (15): - * (304) (IN), TLS handshake, Finished (20): - * (304) (OUT), TLS handshake, Finished (20): - * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF - * ALPN: server did not agree on a protocol. Uses default. - * Server certificate: - * subject: CN=*.example.com; O=any domain - * start date: Oct 3 20:00:29 2025 GMT - * expire date: Oct 3 20:00:29 2026 GMT - * subjectAltName: host "static.example.com" matched cert's "*.example.com" - * issuer: O=any domain; CN=* - * SSL certificate verify ok. - * using HTTP/1.x - > GET /posts HTTP/1.1 - > Host: static.example.com - > User-Agent: curl/8.7.1 - > Accept: */* - > - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < date: Fri, 03 Oct 2025 20:16:33 GMT - date: Fri, 03 Oct 2025 20:16:33 GMT - < content-type: application/json; charset=utf-8 - content-type: application/json; charset=utf-8 - < access-control-allow-credentials: true - access-control-allow-credentials: true - < cache-control: max-age=43200 - cache-control: max-age=43200 - < etag: W/"6b80-Ybsq/K6GwwqrYkAsFxqDXGC7DoM" - etag: W/"6b80-Ybsq/K6GwwqrYkAsFxqDXGC7DoM" - < expires: -1 - expires: -1 - < nel: {"report_to":"heroku-nel","response_headers":["Via"],"max_age":3600,"success_fraction":0.01,"failure_fraction":0.1} - nel: {"report_to":"heroku-nel","response_headers":["Via"],"max_age":3600,"success_fraction":0.01,"failure_fraction":0.1} - < pragma: no-cache - pragma: no-cache - < report-to: {"group":"heroku-nel","endpoints":[{"url":"https://nel.heroku.com/reports?s=ES57MFYpcItNxqncxNgHKfLc4wJs5mHsrj1ja3lxILk%3D\u0026sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d\u0026ts=1756406957"}],"max_age":3600} - report-to: {"group":"heroku-nel","endpoints":[{"url":"https://nel.heroku.com/reports?s=ES57MFYpcItNxqncxNgHKfLc4wJs5mHsrj1ja3lxILk%3D\u0026sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d\u0026ts=1756406957"}],"max_age":3600} - < reporting-endpoints: heroku-nel="https://nel.heroku.com/reports?s=ES57MFYpcItNxqncxNgHKfLc4wJs5mHsrj1ja3lxILk%3D&sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d&ts=1756406957" - reporting-endpoints: heroku-nel="https://nel.heroku.com/reports?s=ES57MFYpcItNxqncxNgHKfLc4wJs5mHsrj1ja3lxILk%3D&sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d&ts=1756406957" - < server: envoy - server: envoy - < vary: Origin, Accept-Encoding - vary: Origin, Accept-Encoding - < via: 2.0 heroku-router - via: 2.0 heroku-router - < x-content-type-options: nosniff - x-content-type-options: nosniff - < x-powered-by: Express - x-powered-by: Express - < x-ratelimit-limit: 1000 - x-ratelimit-limit: 1000 - < x-ratelimit-remaining: 999 - x-ratelimit-remaining: 999 - < x-ratelimit-reset: 1756406983 - x-ratelimit-reset: 1756406983 - < age: 24922 - age: 24922 - < cf-cache-status: HIT - cf-cache-status: HIT - < cf-ray: 988f1e308c9f0a91-IAD - cf-ray: 988f1e308c9f0a91-IAD - < alt-svc: h3=":443"; ma=86400 - alt-svc: h3=":443"; ma=86400 - < x-envoy-upstream-service-time: 107 - x-envoy-upstream-service-time: 107 - < transfer-encoding: chunked - transfer-encoding: chunked - < - - [ - { - "userId": 1, - "id": 1, - "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", - "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" - }, - ... - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -{{< tabs tabTotal="2" items="HTTP,HTTPS">}} -{{% tab tabName="HTTP" %}} -```sh -kubectl delete httproute static-backend -kubectl delete backend json-backend -``` -{{% /tab %}} -{{% tab tabName="HTTPS" %}} -```sh -kubectl delete httproute static-backend -kubectl delete backendconfigpolicy static-tls-policy -kubectl delete backendtlspolicy static-tls-policy -kubectl delete backend json-backend -``` -{{% /tab %}} -{{< /tabs >}} \ No newline at end of file diff --git a/assets/docs/pages/traffic-management/traffic-split.md b/assets/docs/pages/traffic-management/traffic-split.md deleted file mode 100644 index ff331d17e..000000000 --- a/assets/docs/pages/traffic-management/traffic-split.md +++ /dev/null @@ -1,134 +0,0 @@ -Set up weight-based routing between multiple apps. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Deploy the Helloworld sample app - -To demonstrate weighted routing for multiple apps, deploy 3 versions of the Helloworld sample app. - -1. Create the helloworld namespace. - ```sh - kubectl create namespace helloworld - ``` - -2. Deploy the Hellworld sample apps. - ```sh - kubectl -n helloworld apply -f https://raw.githubusercontent.com/solo-io/gloo-edge-use-cases/main/docs/sample-apps/helloworld.yaml - ``` - - Example output: - ``` - service/helloworld-v1 created - service/helloworld-v2 created - service/helloworld-v3 created - deployment.apps/helloworld-v1 created - deployment.apps/helloworld-v2 created - deployment.apps/helloworld-v3 created - ``` - -3. Verify that the Helloworld pods are up and running. - ```sh - kubectl -n default get pods -n helloworld - ``` - - Example output: - ``` - NAME READY STATUS RESTARTS AGE - helloworld-v1-5c457458f-rfkc7 3/3 Running 0 30s - helloworld-v2-6594c54f6b-8dvjp 3/3 Running 0 29s - helloworld-v3-8576f76d87-czdll 3/3 Running 0 29s - ``` - -## Set up weighted routing - -1. Create an HTTPRoute resource for the `traffic.split.example` domain that routes 10% of the traffic to `helloworld-v1`, 10% to `helloworld-v2`, and 80% to `helloworld-v3`. - ```yaml - kubectl apply -f- <}} - hostnames: - - traffic.split.example - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - name: helloworld-v1 - port: 5000 - weight: 10 - - name: helloworld-v2 - port: 5000 - weight: 10 - - name: helloworld-v3 - port: 5000 - weight: 80 - EOF - ``` - - |Setting|Description| - |--|--| - |`spec.parentRefs.name`|The name and namespace of the gateway resource that serves the route. In this example, you use the gateway that you created when you set up the [Sample app]({{< link-hextra path="/install/sample-app#deploy-app/" >}}). | - |`spec.hostnames`| The hostname for which you want to apply traffic splitting.| - |`spec.rules.matches.path`|The path prefix to match on. In this example, `/` is used. | - |`spec.rules.backendRefs`| A list of services you want to forward traffic to. Use the `weight` option to define the amount of traffic that you want to forward to each service. | - -2. Verify that the HTTPRoute is applied successfully. - ```sh - kubectl get httproute/traffic-split -n helloworld -o yaml - ``` - -3. Send a few requests to the `/hello` path. Verify that you see responses from all 3 Helloworld apps, and that most responses are returned from `helloworld-v3`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - for i in {1..20}; do curl -i http://$INGRESS_GW_ADDRESS:8080/hello \ - -H "host: traffic.split.example:8080"; done - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - for i in {1..20}; do curl -i localhost:8080/hello \ - -H "host: traffic.split.example"; done - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ``` - HTTP/1.1 200 OK - server: envoy - date: Wed, 12 Mar 2025 20:59:35 GMT - content-type: text/html; charset=utf-8 - content-length: 60 - x-envoy-upstream-service-time: 110 - - Hello version: v3, instance: helloworld-v3-55bfdf76cf-nv545 - ``` - - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Remove the HTTP route resource. - ```sh - kubectl delete httproute traffic-split -n helloworld - ``` - -2. Remove the Helloworld apps. - ```sh - kubectl delete -n helloworld -f https://raw.githubusercontent.com/solo-io/gloo-edge-use-cases/main/docs/sample-apps/helloworld.yaml - ``` - - - diff --git a/assets/docs/pages/traffic-management/transformations/change-response-status.md b/assets/docs/pages/traffic-management/transformations/change-response-status.md deleted file mode 100644 index 177574043..000000000 --- a/assets/docs/pages/traffic-management/transformations/change-response-status.md +++ /dev/null @@ -1,153 +0,0 @@ -Update the response status based on headers being present in a response. - - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - - -## Change the response status - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource with your transformation rules. In this example, you change the value of the `:status` pseudo response header to 401 if the response header `foo:bar` is present. If the `foo:bar` response header is not present, you return a 403 HTTP response code. - - {{< tabs items="Envoy-based kgateway,Agentgateway" tabTotal="2" >}} - {{% tab tabName="Envoy-based kgateway" %}} - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - set: - - name: ":status" - value: '{% if header("foo") == "bar" %}401{% else %}403{% endif %}' - EOF - ``` - {{% /tab %}} - {{% tab tabName="Agentgateway" %}} - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - set: - - name: ":status" - value: 'request.uri.contains("foo=bar") ? 401 : 403' - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Send a request to the httpbin app and include the `foo:bar` query parameter. This query parameter automatically gets added as a response header and therefore triggers the transformation rule that you set up. Verify that you get back a 401 HTTP response code. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers?foo=bar \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi "localhost:8080/response-headers?foo=bar" \ - -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[1,2,20,21]} - < HTTP/1.1 401 Unauthorized - HTTP/1.1 401 Unauthorized - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-type: application/json; encoding=utf-8 - content-type: application/json; encoding=utf-8 - < foo: bar - foo: bar - < content-length: 29 - content-length: 29 - < x-envoy-upstream-service-time: 4 - x-envoy-upstream-service-time: 4 - < server: envoy - server: envoy - < - - { - "foo": [ - "bar" - ] - } - ``` - -3. Send another request to the httpbin app. This time, you include the `foo:baz` query parameter. Verify that you get back a 403 HTTP response code. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers?foo=baz \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi "localhost:8080/response-headers?foo=baz" \ - -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[1,2,20,21]} - < HTTP/1.1 403 Forbidden - HTTP/1.1 403 Forbidden - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-type: application/json; encoding=utf-8 - content-type: application/json; encoding=utf-8 - < foo: bar - foo: bar - < content-length: 29 - content-length: 29 - < x-envoy-upstream-service-time: 4 - x-envoy-upstream-service-time: 4 - < server: envoy - server: envoy - < - - { - "foo": [ - "baz" - ] - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin -``` - diff --git a/assets/docs/pages/traffic-management/transformations/decode-base64-headers.md b/assets/docs/pages/traffic-management/transformations/decode-base64-headers.md deleted file mode 100644 index 92cf55228..000000000 --- a/assets/docs/pages/traffic-management/transformations/decode-base64-headers.md +++ /dev/null @@ -1,122 +0,0 @@ -Combine multiple Inja functions to accomplish the following tasks: - -- Extract a base64-encoded value from a specific request header. -- Decode the base64-encoded value. -- Trim the decoded value and only capture everything starting from the 11th character. -- Add the captured string as a response header. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Decode base64 headers - -1. Encode a string to base64. - ```sh - echo -n "transformation test" | base64 - ``` - - Example output: - ``` - dHJhbnNmb3JtYXRpb24gdGVzdA== - ``` - -2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource with your transformation rules. Make sure to create the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}in the same namespace as the HTTPRoute resource. In the following example, you decode the base64-encoded value from the `x-base64-encoded` request header and populate the decoded value into an `x-base64-decoded` header starting from the 11th character. - - {{< tabs items="Envoy-based kgateway,Agentgateway" tabTotal="2" >}} - {{% tab tabName="Envoy-based kgateway" %}} - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - add: - - name: x-base64-decoded - value: '{{ substring(base64_decode(request_header("x-base64-encoded")), 11) }}' - EOF - ``` - {{% /tab %}} - {{% tab tabName="Agentgateway" %}} - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - add: - - name: x-base64-decoded - value: 'string(base64_decode(request.headers["x-base64-encoded"])).substring(11)' - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -3. Send a request to the httpbin app and include your base64-encoded string in the `x-base64-encoded` request header. Verify that you get back a 200 HTTP response code and that you see the trimmed decoded value of your base64-encoded string in the `x-base64-decoded` response header. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers \ - -H "host: www.example.com:8080" \ - -H "x-base64-encoded: dHJhbnNmb3JtYXRpb24gdGVzdA==" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/response-headers \ - -H "host: www.example.com" \ - -H "x-base64-encoded: dHJhbnNmb3JtYXRpb24gdGVzdA==" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[20,21]} - * Mark bundle as not supporting multiuse - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-type: application/json; encoding=utf-8 - content-type: application/json; encoding=utf-8 - < date: Wed, 26 Jun 2024 02:54:48 GMT - date: Wed, 26 Jun 2024 02:54:48 GMT - < content-length: 3 - content-length: 3 - < x-envoy-upstream-service-time: 2 - x-envoy-upstream-service-time: 2 - < server: envoy - server: envoy - < x-envoy-decorator-operation: httpbin.httpbin.svc.cluster.local:8000/* - x-envoy-decorator-operation: httpbin.httpbin.svc.cluster.local:8000/* - < x-base64-decoded: ion test - x-base64-decoded: ion test - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin -``` - diff --git a/assets/docs/pages/traffic-management/transformations/inject-response-headers.md b/assets/docs/pages/traffic-management/transformations/inject-response-headers.md deleted file mode 100644 index 4927ee832..000000000 --- a/assets/docs/pages/traffic-management/transformations/inject-response-headers.md +++ /dev/null @@ -1,144 +0,0 @@ -Use an Inja template to extract a value from a request header and add it as a header to your responses. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Inject response headers - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource with the folloing transformation rules: - * `x-gateway-response`: Use the value from the `x-gateway-request` request header and populate the value of that header into an `x-gateway-response` response header. - * `x-podname`: Retrieve the value of the `POD_NAME` environment variable and add the value to the `x-podname` response header. Because the transformation is processed in the gateway proxy, these environment variables refer to the variables that are set on the proxy. You can view supported environment variables when you run `kubectl get deployment http -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml and look at the `spec.containers.env` section. - * `x-season`: Adds a static string value of `summer` to the `x-season` response header. - * `x-response-raw`: Adds a static string values of `hello` with all escape characters intact. - * `x-replace`: Replaces the pattern-to-replace text in the `baz` header with a random string. - - {{< tabs items="Envoy-based kgateway,Agentgateway" tabTotal="2" >}} - {{% tab tabName="Envoy-based kgateway" %}} - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - set: - - name: x-gateway-response - value: '{{ request_header("x-gateway-request") }}' - - name: x-podname - value: '{{ env("POD_NAME") }}' - - name: x-season - value: 'summer' - - name: x-response-raw - value: '{{ raw_string("hello") }}' - - name: x-replace - value: '{{ replace_with_random(request_header("baz"), "pattern-to-replace") }}' - EOF - ``` - {{% /tab %}} - {{% tab tabName="Agentgateway" %}} - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - set: - - name: x-gateway-response - value: 'request.headers["x-gateway-request"]' - - name: x-podname - value: 'request.headers["x-pod-name"]' - - name: x-season - value: '"summer"' - - name: x-response-raw - value: '"hello"' - - name: x-replace - value: 'request.headers["baz"].replace("pattern-to-replace", string(random()))' - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Send a request to the httpbin app and include the `x-gateway-request` and `baz` request headers. Verify that you get back a 200 HTTP response code and that the following response headers are included: - * `x-podname` that is set to the name of the gateway proxy pod. - * `x-season` that is set to `summer`. - * `x-gateway-response` that is set to the value of the `x-gateway-request` request header. - * `x-response-raw` that is set to `hello`. - * `x-replace` that is set to a random string. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/response-headers \ - -H "host: www.example.com:8080" \ - -H "x-gateway-request: my custom request header" \ - -H "baz: pattern-to-replace" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/response-headers \ - -H "host: www.example.com" \ - -H "x-gateway-request: my custom request header" \ - -H "baz: pattern-to-replace" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```console {hl_lines=[3,4,20,21,22,23,24,25,26,27,28,29]} - ... - * Request completely sent off - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - < access-control-allow-credentials: true - access-control-allow-credentials: true - < access-control-allow-origin: * - access-control-allow-origin: * - < content-type: application/json; encoding=utf-8 - content-type: application/json; encoding=utf-8 - < content-length: 3 - content-length: 3 - < x-envoy-upstream-service-time: 2 - x-envoy-upstream-service-time: 2 - < server: envoy - server: envoy - < x-envoy-decorator-operation: httpbin.httpbin.svc.cluster.local:8000/* - x-envoy-decorator-operation: httpbin.httpbin.svc.cluster.local:8000/* - < x-envoy-upstream-service-time: 1 - < x-podname: http-85d5775587-tkxmt - x-podname: http-85d5775587-tkxmt - < x-replace: zljPMhO86gJCFc69jZ0+kQ - x-replace: zljPMhO86gJCFc69jZ0+kQ - < x-response-raw: hello - x-response-raw: hello - < x-gateway-response: my custom request header - x-gateway-response: my custom request header - < x-season: summer - x-season: summer - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin -``` - diff --git a/assets/docs/pages/traffic-management/transformations/redirect-url.md b/assets/docs/pages/traffic-management/transformations/redirect-url.md deleted file mode 100644 index 7bb3591e0..000000000 --- a/assets/docs/pages/traffic-management/transformations/redirect-url.md +++ /dev/null @@ -1,165 +0,0 @@ -Extract the values of common headers to generate a redirect URL. - - - - - -## About pseudo headers - -Pseudo headers are special headers that are used in HTTP/2 to provide metadata about the request or response in a structured way. Although they look like traditional HTTP/1.x headers, they come with specific characteristics: - -* Must always start with a colon (`:`). -* Must appear before regular headers in the HTTP/2 frame. -* Contain details about the request or response. - -Common pseudo headers include: -* `:method`: The HTTP method that is used, such as GET or POST. -* `:scheme`: The protocol that is used, such as http or https. -* `:authority`: The hostname and port number that the request is sent to. -* `:path`: The path of the request. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Set up redirect URLs - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource with the following transformation rules: - * Build a redirect URL with the values of the `:authority` and `:path` pseudo headers. These headers are extracted from the request with the `request_header` function that is provided in {{< reuse "agw-docs/snippets/kgateway.md" >}}. - * The `:authority` pseudo header contains the hostname that the request is sent to. - * The `:path` pseudo header is set to the request path. - * The redirect URL is added to the `x-forwarded-uri` response header. - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - request: - add: - - name: x-forwarded-uri - value: 'https://{{ request_header(":authority") }}{{ request_header(":path") }}' - EOF - ``` - -2. Send a request to the httpbin app. Verify that you get back a 200 HTTP response code and that you see the redirect URL in the `x-forwarded-uri` response header. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/get \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/get \ - -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[2,3,30,31]} - ... - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com:8080" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Envoy-External-Address": [ - "10.0.9.76" - ], - "X-Forwarded-For": [ - "10.0.9.76" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Forwarded-Uri": [ - "https://www.example.com:8080/get" - ], - "X-Request-Id": [ - "55140fab-c68e-44d3-a4fc-7f6242ba8194" - ] - }, - "origin": "10.0.9.76", - "url": "http://www.example.com:8080/get" - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin -``` - diff --git a/assets/docs/pages/traffic-management/transformations/templating-language.md b/assets/docs/pages/traffic-management/transformations/templating-language.md deleted file mode 100644 index 471589a15..000000000 --- a/assets/docs/pages/traffic-management/transformations/templating-language.md +++ /dev/null @@ -1,32 +0,0 @@ -The data plane proxy of your Gateway determines the templating language that you use to express transformations. - - - -{{< icon "agentgateway" >}} Common Expression Language (CEL) for {{< reuse "agw-docs/snippets/agentgateway.md" >}} - -## CEL for Agentgateway {#cel} - -{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} transformation templates are written in Common Expression Language (CEL). CEL is a fast, portable, and safely executable language that goes beyond declarative configurations. CEL lets you develop more complex expressions in a readable, developer-friendly syntax. - -To learn more about how to use CEL, refer to the following resources: - -* [cel.dev tutorial](https://cel.dev/tutorials/cel-get-started-tutorial) -* [Agentgateway reference docs](https://agentgateway.dev/docs/reference/cel/) - -### Log CEL variables in agentgateway {#cel-log} - -You can log the full context of the CEL variables by [upgrading your Helm installation settings]({{< link-hextra path="/operations/upgrade/">}}), such as the following example: - -```yaml -agentgateway: - config: - logging: - fields: - add: - cel: variables() - enabled: true -``` - - - - diff --git a/assets/docs/pages/traffic-management/transformations/update-request-path.md b/assets/docs/pages/traffic-management/transformations/update-request-path.md deleted file mode 100644 index 1299eaf2c..000000000 --- a/assets/docs/pages/traffic-management/transformations/update-request-path.md +++ /dev/null @@ -1,204 +0,0 @@ -Change the request path and HTTP method when a request header is present. To update the path and HTTP method the `:path` and `:method` pseudo headers are used. - -## About pseudo headers - -Pseudo headers are special headers that are used in HTTP/2 to provide metadata about the request or response in a structured way. Although they look like traditional HTTP/1.x headers, they come with specific characteristics: - -* Must always start with a colon (`:`). -* Must appear before regular headers in the HTTP/2 frame. -* Contain details about the request or response. - -Common pseudo headers include: -* `:method`: The HTTP method that is used, such as GET or POST. -* `:scheme`: The protocol that is used, such as http or https. -* `:authority`: The hostname and port number that the request is sent to. -* `:path`: The path of the request. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Update request paths and HTTP methods - -1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource with the following transformation rules: - * If the request contains the `foo:bar` header, the request path is rewritten to the `/post` path. In addition, the HTTP method is changed to the `POST` method. - * If the request does not contain the `foo:bar` header, the request path and method do not change. - - {{< tabs items="Envoy-based kgateway,Agentgateway" tabTotal="2" >}} - {{% tab tabName="Envoy-based kgateway" %}} - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - request: - set: - - name: ":path" - value: '{% if request_header("foo") == "bar" %}/post{% else %}{{ header(":path") }}{% endif %}' - - name: ":method" - value: '{% if request_header("foo") == "bar" %}POST{% else %}{{ request_header(":method")}}{% endif %}' - EOF - ``` - {{% /tab %}} - {{% tab tabName="Agentgateway" %}} - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - request: - set: - - name: ":path" - value: 'request.headers["foo"] == "bar" ? "/post" : request.path' - - name: ":method" - value: 'request.headers["foo"] == "bar" ? "POST" : request.method' - EOF - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Send a request to the `/get` endpoint of the httpbin app. Include the `foo: bar` request header to trigger the request transformation. Verify that you get back a 200 HTTP response code and that your request path is rewritten to the `/post` endpoint. The `/post` endpoint accepts requests only if the HTTP `POST` method is used. The 200 HTTP response code therefore also indicates that the HTTP method was successfully changed from `GET` to `POST`. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/get \ - -H "foo: bar" \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/get \ - -H "foo: bar" \ - -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[1,2,39]} - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Content-Length": [ - "0" - ], - "Foo": [ - "bar" - ], - "Host": [ - "www.example.com:8080" - ], - "User-Agent": [ - "curl/7.77.0" - ], - "X-B3-Sampled": [ - "0" - ], - "X-B3-Spanid": [ - "5f36d131289dba78" - ], - "X-B3-Traceid": [ - "590047a63783206e5f36d131289dba78" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "6b7debde-6a8a-4d9e-90a4-33a9a35937d3" - ] - }, - "origin": "127.0.0.6:48539", - "url": "http://www.example.com:8080/post", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -3. Send another request to the `/get` endpoint of the httpbin app. This time, you omit the `foo: bar` header. Verify that you get back a 200 HTTP response code and that the request path is not rewritten to the `/post` endpoint. The `/get` endpoint accepts requests only if the HTTP GET method is used. A 200 HTTP response code therefore also verifies that the HTTP method was not changed. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/get \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/get \ - -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[1,2,34]} - < HTTP/1.1 200 OK - HTTP/1.1 200 OK - ... - - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com:8080" - ], - "User-Agent": [ - "curl/7.77.0" - ], - "X-B3-Sampled": [ - "0" - ], - "X-B3-Spanid": [ - "a83c35458cc4a47b" - ], - "X-B3-Traceid": [ - "bf14b3d3098cd639a83c35458cc4a47b" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "b91ecfcf-4f79-4b65-9727-09aafcaeb40e" - ] - }, - "origin": "127.0.0.6:46209", - "url": "http://www.example.com:8080/get" - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin -``` - diff --git a/assets/docs/pages/traffic-management/transformations/update-response-body.md b/assets/docs/pages/traffic-management/transformations/update-response-body.md deleted file mode 100644 index 560c5b951..000000000 --- a/assets/docs/pages/traffic-management/transformations/update-response-body.md +++ /dev/null @@ -1,173 +0,0 @@ -Learn how to return a customized response body and how replace specific values in the body. - -In this guide, you use the following methods to transform a JSON body: - -* Directly access fields in the JSON body and inject them into a custom JSON body. -* Use the `replace_with_random` Inja function to replace specific patterns in the JSON body. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Update response body - -1. Send a request to the `json` endpoint of the httpbin app. The request returns a JSON body that you later transform. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/json \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/json \ - -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console - { - "slideshow": { - "author": "Yours Truly", - "date": "date of publication", - "slides": [ - { - "title": "Wake up to WonderWidgets!", - "type": "all" - }, - { - "items": [ - "Why WonderWidgets are great", - "Who buys WonderWidgets" - ], - "title": "Overview", - "type": "all" - } - ], - "title": "Sample Slide Show" - } - } - ``` - -2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource with your transformation rules: - * A new body is created in the response with the values of the `author`, `title`, and `slides` fields. - * To extract the values, you use dot notation. Because the response is parsed as a JSON file, no extractors need to be defined. Instead, you can access the fields directly. - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - body: - parseAs: AsJson - value: '{"author": "{{ slideshow.author }}", "title": "{{ slideshow.title }}", "slides": "{{ slideshow.slides }}}' - EOF - ``` - -3. Send a request to the `json` endpoint of the httpbin app again. Verify that you see the transformed response body. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/json \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/json \ - -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console - {"author": "Yours Truly", "title": "Sample Slide Show", "slides": - "[{"title":"Wake up to WonderWidgets!","type":"all"},{"items": - ["Why WonderWidgets are great","Who buys WonderWidgets"], - "title":"Overview","type":"all"}]} - ``` - -4. Update the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to replace the `all` pattern with a random string. - - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - body: - parseAs: AsJson - value: '{{ replace_with_random(body(), "all") }}' - EOF - ``` - -5. Send another request to the `json` endpoint of the httpbin app. Verify that every `all` value is replaced with a random string. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vi http://$INGRESS_GW_ADDRESS:8080/json \ - -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vi localhost:8080/json \ - -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - ```console {hl_lines=[8,16]} - { - "slideshow": { - "author": "Yours Truly", - "date": "date of publication", - "slides": [ - { - "title": "Wake up to WonderWidgets!", - "type": "5pESMzYNtg8W9AG/eVZ13A" - }, - { - "items": [ - "Why WonderWidgets are great", - "Who buys WonderWidgets" - ], - "title": "Overview", - "type": "5pESMzYNtg8W9AG/eVZ13A" - } - ], - "title": "Sample Slide Show" - } - } - ``` - -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -```sh -kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin -``` - diff --git a/assets/docs/pages/traffic-management/weighted-routes.md b/assets/docs/pages/traffic-management/weighted-routes.md deleted file mode 100644 index 11aff05ee..000000000 --- a/assets/docs/pages/traffic-management/weighted-routes.md +++ /dev/null @@ -1,407 +0,0 @@ -By default, the Kubernetes Gateway API sorts HTTPRoute rules based on their order and specificity, as defined in the [Gateway API docs](https://gateway-api.sigs.k8s.io/reference/spec/#httprouterule). When a route matches a request, no further routes are evaluated for matching, which might affect the gateway's routing decision and the policies that are applied to the traffic. With {{< reuse "/agw-docs/snippets/kgateway.md" >}}, you can configure weights for more fine-grained control over your routing rules. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} - -## Step 1: Review the default routing behavior {#default-routing} - -By default, the Kubernetes Gateway API sorts HTTPRoute rules as defined in the [Gateway API docs](https://gateway-api.sigs.k8s.io/reference/spec/#httprouterule). - -1. Specificity of the route matching rule, such as a header match with largest number of matching headers. -2. Oldest route based on creation timestamp. -3. Alphabetical order of the route based on the `namespace/name` of the route. -4. Order of the route in the list of the HTTPRoute resource. - -Review route precedence in action: - -1. Deploy a hello-world app to demonstrate different backend responses. - - ```yaml - kubectl apply -f- <}} - hostnames: - - "www.example.com" - rules: - - matches: - - path: - type: PathPrefix - value: /anything - backendRefs: - - name: httpbin - port: 8000 - - matches: - - path: - type: PathPrefix - value: /anything/a - backendRefs: - - name: hello-world - port: 80 - EOF - ``` - -3. Send a request to the `/anything/a` path. The request matches both the rules for `/anything` and `/anything/a`. Because the more specific `/anything/a` rule takes precedence, the request routes to the hello-world service instead of the httpbin service. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/a -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - curl -i localhost:8080/anything/a -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output from the hello-world service: - - ```txt - HTTP/1.1 200 OK - server: envoy - date: Tue, 29 Jul 2025 20:07:36 GMT - content-type: text/plain - content-length: 167 - expires: Tue, 29 Jul 2025 20:07:35 GMT - cache-control: no-cache - x-envoy-upstream-service-time: 0 - - Server address: 10.244.0.8:80 - Server name: hello-world-669dfbd799-g4jkg - Date: 29/Jul/2025:20:07:36 +0000 - URI: /anything/a - Request ID: 796644ce8bda8ae5ecc36c5f4117a590 - ``` - -4. Send a request to the `/anything` path. This example routes to the httpbin service because it only matches the less specific rule. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - curl -i localhost:8080/anything -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output from the httpbin service: - - ```txt - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Tue, 29 Jul 2025 20:08:21 GMT - content-length: 587 - x-envoy-upstream-service-time: 1 - server: envoy - ``` - ```json - { - "args": {}, - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Envoy-External-Address": [ - "127.0.0.1" - ], - "X-Forwarded-For": [ - "10.244.0.7" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "7ec1f5f7-72b7-4053-b2e4-0117a2438d4c" - ] - }, - "origin": "10.244.0.7", - "url": "http://www.example.com/anything", - "data": "", - "files": null, - "form": null, - "json": null - } - ``` - -## Step 2: Enable weighted route precedence {#enable-weighted-route-precedence} - -By default, weighted routes are disabled. Upgrade your {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm installation to enable the feature. - -1. Get the Helm values for your current Helm installation. - ```sh - helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - ``` - -2. Add the following values to the Helm values file to enable the weighted routes feature in {{< reuse "/agw-docs/snippets/kgateway.md" >}}. - ```yaml - - controller: - extraEnv: - KGW_WEIGHTED_ROUTE_PRECEDENCE: true - ``` - -3. Upgrade your Helm installation. Replace the `--version {{< reuse "/agw-docs/versions/helm-version-flag.md" >}}` option to match your current version. - - ```sh - helm upgrade -i --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} --version {{< reuse "/agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml - ``` - -## Step 3: Add weights to routes {#weight-routes} - -Apply an annotation at the HTTPRoute level that sets a weight for the route, which can be any 32-bit integer, including negative numbers. HTTPRoutes without the annotation are given a weight of `0`. Routes are sorted as follows: - -1. In descending order by weight, from highest to lowest. -2. By [Gateway API route precedence](https://gateway-api.sigs.k8s.io/reference/spec/#httprouterule) for routes with the same weight. - -{{< callout type="info" >}} -Using route delegation? Make sure to add the `kgateway.dev/route-weight` annotation to the child HTTPRoute that you want to weight. Children **do not** inherit the weight of their parent HTTPRoute. -{{< /callout >}} - -Steps to weight routes: - -1. Create separate HTTPRoutes for the `/anything` and `/anything/a` paths. - - ```yaml - kubectl apply -f- <}} - hostnames: - - "www.example.com" - rules: - - matches: - - path: - type: PathPrefix - value: /anything - backendRefs: - - name: httpbin - port: 8000 - --- - apiVersion: gateway.networking.k8s.io/v1 - kind: HTTPRoute - metadata: - name: hello-world-a - namespace: httpbin - spec: - parentRefs: - - name: http - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - hostnames: - - "www.example.com" - rules: - - matches: - - path: - type: PathPrefix - value: /anything/a - backendRefs: - - name: hello-world - port: 80 - EOF - ``` - -2. Send a request to the httpbin app on the `/anything/a` path. Because the default Gateway API sorting rules give precedence to the more specific `/anything/a` route, the request is served by the hello-world service instead of the httpbin service. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/a -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - curl -i localhost:8080/anything/a -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```txt - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Thu, 13 Feb 2025 18:49:32 GMT - content-length: 330 - x-envoy-upstream-service-time: 4 - server: envoy - ``` - ```txt - Server address: 10.244.0.8:80 - Server name: hello-world-669dfbd799-g4jkg - Date: 29/Jul/2025:20:19:01 +0000 - URI: /anything/a - Request ID: dbfe6dd762fc25ae7297f2ef881ae30b - ``` - -3. Add a weight of `10` to the HTTPRoute with the matching rule for the `/anything` path that is served by the httpbin service, and a weight of `1` to the HTTPRoute with the matching rule for the `/anything/a` path that is served by the hello-world service. - - ```yaml - kubectl annotate httproute -n httpbin httpbin kgateway.dev/route-weight=10 - kubectl annotate httproute -n httpbin hello-world-a kgateway.dev/route-weight=1 - ``` - -4. Send another request on the `/anything/a` path. Because the weight of the httpbin HTTPRoute is higher than the hello-world route, the request is served by the httpbin service instead of the hello-world service. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -i http://$INGRESS_GW_ADDRESS:8080/anything/a -H "host: www.example.com:8080" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing"%}} - ```sh - curl -i localhost:8080/anything/a -H "host: www.example.com" - ``` - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```txt - HTTP/1.1 200 OK - access-control-allow-credentials: true - access-control-allow-origin: * - content-type: application/json; encoding=utf-8 - date: Thu, 13 Feb 2025 18:49:32 GMT - content-length: 330 - x-envoy-upstream-service-time: 4 - server: envoy - ``` - ```json - { - "headers": { - "Accept": [ - "*/*" - ], - "Host": [ - "www.example.com" - ], - "User-Agent": [ - "curl/8.7.1" - ], - "X-Envoy-Expected-Rq-Timeout-Ms": [ - "15000" - ], - "X-Forwarded-Proto": [ - "http" - ], - "X-Request-Id": [ - "26be0bcd-d941-48f4-ac3b-d5ac288ac46f" - ] - } - } - ``` - -## More resources - -For more examples of weighted routes, review the following examples from the kgateway GitHub repository. - -{{< cards >}} - {{< card link="https://github.com/kgateway-dev/kgateway/blob/main/pkg/kgateway/translator/gateway/testutils/inputs/route-sort-weighted.yaml" title="Weighted route input" icon="external-link" >}} - {{< card link="https://github.com/kgateway-dev/kgateway/blob/main/pkg/kgateway/translator/gateway/testutils/outputs/route-sort-weighted.yaml" title="Weighted route output" icon="external-link" >}} -{{< /cards >}} - -## Cleanup {#cleanup} - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the extra hello-world app that you created for this tutorial. - - ```sh - kubectl delete deployment -n httpbin hello-world - kubectl delete service -n httpbin hello-world - kubectl delete httproute -n httpbin hello-world-a - ``` - -2. Restore the sample httpbin HTTPRoute. - - ```yaml - kubectl apply -f- <}} - hostnames: - - "www.example.com" - rules: - - backendRefs: - - name: httpbin - port: 8000 - EOF - ``` diff --git a/assets/docs/snippets/about-agw.md b/assets/docs/snippets/about-agw.md deleted file mode 100644 index 58e9bdee2..000000000 --- a/assets/docs/snippets/about-agw.md +++ /dev/null @@ -1 +0,0 @@ -Agentgateway is an opensource LLM, MCP, and A2A gateway hosted [as part of the Linux Foundation](https://www.linuxfoundation.org/press/linux-foundation-welcomes-agentgateway-project-to-accelerate-ai-agent-adoption-while-maintaining-security-observability-and-governance). It focuses on implementing the missing pieces [not found in traditional API gateways](https://www.solo.io/blog/why-do-we-need-a-new-gateway-for-ai-agents) to support MCP and Agent workloads. The project emphasizes enterprise-grade security, observability, resiliency, reliability, and multi-tenancy features. Agentgateway is built to be the most performant, reliable, and mature LLM/MCP gateway on the market. \ No newline at end of file diff --git a/assets/docs/snippets/about-llm.md b/assets/docs/snippets/about-llm.md deleted file mode 100644 index 8e3de868e..000000000 --- a/assets/docs/snippets/about-llm.md +++ /dev/null @@ -1,20 +0,0 @@ -## What is an LLM? - -Large Language Models (LLMs) are very large, deep learning models that are pre-trained on massive amounts of unlabeled and self-supervised data, often containing billions of words. LLMs extract meanings from a sequence of text and can understand the relationship between words and phrases in it. Based on this understanding, the LLM can then predict and generate natural language, and perform related tasks, such as answering questions, summarizing text, translating between languages, or writing content. LLMs can be fine-tuned on a smaller, more specific data set so that it can perform a more specific task more accurately. - -While LLMs were originally designed to be trained on text and natural language, they are now becoming multimodal, supporting different media types, such as images and videos. - -## Common problems with LLM consumption - -When adopting an LLM on an enterprise-level, you typically run into the following issues: - -* **Data leakage and privacy**: When interacting with LLMs, it is essential to comply with federal laws and to not leak any PII (personally identifiable information) or other sensitive information in prompts. For example, users might enter personal credit card or customer related information, such as account numbers and names. Attackers might also trick the model into revealing previous user data that is still stored in the context. To prevent sensitive information from leaking to the LLM provider, prompt guards must be in place that help to filter, block, monitor, and control LLM inputs and outputs to find offensive content, prevent misuse, and ensure ethical and responsible AI usage. - -* **Cost controls**: Compared to traditional APIs, LLM queries are long-running, meaning the LLM must parse through its large data set iteratively to compute one token at a time. All tokens must then be summarized to generate a prediction. Given the large amounts of data that the LLM parses, GPUs are required to run LLMs efficently, which are costly to run and maintain. Limiting the amount of tokens that can be used and monitoring token consumption are critical to keep costs to a minimum. - -* **Fan-out patterns**: LLMs are limited by static training data. This limitation can make seemingly simple questions difficult to answer. For example, answering a simple question, such as `What is the weather today?` requires the LLM to have access to several real-time information, such as the location, time, and weather forecast. Integrating LLMs with other MCP servers and agents to perform these tasks becomes essential to accurately answer questions of this nature. - -* **Security**: To protect your LLM from being consumed by unauthorized users, you typically want to authenticate with the LLM before you start sending requests. Managing credentials, such as API keys, and monitoring the traffic to the LLM becomes essential to protect access to the LLM. - -* **Scalability and reliability**: When relying on an LLM to perform specific tasks in your environment, you must put measures in place that prevent your applications from failing, being overwhelmed, or performing inefficiently. This includes retries and timeouts, request rate limiting, and multi-model failovers. - diff --git a/assets/docs/snippets/about-mcp-a2a.md b/assets/docs/snippets/about-mcp-a2a.md deleted file mode 100644 index 76f6aafcc..000000000 --- a/assets/docs/snippets/about-mcp-a2a.md +++ /dev/null @@ -1,3 +0,0 @@ -With agentic artificial intelligence (AI) changing the way organizations build and deliver applications, organizations face the challenge of rapidly adopting new technologies and interoperability protocols to connect agents and tools in fragmented environments. Because AI agents and tools can be built with different frameworks, and access different APIs and data sources, standardizing the way agents and tools communicate with each other is essential to further accelerate agent development. - -[Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) and [Agent-to-Agent (A2A)](https://github.com/a2aproject/A2A) are the leading protocols for enabling communication between agents and tools. MCP helps to retrieve and exchange context with Large Language Models (LLMs) and connect LLMs to tools. On the other hand, A2A solves for long-running tasks and state management across multiple agents. MCP and A2A are both JSON-RPC protocols that define the structure of how an agent describes what it wants to do, how it calls tools, and how it hands off tasks to other agents. \ No newline at end of file diff --git a/assets/docs/snippets/about-mcp-challenges.md b/assets/docs/snippets/about-mcp-challenges.md deleted file mode 100644 index a64d7b78c..000000000 --- a/assets/docs/snippets/about-mcp-challenges.md +++ /dev/null @@ -1,11 +0,0 @@ -While MCP and A2A define the RPC communication protocol for agents and tools, they currently do not address real-world, enterprise-level concerns. - -Agents typically do not operate in isolation. Instead, they interact with each other (agent-to-agent), with internal systems (agent-to-tool), and external or foundational models (agent-to-LLM). These interactions are often dynamic, multi-modal, and span organizational and data boundaries. - -Such long-lived interactivity creates new vectors for risk and complexity, including: -* **Security**: How to handle authentication, authorization, and auditing of agent interactions across tools and services? -* **Governance**: How to enforce policies across autonomous workflows, such as data residency or access control? -* **Observability**: How to gain visibility into what agents are doing, when, and why? -* **Scalability and performance**: How to ensure low latency while securely handling retries, timeouts, and failures? - -Agentgateway is designed to tackle these challenges at its core with built-in security, governance, and observability for all MCP and A2A communication between agents, tools, and LLMs. \ No newline at end of file diff --git a/assets/docs/snippets/about-traditional-gw.md b/assets/docs/snippets/about-traditional-gw.md deleted file mode 100644 index b5057f857..000000000 --- a/assets/docs/snippets/about-traditional-gw.md +++ /dev/null @@ -1,7 +0,0 @@ -Traditional API gateways, reverse proxies and AI gateways, such as Envoy, were built and optimized for RESTful microservices architectures where the gateway receives short-lived HTTP requests from a client, decides on a backend, and forwards the request to that backend. Typically, no session context or ongoing connection state is required in these cases. - -MCP, by contrast, is a stateful protocol based on JSON-RPC with its own semantics for how to retrieve and exchange context with LLMs. MCP clients and servers must maintain long-lived sessions where requests and responses are sent constantly. Every request and response must be tied to the same session context. In addition, MCP servers can initiate messages back to the client asynchronously, which makes keeping track of all stateful sessions challenging. - -A single client request, such as to list all available tools, might require the proxy to access multiple backend MCP servers, aggregate the responses, and return a single coherent result. In addition, clients might not have access to all the tools that are available on the server. The proxy must be capable to dynamically adjust its responses on a per-session basis and map each client session to the backend servers it is allowed to access. - -Traditional gateways were not designed and built to support the session and message awareness that is required to properly handle stateful, session-based, and bidirectional communications. In addition, these communication patterns are very resource intensive and can quicky overwhelm traditional gateways leading to performance impacts or even failure. Without major re-architecture, traditional gateways cannot support the rise of agentic AI use cases. \ No newline at end of file diff --git a/assets/docs/snippets/agentgateway-capital.md b/assets/docs/snippets/agentgateway-capital.md deleted file mode 100644 index cc2b35af9..000000000 --- a/assets/docs/snippets/agentgateway-capital.md +++ /dev/null @@ -1 +0,0 @@ -Agentgateway \ No newline at end of file diff --git a/assets/docs/snippets/agentgateway-prereq.md b/assets/docs/snippets/agentgateway-prereq.md deleted file mode 100644 index 45bc359eb..000000000 --- a/assets/docs/snippets/agentgateway-prereq.md +++ /dev/null @@ -1 +0,0 @@ -[Install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane]({{< link-hextra path="/quickstart/" >}}). diff --git a/assets/docs/snippets/agentgateway-setup.md b/assets/docs/snippets/agentgateway-setup.md deleted file mode 100644 index 3771b230f..000000000 --- a/assets/docs/snippets/agentgateway-setup.md +++ /dev/null @@ -1,64 +0,0 @@ -1. Create a Gateway that uses the `{{< reuse "agw-docs/snippets/agw-gatewayclass.md" >}}` GatewayClass. The following example sets up a Gateway that uses the [default agentgateway proxy template](https://github.com/kgateway-dev/kgateway/blob/main/pkg/kgateway/helm/agentgateway/templates/deployment.yaml). - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "agw-docs/snippets/agw-gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 80 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -2. Verify that the agentgateway proxy is created. - - * Gateway: Note that it might take a few minutes for an address to be assigned. - * Pod for `agentgateway-proxy`: The pod has one container: `agent-gateway`. - - ```sh - kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} - kubectl get deployment agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ``` - NAME CLASS ADDRESS PROGRAMMED AGE - agentgateway-proxy {{< reuse "agw-docs/snippets/agw-gatewayclass.md" >}} a1cff4bd974a34d8b882b2fa01d357f0-119963959.us-east-2.elb.amazonaws.com True 6m9s - NAME READY UP-TO-DATE AVAILABLE AGE - agentgateway-proxy 1/1 1 1 6m11s - ``` - -3. Verify that the external IP has been created and is not `pending`. - - ```sh - kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} agentgateway-proxy - ``` - - Example output: - ```txt - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - agentgateway-proxy LoadBalancer 172.20.200.127 80:30752/TCP 7m6s - ``` - -4. Get the external address of the agentgateway proxy and save it in an environment variable. - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} agentgateway-proxy -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80 - ``` - {{% /tab %}} - {{< /tabs >}} diff --git a/assets/docs/snippets/agentgateway.md b/assets/docs/snippets/agentgateway.md deleted file mode 100644 index 16008aa0e..000000000 --- a/assets/docs/snippets/agentgateway.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway \ No newline at end of file diff --git a/assets/docs/snippets/agentgateway/about.md b/assets/docs/snippets/agentgateway/about.md deleted file mode 100644 index 458d84e06..000000000 --- a/assets/docs/snippets/agentgateway/about.md +++ /dev/null @@ -1 +0,0 @@ -[Agentgateway](https://agentgateway.dev/) is an open source, AI-first data plane that provides connectivity for agents, MCP tools, LLMs, and inferences in any environment. In Kubernetes environments, you can use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the control plane to quickly spin up and manage the lifecycle of agentgateway proxies. The control plane translates Kubernetes Gateway API and {{< reuse "agw-docs/snippets/agentgateway.md" >}}'s Kubernetes custom resources such as {{< reuse "/agw-docs/snippets/agentgateway/agentgatewaypolicy.md" >}} and {{< reuse "/agw-docs/snippets/agentgateway/agentgatewaybackend.md" >}} into proxy configuration for the data plane. \ No newline at end of file diff --git a/assets/docs/snippets/agentgateway/agentgatewaybackend.md b/assets/docs/snippets/agentgateway/agentgatewaybackend.md deleted file mode 100644 index 182b2a4c1..000000000 --- a/assets/docs/snippets/agentgateway/agentgatewaybackend.md +++ /dev/null @@ -1 +0,0 @@ -AgentgatewayBackend \ No newline at end of file diff --git a/assets/docs/snippets/agentgateway/agentgatewaypolicy.md b/assets/docs/snippets/agentgateway/agentgatewaypolicy.md deleted file mode 100644 index 7f2127588..000000000 --- a/assets/docs/snippets/agentgateway/agentgatewaypolicy.md +++ /dev/null @@ -1 +0,0 @@ -AgentgatewayPolicy \ No newline at end of file diff --git a/assets/docs/snippets/agentgateway/get-started.md b/assets/docs/snippets/agentgateway/get-started.md deleted file mode 100644 index 7c03853ea..000000000 --- a/assets/docs/snippets/agentgateway/get-started.md +++ /dev/null @@ -1,45 +0,0 @@ -1. Deploy the Kubernetes Gateway API CRDs. - - {{< tabs items="Standard, Experimental" tabTotal="2" >}} - {{% tab tabName="Standard" %}} - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml - ``` - {{% /tab %}} - {{% tab tabName="Experimental" %}} - CRDs in the experimental channel are required to use some experimental features in the Gateway API. Guides that require experimental CRDs note this requirement in their prerequisites. - ```sh - kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Deploy the CRDs for the kgateway control plane and agentgateway data plane by using Helm. - ```sh - helm upgrade -i {{< reuse "agw-docs/snippets/helm-kgateway-crds.md" >}} oci://ghcr.io/kgateway-dev/charts/agentgateway-crds \ - --create-namespace --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} \ - --version v{{< reuse "agw-docs/versions/patch-dev.md" >}} \ - --set controller.image.pullPolicy=Always - ``` - -3. Install the agentgateway control plane by using Helm. To use experimental Gateway API features, include the experimental feature gate, `--set controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true`. - ```sh - helm upgrade -i {{< reuse "agw-docs/snippets/helm-kgateway.md" >}} oci://ghcr.io/kgateway-dev/charts/agentgateway \ - --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} \ - --version v{{< reuse "agw-docs/versions/patch-dev.md" >}} \ - --set controller.image.pullPolicy=Always \ - --set controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true - ``` - -4. Make sure that the `{{< reuse "agw-docs/snippets/pod-name.md" >}}` control plane is running. - - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - - ```console - NAME READY STATUS RESTARTS AGE - {{< reuse "agw-docs/snippets/pod-name.md" >}}-5495d98459-46dpk 1/1 Running 0 19s - ``` \ No newline at end of file diff --git a/assets/docs/snippets/agentgateway/grafana-dashboards.md b/assets/docs/snippets/agentgateway/grafana-dashboards.md deleted file mode 100644 index 795c80fb4..000000000 --- a/assets/docs/snippets/agentgateway/grafana-dashboards.md +++ /dev/null @@ -1,54 +0,0 @@ -You can use the pre-built Grafana dashboards to observe the control and data plane statuses. - -1. Create a Grafana dashboard for the control metrics. You can download the following sample Grafana dashboard configuration: - * [Agentgateway dashboard](../agentgateway.json) - ```sh - curl -L "http://kgateway.dev/docs/main/agentgateway/observability/agentgateway.json" >> agentgateway.json - ``` - -2. Import the Grafana dashboard. - ```sh - kubectl -n telemetry create cm agentgateway-dashboard \ - --from-file=agentgateway.json - kubectl label -n telemetry cm agentgateway-dashboard grafana_dashboard=1 - ``` - -3. Open and log in to Grafana by using the username `admin` and password `prom-operator`. - - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2">}} -{{% tab tabName="Cloud Provider LoadBalancer" %}} -```sh -open "http://$(kubectl -n telemetry get svc kube-prometheus-stack-grafana -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}"):3000" -``` -{{% /tab %}} -{{% tab tabName="Port-forward for local testing" %}} -1. Port-forward the Grafana service to your local machine. - ```sh - kubectl port-forward deployment/kube-prometheus-stack-grafana -n telemetry 3000 - ``` -2. Open Grafana in your browser by using the following URL: [http://localhost:3000](http://localhost:3000) -{{% /tab %}} - {{< /tabs >}} - -1. Go to **Dashboards** > **Agentgateway** to open the Agentgateway dashboard that you imported. Verify that you see metrics, such as the translation and reconciliation time, total number of operations, or the number of resources in your cluster. - - {{< reuse-image src="img/kgateway-dashboard.png" >}} - {{< reuse-image-dark srcDark="img/kgateway-dashboard.png" >}} - - | Metric | Description | - | -- | -- | - | Number of translations running per translator | The number of active Kubernetes Gateway API translations. | - | Number of reconciliations running per controller | The number of active reconciliations for each controller. | - | Number of resources | The number of Kubernetes Gateway API and kgateway resources in your cluster. | - | Translations rate by results | The rate of translations in seconds and their statuses. | - | Reconciliation rate by results | The rate of reconciliations in seconds and their statuses. | - | Status syncs rate by results | The rate of status syncs in seconds and their statuses. | - | Total operations | The total number of reconciliations for each controller plus the total number of translations for each translator, and the total number of status syncs for each status syncer. | - | XDS resources by gateway | The total number of resources in the XDS snapshot for each gateway, such as clusters, endpoints, listeners, and routes. | - | Routing domains per gateway port | The total number of routing domains for each gateway and port. | - | Reconciliation latency | In the last 5 minutes, the amount of time that it took 70%, 90%, and 99% of reconciliation processes to finish. | - | Status Syncer Latency | In the last 5 minutes, the amount of time that it took 70%, 90%, and 99% of status syncs to finish. | - | Translation Latency | In the last 5 minutes, the amount of time that it took 70%, 90%, and 99% of translations to finish. | - | XDS Snapshot Sync Latency | In the last 5 minutes, the amount of time that it took 70%, 90%, and 99% of xDS snapshots to finish. | - | Resource Status Sync Latency | In the last 5 minutes, the amount of time that it took 70%, 90%, and 99% of resource status syncs to finish. | - | Status Syncs by Resource | The total number of status syncs completed by resource type. | diff --git a/assets/docs/snippets/agentgateway/llm-next.md b/assets/docs/snippets/agentgateway/llm-next.md deleted file mode 100644 index f3b56c47a..000000000 --- a/assets/docs/snippets/agentgateway/llm-next.md +++ /dev/null @@ -1,5 +0,0 @@ -## Next steps - -- Want to use other endpoints than chat completions, such as embeddings or models? Check out the [multiple endpoints]({{< link-hextra path="/llm/providers/multiple-endpoints/" >}}) guide. -- Explore [other guides for LLM consumption]({{< link-hextra path="/llm/" >}}), such as function calling, model failover, and prompt guards. - diff --git a/assets/docs/snippets/agentgateway/otel-prereq.md b/assets/docs/snippets/agentgateway/otel-prereq.md deleted file mode 100644 index ed0dace3f..000000000 --- a/assets/docs/snippets/agentgateway/otel-prereq.md +++ /dev/null @@ -1,61 +0,0 @@ -Deploy an open source observability stack based on OpenTelemetry (OTel) that includes the following components: - -- **Logs**: Centralized log collection and storage with Grafana [Loki](https://github.com/grafana/loki). -- **Traces**: Distributed tracing with Grafana [Tempo](https://github.com/grafana/tempo). -- **Metrics**: Time-series metrics collection with [Prometheus](https://github.com/prometheus/prometheus). -- **Collection**: Unified telemetry collection with [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector). -- **Visualization**: Comprehensive dashboards with [Grafana](https://github.com/grafana/grafana). - -## About - -Observability tools are essential to gain insight into the health and performance of your gateway proxies. [OpenTelemetry](https://opentelemetry.io/) (OTel) is a flexible, open source framework that provides a set of APIs, libraries, and instrumentation to help capture and export observability data. However, you can follow a similar process as this guide to use the tools that you prefer. - -### Observability data types {#data-types} - -Observability is built on three core pillars as described in the following table. By combining these three data types, you get a complete picture of your system's health and performance. - -| Pillar | Description | -| -- | -- | -| Logs | Discrete events that happen at a specific time with detailed context. | -| Metrics | Numerical measurements aggregated over time intervals. | -| Traces | Records of requests as they flow through distributed systems. | - -### Architecture - -Review the following diagram to understand the architecture of the observability stack. - -The gateway proxy acts as the primary telemetry generator, while the OTel Collectors serve as the central routing hub for all observability data. - -```mermaid -flowchart TD - A["1- Application Traffic"] --> B["2- Gateway proxy"] - B --> C["3- OTel Collectors"] - C --> D["4- Storage Backends"] - D --> D1["Logs (Loki)"] - D --> D2["Traces (Tempo)"] - D --> D3["Metrics (Prometheus)"] - D1 --> E["5- Visualization (Grafana)"] - D2 --> E - D3 --> E -``` -Architecture data flow: -1. **Application Traffic**: Applications send requests to the gateway proxy. -2. **Gateway Processing**: The gateway proxy processes requests and generates telemetry data in the form of logs, traces, and metrics. -3. **Telemetry Collection**: The OTel Collectors receive telemetry data from the gateway proxy. -4. **Data Storage**: The OTel Collectors route data to the appropriate storage backends: - - **Logs** go to Loki for log aggregation and storage. - - **Traces** go to Tempo for distributed tracing storage. - - **Metrics** go to Prometheus for time-series metrics storage. -5. **Visualization**: Grafana queries the storage backends as data sources to create unified dashboards. - -### More considerations {#more-considerations} - -**Push model**: This guide sets up the OTel collectors to push metrics to the storage backends (`push` model), vs. setting up the backends such as Prometheus to scrape metrics from the collector pod (`pull` model). The `push` model is used because it shows the ease and consistency of using OTel for demonstration purposes. It also supports Native Histograms out of the box, which the `pull` model does not due to [a known OTel issue with the Prometheus exporter](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/33703). - -**Debug exporter**: The example pipelines in all three OTel collectors set up the `debug` exporter. This exporter is useful for testing and validation purposes. However, for production scenarios, remove this exporter to avoid performance impacts. - -**Prometheus exporter**: If you prefer the `pull` model to the `push` model, you can use `prometheusexporter`'s `promexporter` port with Prometheus to scrape metrics from the collector pod, such as configured in the example later. Also, if you use the `pull` model, make sure to configure Prometheus to handle Native Histograms and scrape the metrics directly as for this model OTel's `prometheusexporter` is not yet supported, per the [known issue](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/33703) previously mentioned. - -## Before you begin - -{{< reuse "agw-docs/snippets/agentgateway-prereq.md" >}} \ No newline at end of file diff --git a/assets/docs/snippets/agentgateway/tracing-config.md b/assets/docs/snippets/agentgateway/tracing-config.md deleted file mode 100644 index c98d7c727..000000000 --- a/assets/docs/snippets/agentgateway/tracing-config.md +++ /dev/null @@ -1,112 +0,0 @@ -{{< tabs tabTotal="4" items="Jaeger,Langfuse,Phoenix (Arize),OpenLLMetry" >}} -{{% tab tabName="Jaeger" %}} -```yaml -kubectl apply -f- <}} -kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} -metadata: - name: jaeger-tracing-config - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - rawConfig: - config: - tracing: - otlpEndpoint: http://jaeger-collector.jaeger.svc.cluster.local:4317 - otlpProtocol: grpc - randomSampling: true - fields: - add: - gen_ai.operation.name: '"chat"' - gen_ai.system: "llm.provider" - gen_ai.request.model: "llm.requestModel" - gen_ai.response.model: "llm.responseModel" - gen_ai.usage.completion_tokens: "llm.outputTokens" - gen_ai.usage.prompt_tokens: "llm.inputTokens" -EOF -``` -{{% /tab %}} -{{% tab tabName="Langfuse" %}} -```yaml -kubectl apply -f- <}} -kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} -metadata: - name: langfuse-tracing-config - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - rawConfig: - config: - tracing: - otlpEndpoint: https://us.cloud.langfuse.com/api/public/otel - otlpProtocol: http - headers: - Authorization: "Basic " - randomSampling: true - fields: - add: - gen_ai.operation.name: '"chat"' - gen_ai.system: "llm.provider" - gen_ai.prompt: "llm.prompt" - gen_ai.completion: 'llm.completion.map(c, {"role":"assistant", "content": c})' - gen_ai.usage.completion_tokens: "llm.outputTokens" - gen_ai.usage.prompt_tokens: "llm.inputTokens" - gen_ai.request: "flatten(llm.params)" -EOF -``` -{{% /tab %}} -{{% tab tabName="Phoenix (Arize)" %}} -```yaml -kubectl apply -f- <}} -kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} -metadata: - name: phoenix-tracing-config - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - rawConfig: - config: - tracing: - otlpEndpoint: http://localhost:4317 - randomSampling: true - fields: - add: - span.name: '"openai.chat"' - openinference.span.kind: '"LLM"' - llm.system: "llm.provider" - llm.input_messages: 'flattenRecursive(llm.prompt.map(c, {"message": c}))' - llm.output_messages: 'flattenRecursive(llm.completion.map(c, {"role":"assistant", "content": c}))' - llm.token_count.completion: "llm.outputTokens" - llm.token_count.prompt: "llm.inputTokens" - llm.token_count.total: "llm.totalTokens" -EOF -``` -{{% /tab %}} -{{% tab tabName="OpenLLMetry" %}} -```yaml -kubectl apply -f- <}} -kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} -metadata: - name: openllmetry-tracing-config - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} -spec: - rawConfig: - config: - tracing: - otlpEndpoint: http://localhost:4317 - randomSampling: true - fields: - add: - span.name: '"openai.chat"' - gen_ai.operation.name: '"chat"' - gen_ai.system: "llm.provider" - gen_ai.prompt: "flattenRecursive(llm.prompt)" - gen_ai.completion: 'flattenRecursive(llm.completion.map(c, {"role":"assistant", "content": c}))' - gen_ai.usage.completion_tokens: "llm.outputTokens" - gen_ai.usage.prompt_tokens: "llm.inputTokens" - llm.usage.total_tokens: 'llm.totalTokens' - llm.is_streaming: "llm.streaming" -EOF -``` -{{% /tab %}} -{{< /tabs >}} \ No newline at end of file diff --git a/assets/docs/snippets/agw-gatewayclass-choice.md b/assets/docs/snippets/agw-gatewayclass-choice.md deleted file mode 100644 index 5434b96c8..000000000 --- a/assets/docs/snippets/agw-gatewayclass-choice.md +++ /dev/null @@ -1 +0,0 @@ -To use the default Envoy-based {{< reuse "/agw-docs/snippets/kgateway.md" >}} proxy, set the `gatewayClassName` to `{{< reuse "/agw-docs/snippets/gatewayclass.md" >}}`. To use [agentgateway](../../../agentgateway/), set the `gatewayClassName` to `agentgateway`. \ No newline at end of file diff --git a/assets/docs/snippets/agw-gatewayclass.md b/assets/docs/snippets/agw-gatewayclass.md deleted file mode 100644 index 16008aa0e..000000000 --- a/assets/docs/snippets/agw-gatewayclass.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway \ No newline at end of file diff --git a/assets/docs/snippets/agw-kgw.md b/assets/docs/snippets/agw-kgw.md deleted file mode 100644 index bd9fb5b3b..000000000 --- a/assets/docs/snippets/agw-kgw.md +++ /dev/null @@ -1 +0,0 @@ -kgateway \ No newline at end of file diff --git a/assets/docs/snippets/agw-prereq-llm.md b/assets/docs/snippets/agw-prereq-llm.md deleted file mode 100644 index 37974a4bb..000000000 --- a/assets/docs/snippets/agw-prereq-llm.md +++ /dev/null @@ -1,2 +0,0 @@ -1. Set up an [agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}). -2. [Set up access to the OpenAI LLM provider]({{< link-hextra path="/llm/providers/openai/" >}}). \ No newline at end of file diff --git a/assets/docs/snippets/ai-deprecation-note.md b/assets/docs/snippets/ai-deprecation-note.md deleted file mode 100644 index 12957f189..000000000 --- a/assets/docs/snippets/ai-deprecation-note.md +++ /dev/null @@ -1,3 +0,0 @@ -{{< callout type="warning" >}} -AI Gateway for Envoy-based gateway proxies is deprecated and is planned to be removed in version 2.2. If you want to use AI capabilities, use an [agentgateway proxy](../../../agentgateway/) instead. -{{< /callout >}} diff --git a/assets/docs/snippets/ai-gateway-address.md b/assets/docs/snippets/ai-gateway-address.md deleted file mode 100644 index c1c67afad..000000000 --- a/assets/docs/snippets/ai-gateway-address.md +++ /dev/null @@ -1,15 +0,0 @@ -Get the external address of the gateway and save it in an environment variable. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{< tab tabName="Cloud Provider LoadBalancer" >}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} ai-gateway -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{< /tab >}} - {{< tab tabName="Port-forward for local testing" >}} - ```sh - kubectl port-forward deployment/ai-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - {{< /tab >}} - {{< /tabs >}} \ No newline at end of file diff --git a/assets/docs/snippets/alb-elb-name.md b/assets/docs/snippets/alb-elb-name.md deleted file mode 100644 index bd9fb5b3b..000000000 --- a/assets/docs/snippets/alb-elb-name.md +++ /dev/null @@ -1 +0,0 @@ -kgateway \ No newline at end of file diff --git a/assets/docs/snippets/api-ref-docs-intro.md b/assets/docs/snippets/api-ref-docs-intro.md deleted file mode 100644 index 637a437e6..000000000 --- a/assets/docs/snippets/api-ref-docs-intro.md +++ /dev/null @@ -1,3 +0,0 @@ -Review the API reference documentation for {{< reuse "agw-docs/snippets/kgateway-and-data-plane.md" >}}. - -Looking for the Envoy data plane APIs instead? See the [kgateway with Envoy](https://kgateway.dev/docs/envoy/main/reference/api/) API docs. diff --git a/assets/docs/snippets/argocd.md b/assets/docs/snippets/argocd.md deleted file mode 100644 index 415b03d89..000000000 --- a/assets/docs/snippets/argocd.md +++ /dev/null @@ -1,124 +0,0 @@ -1. Install the custom resources of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} version {{< reuse "agw-docs/versions/k8s-gw-version.md" >}}. - - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml - ``` - - Example output: - ```console - customresourcedefinition.apiextensions.k8s.io/backendtlspolicies.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created - customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created - ``` - - {{< callout type="info" >}}If you need to use an experimental feature such as TCPRoutes, install the experimental CRDs. For more information, see [Experimental features in Gateway API](../../reference/versions/#experimental-features).{{< /callout >}} - -2. Port-forward the Argo CD server on port 9999. - - ```sh - kubectl port-forward svc/argocd-server -n argocd 9999:443 - ``` - -3. Open the [Argo CD UI](https://localhost:9999/). - -4. Log in with the `admin` username and `gateway` password. - - {{< reuse-image src="img/argocd-welcome.png" >}} - {{< reuse-image-dark srcDark="img/argocd-welcome.png" >}} - -5. Create an Argo CD application to deploy the {{< reuse "/agw-docs/snippets/kgateway.md" >}} CRD Helm chart. - - ```yaml - kubectl apply -f- <}}-helm - namespace: argocd - spec: - destination: - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - server: https://kubernetes.default.svc - project: default - source: - chart: {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} - helm: - skipCrds: false - repoURL: {{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts - targetRevision: {{< reuse "agw-docs/versions/helm-version-flag.md" >}} - syncPolicy: - automated: - # Prune resources during auto-syncing (default is false) - prune: true - # Sync the app in part when resources are changed only in the target Kubernetes cluster - # but not in the git source (default is false). - selfHeal: true - syncOptions: - - CreateNamespace=true - EOF - ``` - -6. Create an Argo CD application to install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart. You might also need the following parameters: - * **Development builds**: `controller.image.pullPolicy=Always` to ensure you get the latest image. - * **Experimental Gateway API features**: `controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true` to enable experimental features such as TCPRoutes. - - ```yaml - kubectl apply -f- <}}-helm - namespace: argocd - spec: - destination: - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - server: https://kubernetes.default.svc - project: default - source: - chart: {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} - helm: - skipCrds: false - parameters: - - name: controller.image.pullPolicy - value: "Always" - - name: controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES - value: "true" - repoURL: {{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts - targetRevision: {{< reuse "agw-docs/versions/helm-version-flag.md" >}} - syncPolicy: - automated: - # Prune resources during auto-syncing (default is false) - prune: true - # Sync the app in part when resources are changed only in the target Kubernetes cluster - # but not in the git source (default is false). - selfHeal: true - syncOptions: - - CreateNamespace=true - EOF - ``` - -7. Verify that the control plane is up and running. - - ```sh - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - - Example output: - ```txt - NAME READY STATUS RESTARTS AGE - {{< reuse "agw-docs/snippets/pod-name.md" >}}-helm-6b5bb4db6b-c2pkq 1/1 Running 0 4m4s - ``` - -8. Verify that the `{{< reuse "/agw-docs/snippets/agw-gatewayclass.md" >}}` GatewayClass is created. You can optionally take a look at how the gateway class is configured by adding the `-o yaml` option to your command. - - ```sh - kubectl get gatewayclass {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - ``` - -9. Open the Argo CD UI and verify that you see the Argo CD application with a `Healthy` and `Synced` status. - - {{< reuse-image src="img/argo-app-agw.png" >}} - {{< reuse-image-dark srcDark="img/argo-app-agw.png" >}} diff --git a/assets/docs/snippets/aws-alb-nlb.md b/assets/docs/snippets/aws-alb-nlb.md deleted file mode 100644 index e8ddbf036..000000000 --- a/assets/docs/snippets/aws-alb-nlb.md +++ /dev/null @@ -1,14 +0,0 @@ -## About AWS Elastic Load Balancers (ELBs) - -{{< reuse "agw-docs/snippets/kgateway-capital.md" >}} is an application (L7) proxy based on Envoy and the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} that can act as both a secure edge router and as a developer-friendly Kubernetes ingress/egress (north-south traffic) gateway. You can get many benefits by pairing {{< reuse "agw-docs/snippets/kgateway.md" >}} with an AWS Elastic Load Balancer (ELB), including better cross availability zone failover and deeper integration with AWS services like AWS Certificate Manager, AWS CLI & CloudFormation, and Route 53 (DNS). - -AWS provides the following types of ELBs: - -* **Network Load Balancer (NLB)**: An optimized L4 TCP/UDP load balancer that can handle very high throughput (millions of requests per second) while maintaining low latency. This load balancer also has deep integration with other AWS services like Route 53 (DNS). -* **Application Load Balancer (ALB)**: An L7 HTTP-only load balancer that is focused on providing HTTP request routing capabilities. - -### AWS NLB vs. ALB - -In general, using a {{< reuse "agw-docs/snippets/kgateway.md" >}} proxy with an AWS NLB is recommended, as NLBs provide more application (L7) capabilities than AWS ALBs. For example, you can configure the NLB for TLS passthrough and terminate TLS traffic on the gateway. You can also terminate traffic at the NLB and configure the NLB with a certificate that is used to secure the connection from the NLB to the gateway proxy. - -ALBs can be useful if you want to use AWS WAF policies. Because TLS traffic is terminated at the ALB, you are responsible for securing the connection from the AWS to the {{< reuse "agw-docs/snippets/kgateway.md" >}} proxy. However, note that the AWS Load Balancer Controller only supports the creation of an ALB through an Ingress Controller and not through the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}. Because of this, you must create the ALB separately through an Ingress resource that connects it to the service that exposes your gateway proxy. \ No newline at end of file diff --git a/assets/docs/snippets/aws-elb-controller-install.md b/assets/docs/snippets/aws-elb-controller-install.md deleted file mode 100644 index 80f5a098b..000000000 --- a/assets/docs/snippets/aws-elb-controller-install.md +++ /dev/null @@ -1,53 +0,0 @@ -1. Save the name and region of your AWS EKS cluster and your AWS account ID in environment variables. - ```sh - export CLUSTER_NAME="" - export REGION="" - export AWS_ACCOUNT_ID= - export IAM_POLICY_NAME=AWSLoadBalancerControllerIAMPolicyNew - export IAM_SA=aws-load-balancer-controller - ``` - -2. Create an AWS IAM policy and bind it to a Kubernetes service account. - ```sh - # Set up an IAM OIDC provider for a cluster to enable IAM roles for pods - eksctl utils associate-iam-oidc-provider \ - --region ${REGION} \ - --cluster ${CLUSTER_NAME} \ - --approve - - # Fetch the IAM policy that is required for the Kubernetes service account - curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.5.3/docs/install/iam_policy.json - - # Create the IAM policy - aws iam create-policy \ - --policy-name ${IAM_POLICY_NAME} \ - --policy-document file://iam-policy.json - - # Create the Kubernetes service account - eksctl create iamserviceaccount \ - --cluster=${CLUSTER_NAME} \ - --namespace=kube-system \ - --name=${IAM_SA} \ - --attach-policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME} \ - --override-existing-serviceaccounts \ - --approve \ - --region ${REGION} - ``` - -3. Verify that the service account is created in your cluster. - ```sh - kubectl -n kube-system get sa aws-load-balancer-controller -o yaml - ``` - -4. Deploy the AWS Load Balancer Controller. - ```sh - kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master" - - helm repo add eks https://aws.github.io/eks-charts - helm repo update - helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ - -n kube-system \ - --set clusterName=${CLUSTER_NAME} \ - --set serviceAccount.create=false \ - --set serviceAccount.name=${IAM_SA} - ``` \ No newline at end of file diff --git a/assets/docs/snippets/backend.md b/assets/docs/snippets/backend.md deleted file mode 100644 index 831a1d9dd..000000000 --- a/assets/docs/snippets/backend.md +++ /dev/null @@ -1 +0,0 @@ -AgentgatewayBackend diff --git a/assets/docs/snippets/buffering-cleanup.md b/assets/docs/snippets/buffering-cleanup.md deleted file mode 100644 index 5070534f8..000000000 --- a/assets/docs/snippets/buffering-cleanup.md +++ /dev/null @@ -1,30 +0,0 @@ -## Cleanup - -{{< reuse "agw-docs/snippets/cleanup.md" >}} - -1. Delete the {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} resources. - ```sh - kubectl delete {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} transformation-buffer-body -n httpbin - - kubectl delete {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} transformation-buffer-limit -n httpbin - ``` - -2. Remove the buffer limit annotation from the http Gateway resource. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` \ No newline at end of file diff --git a/assets/docs/snippets/buffering-route.md b/assets/docs/snippets/buffering-route.md deleted file mode 100644 index 6a72103bb..000000000 --- a/assets/docs/snippets/buffering-route.md +++ /dev/null @@ -1,128 +0,0 @@ -## Set up buffer limits per route - -You can configure connection buffer limits using a {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} to control how much data can be buffered per connection at the level of individual routes. This can provide more fine-grained control than applying the buffer limit at the Gateway, or can provide a method of overriding a buffer limit at the level of the Gateway. - -1. If you did not already, create a {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} called `transformation-buffer-body` that forces buffering by transforming the response from the httpbin sample app. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation-buffer-body - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - transformation: - response: - body: - parseAs: AsString - value: '{{ body() }}' - EOF - ``` - -2. If you previously added the `kgateway.dev/per-connection-buffer-limit` annotation to the Gateway, remove that annotation. - ```yaml - kubectl apply -f- <}} - spec: - gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}} - listeners: - - protocol: HTTP - port: 8080 - name: http - allowedRoutes: - namespaces: - from: All - EOF - ``` - -3. In a separate {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}}, apply a buffer limit of `maxRequestSize: '1024'` to the httpbin app. This setting limits the request payload to 1024 bytes. - ```yaml - kubectl apply -f- <}} - kind: {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} - metadata: - name: transformation-buffer-limit - namespace: httpbin - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: httpbin - buffer: - maxRequestSize: '1024' - EOF - ``` - -4. To test the buffer limit, create a payload in a temp file that exceeds the 1Ki buffer limit. - ```sh - dd if=/dev/zero bs=2048 count=1 | base64 -w 0 > /tmp/large_payload_2k.txt - ``` - -5. Send a request to the `/anything` httpbin path with the large payload. Verify that the request fails with a connection error or timeout, indicating that the buffer limit was exceeded. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik -X POST http://$INGRESS_GW_ADDRESS:8080/anything \ - -H "host: www.example.com:8080" \ - -H "Content-Type: text/plain" \ - -d "{\"payload\": \"$(< /tmp/large_payload_2k.txt)\"}" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik -X POST http://localhost:8080/anything \ - -H "host: www.example.com:8080" \ - -H "Content-Type: text/plain" \ - -d "{\"payload\": \"$(< /tmp/large_payload_2k.txt)\"}" - ``` - {{% /tab %}} - {{< /tabs >}} - -5. Test the buffer limit again by sending a request with a small payload, `"hello world"`. This request succeeds with a normal response from httpbin because the payload size is within the 2Ki limit. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - curl -vik -X POST http://$INGRESS_GW_ADDRESS:8080/anything \ - -H "host: www.example.com:8080" \ - -H "Content-Type: application/json" \ - -d "{\"payload\": \"hello world\"}" - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik -X POST http://localhost:8080/anything \ - -H "host: www.example.com:8080" \ - -H "Content-Type: application/json" \ - -d "{\"payload\": \"hello world\"}" - ``` - {{% /tab %}} - {{< /tabs >}} - - - Example output: - - ```json - { - "args": {}, - "data": "{\"payload\": \"hello world\"}", - "files": {}, - "form": {}, - "headers": { - ... - }, - "json": { - "payload": "hello world" - }, - "method": "POST", - "origin": "...", - "url": "https://$INGRESS_GW_ADDRESS:8080/anything" - } - ``` \ No newline at end of file diff --git a/assets/docs/snippets/byo-gateway.md b/assets/docs/snippets/byo-gateway.md deleted file mode 100644 index b94f581a0..000000000 --- a/assets/docs/snippets/byo-gateway.md +++ /dev/null @@ -1 +0,0 @@ -If you want to change the [default gateway proxy template]({{< link-hextra path="/setup/default/#gateway-proxy-template" >}}) and provide your own Envoy configuration to bootstrap the proxy with, you must create a self-managed gateway. For more information, see [Self-managed gateways (BYO)]({{< link-hextra path="/setup/selfmanaged" >}}). \ No newline at end of file diff --git a/assets/docs/snippets/cert-prereqs.md b/assets/docs/snippets/cert-prereqs.md deleted file mode 100644 index 3684c3874..000000000 --- a/assets/docs/snippets/cert-prereqs.md +++ /dev/null @@ -1,19 +0,0 @@ -1. Set up kgateway by following the [Quick start]({{< link-hextra path="/quickstart/" >}}) or [Installation]({{< link-hextra path="/install/" >}}) guides. - -2. [Deploy the httpbin sample app]({{< link-hextra path="/install/sample-app/" >}}). - -3. Make sure that you have the OpenSSL version of `openssl`, not LibreSSL. The `openssl` version must be at least 1.1. - 1. Check the `openssl` version that is installed. If you see LibreSSL in the output, continue to the next step. - ```sh - openssl version - ``` - 2. Install the OpenSSL version (not LibreSSL). For example, you might use Homebrew. - ```sh - brew install openssl - ``` - - 3. Review the output of the OpenSSL installation for the path of the binary file. You can choose to export the binary to your path, or call the entire path whenever the following steps use an openssl command. - - For example, openssl might be installed along the following path: `/usr/local/opt/openssl@3/bin/` - - To run commands, you can append the path so that your terminal uses this installed version of OpenSSL, and not the default LibreSSL. `/usr/local/opt/openssl@3/bin/openssl req -new -newkey rsa:4096 -x509 -sha256 -days 3650...` - -4. {{< reuse "agw-docs/snippets/prereq-listenerset.md" >}}. Note that you must install the experimental channel of the Kubernetes Gateway API at version {{< reuse "agw-docs/versions/k8s-gw-version.md" >}} or later if you want to use ListenerSets. \ No newline at end of file diff --git a/assets/docs/snippets/cert_openssl.md b/assets/docs/snippets/cert_openssl.md deleted file mode 100644 index 871b83cad..000000000 --- a/assets/docs/snippets/cert_openssl.md +++ /dev/null @@ -1,12 +0,0 @@ -{{< callout type="info" >}} The default `openssl` version that is included in macOS is LibreSSL, which does not work with these instructions. Make sure that you have the OpenSSL version of `openssl`, not LibreSSL. {{< /callout >}} The `openssl` version must be at least 1.1. - 1. Check your `openssl` version. If you see **LibreSSL** in the output, continue to the next step. - ```shell - openssl version - ``` - 2. Install the OpenSSL version (not LibreSSL). For example, you might use Homebrew. - ```shell - brew install openssl - ``` - 3. Review the output of the OpenSSL installation for the path of the binary file. You can choose to export the binary to your path, or call the entire path whenever the following steps use an `openssl` command. - * For example, `openssl` might be installed along the following path: `/usr/local/opt/openssl@3/bin/` - * To run commands, you can append the path so that your terminal uses this installed version of OpenSSL, and not the default LibreSSL. `/usr/local/opt/openssl@3/bin/openssl req -new -newkey rsa:4096 -x509 -sha256 -days 3650...` \ No newline at end of file diff --git a/assets/docs/snippets/class-setup.md b/assets/docs/snippets/class-setup.md deleted file mode 100644 index 4ef8c9bfe..000000000 --- a/assets/docs/snippets/class-setup.md +++ /dev/null @@ -1,28 +0,0 @@ -{{< tabs items="agentgateway,agentgateway-waypoint" tabTotal="2">}} -{{% tab %}} -The `agentgateway` GatewayClass is the standard class for when you want to use an agentgateway proxy in kgateway. -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: agentgateway -spec: - controllerName: kgateway.dev/agentgateway - description: Specialized class for agentgateway. -``` -{{% /tab %}} -{{% tab %}} -The `agentgateway-waypoint` GatewayClass is for when you use agentgateway as a waypoint in an Istio Ambient service mesh setup. -```yaml -apiVersion: gateway.networking.k8s.io/v1 -kind: GatewayClass -metadata: - name: agentgateway-waypoint -spec: - controllerName: kgateway.dev/kgateway - description: Specialized class for Istio ambient mesh waypoint proxies. -``` -{{% /tab %}} -{{< /tabs >}} - -The `kgateway.dev/kgateway` controller watches the resources in your cluster. When a Gateway resource is created that references the GatewayClass, the controller spins up an agentgateway proxy by using the configuration that is defined in the GatewayParameters resource. The controller also translates other resources, such as HTTPRoute, {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, HTTPListenerPolicy, and more, into valid agentgateway configuration, and applies the configuration to the gateway proxies it manages. diff --git a/assets/docs/snippets/cleanup.md b/assets/docs/snippets/cleanup.md deleted file mode 100644 index a2ce0698f..000000000 --- a/assets/docs/snippets/cleanup.md +++ /dev/null @@ -1 +0,0 @@ -You can remove the resources that you created in this guide. \ No newline at end of file diff --git a/assets/docs/snippets/cli-name.md b/assets/docs/snippets/cli-name.md deleted file mode 100644 index 6210b80a5..000000000 --- a/assets/docs/snippets/cli-name.md +++ /dev/null @@ -1 +0,0 @@ -glooctl \ No newline at end of file diff --git a/assets/docs/snippets/control-plane-note.md b/assets/docs/snippets/control-plane-note.md deleted file mode 100644 index 421c10be8..000000000 --- a/assets/docs/snippets/control-plane-note.md +++ /dev/null @@ -1 +0,0 @@ -To use both Envoy-based {{< reuse "agw-docs/snippets/kgateway.md">}} and {{< reuse "agw-docs/snippets/agentgateway.md">}} data plane proxy types in the same cluster, make sure to create a {{< reuse "agw-docs/snippets/kgateway.md">}} control plane for each proxy type. \ No newline at end of file diff --git a/assets/docs/snippets/cr-ov.md b/assets/docs/snippets/cr-ov.md deleted file mode 100644 index 71cef482d..000000000 --- a/assets/docs/snippets/cr-ov.md +++ /dev/null @@ -1,4 +0,0 @@ -The following image illustrates how the {{< reuse "/agw-docs/snippets/kgateway.md" >}} custom resources interact with the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} custom resources to provide advanced routing, traffic management, security, resiliency, and integration capabilities. To learn more about each custom resource, see [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} resources](#k8s) and [kgateway resources](#kgateway). - -{{< reuse-image src="img/kgw-crs-light.svg" >}} -{{< reuse-image-dark srcDark="img/kgw-crs-dark.svg" >}} \ No newline at end of file diff --git a/assets/docs/snippets/data-plane.md b/assets/docs/snippets/data-plane.md deleted file mode 100644 index 9090b8f64..000000000 --- a/assets/docs/snippets/data-plane.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway diff --git a/assets/docs/snippets/debug-gateway.md b/assets/docs/snippets/debug-gateway.md deleted file mode 100644 index 3b0b64f73..000000000 --- a/assets/docs/snippets/debug-gateway.md +++ /dev/null @@ -1,67 +0,0 @@ -1. Make sure that the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and gateway proxies are running. For any pod that is not running, describe the pod for more details. - - ```she - kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` - -2. Check the HTTPRoutes for the status of the route and any attached policies. - - ```sh - kubectl get httproutes -A - ``` - ```sh - kubectl get httproute -n -o yaml - ``` - -3. Access the debugging interface of your gateway proxy on your localhost. Configuration might be missing on the gateway or might be applied to the wrong route. For example, if you apply multiple policies to the same route by using the `targetRefs` section, only the oldest policy is applied. The newer policy configuration might be ignored and not applied to the gateway. - {{< conditional-text include-if="envoy" >}} - - ```sh - kubectl port-forward deploy/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000 & - ``` - - * [http://localhost:19000/](http://localhost:19000/) - - {{< reuse-image src="img/gateway-admin-interface.png" caption="Figure: Debugging interface of the gateway proxy.">}} - {{< reuse-image-dark srcDark="img/gateway-admin-interface.png" caption="Figure: Debugging interface of the gateway proxy.">}} - - Review the following table of common endpoints that can help troubleshoot your setup further. - | Endpoint | Description| - | -- | -- | - | config_dump | Get the configuration that is available in the Envoy proxy. Any kgateway resources that you create are translated in to Envoy configuration. Depending on whether or not you enabled resource validation, you might have applied invalid configuration that is rejected Envoy. You can also use `{{< reuse "agw-docs/snippets/cli-name.md" >}} proxy dump` to get the Envoy proxy configuration. | - | listeners | See the listeners that are configured on your gateway. | - | logging | Review the log level that is set for each component. | - | stats/prometheus | View metrics that Envoy emitted and sent to the built-in Prometheus instance. | - - {{< /conditional-text >}} - - {{< conditional-text include-if="agentgateway" >}} - ```sh - kubectl port-forward deploy/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 15000 & - ``` - - Open your browser to the following endpoints. - - | Endpoint | Description| - | -- | -- | - | [http://localhost:15000/config_dump](http://localhost:15000/config_dump) | Get the configuration that is available in the agentgateway proxy. Any custom resources that you create are translated in to agentgateway configuration. Depending on whether or not you enabled resource validation, you might have applied invalid configuration that is rejected in agentgateway. | - | [http://localhost:15000/ui](http://localhost:15000/ui) | A read-only user interface to review the agentgateway resources in your environment, such as listeners, routes, backends, and policies. | - - {{< reuse-image src="img/agw-ui-landing.png" caption="Figure: Read-only agentgateway UI.">}} - {{< reuse-image-dark srcDark="img/agw-ui-landing-dark.png" caption="Figure: Read-only agentgateway UI.">}} - - {{< /conditional-text >}} - -4. Review the logs for each component. Each component logs the sync loops that it runs, such as syncing with various environment signals like the Kubernetes API. {{< conditional-text include-if="envoy" >}}You can fetch the latest logs for all the components with the following command. - - * If you have not already, [set the log level for the Envoy gateway proxy to `debug`](#gateway-debug-logging). - - ```bash - # {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane - kubectl logs -n {{< reuse "agw-docs/snippets/namespace.md" >}} deployment/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} - - # Replace $GATEWAY_NAME with the name of your gateway. - export GATEWAY_NAME=http - kubectl logs -n {{< reuse "agw-docs/snippets/namespace.md" >}} deployment/$GATEWAY_NAME - ``` - {{< /conditional-text >}} diff --git a/assets/docs/snippets/demo-disclaimer.md b/assets/docs/snippets/demo-disclaimer.md deleted file mode 100644 index 7d4f17f35..000000000 --- a/assets/docs/snippets/demo-disclaimer.md +++ /dev/null @@ -1 +0,0 @@ -The following example uses a sample app for demonstration purposes only. You can use the app to try out the feature and to help design your own app. The app is not intended for production use and might not have updated dependencies or security patches. \ No newline at end of file diff --git a/assets/docs/snippets/discovery-about.md b/assets/docs/snippets/discovery-about.md deleted file mode 100644 index 1bec4251f..000000000 --- a/assets/docs/snippets/discovery-about.md +++ /dev/null @@ -1,8 +0,0 @@ -Kgateway comes with a built-in service discovery feature that can scan the Kubernetes services and Functions in your cluster and automatically create kgateway Backend resources for them to facilitate routing and self-service. To have more control over the services you want to create Backends for, you can disable service discovery and instead create Backends manually. - -The following resources can be discovered automatically: - -* Kubernetes Services -* AWS EC2 instances -* AWS Lambda Functions -* OpenAPI-based Functions diff --git a/assets/docs/snippets/dynamic-req-resp-headers.md b/assets/docs/snippets/dynamic-req-resp-headers.md deleted file mode 100644 index 5749aaa4a..000000000 --- a/assets/docs/snippets/dynamic-req-resp-headers.md +++ /dev/null @@ -1,33 +0,0 @@ -Keep in mind that some variables are available only at certain times. For example, response codes (`%RESPONSE_CODE%`) are only available after the response has been sent to the client. If you set a response code in a request header, the value is empty. - -You might use some of the following common values in your request or response headers. - -Request and response information: -- %REQ(:METHOD)% - HTTP method -- %REQ(:PATH)% - Request path -- %REQ(:AUTHORITY)% - Host header -- %REQ(HEADER_NAME)% - Any request header -- %RESP(HEADER_NAME)% - Any response header -- %RESPONSE_CODE% - HTTP response code -- %RESPONSE_FLAGS% - Response flags - -Connection information: -- %DOWNSTREAM_REMOTE_ADDRESS% - Client IP address with port -- %DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT% - Client IP address without port -- %DOWNSTREAM_LOCAL_ADDRESS% - Local address -- %DOWNSTREAM_CONNECTION_ID% - Connection ID - -Timing information: -- %START_TIME% - Request start time -- %DURATION% - Request duration - -Upstream information: -- %UPSTREAM_HOST% - Upstream host -- %UPSTREAM_CLUSTER% - Upstream Envoy cluster -- %UPSTREAM_LOCAL_ADDRESS% - Upstream local address - -Data transfer: -- %BYTES_RECEIVED% - Bytes received -- %BYTES_SENT% - Bytes sent - -For more potential values, see [Command operators in the Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage.html#command-operators). \ No newline at end of file diff --git a/assets/docs/snippets/envoy/get-started.md b/assets/docs/snippets/envoy/get-started.md deleted file mode 100644 index f4b55b540..000000000 --- a/assets/docs/snippets/envoy/get-started.md +++ /dev/null @@ -1,45 +0,0 @@ -1. Deploy the Kubernetes Gateway API CRDs. - - {{< tabs items="Standard, Experimental" tabTotal="2" >}} - {{% tab tabName="Standard" %}} - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml - ``` - {{% /tab %}} - {{% tab tabName="Experimental" %}} - CRDs in the experimental channel are required to use some experimental features in the Gateway API. Guides that require experimental CRDs note this requirement in their prerequisites. - ```sh - kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Deploy the kgateway CRDs by using Helm. - ```sh - helm upgrade -i kgateway-crds oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds \ - --create-namespace --namespace kgateway-system \ - --version v{{< reuse "agw-docs/versions/patch-dev.md" >}} \ - --set controller.image.pullPolicy=Always - ``` - -3. Install kgateway by using Helm. To use experimental Gateway API features, include the experimental feature gate, `--set controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true`. - ```sh - helm upgrade -i kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway \ - --namespace kgateway-system \ - --version v{{< reuse "agw-docs/versions/patch-dev.md" >}} \ - --set controller.image.pullPolicy=Always \ - --set controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true - ``` - -4. Make sure that the `kgateway` control plane is running. - - ```sh - kubectl get pods -n kgateway-system - ``` - - Example output: - - ```console - NAME READY STATUS RESTARTS AGE - kgateway-5495d98459-46dpk 1/1 Running 0 19s - ``` \ No newline at end of file diff --git a/assets/docs/snippets/example-basic-mcp.md b/assets/docs/snippets/example-basic-mcp.md deleted file mode 100644 index 1208fc059..000000000 --- a/assets/docs/snippets/example-basic-mcp.md +++ /dev/null @@ -1,10 +0,0 @@ -| Field | Description | -| ----- | ----------- | -| `binds` | Binds set up each port on which the agentgateway listens for incoming requests. This example configures one port. | -| `port` | The port to listen on, such as `3000`. | -| `listeners` | Listeners configure how agentgateway accepts and processes incoming requests. They do this by grouping together resources such as routes and the backends that serve traffic. | -| `routes` | Routes configure advanced routing features, such as traffic policies, that control how traffic is sent to the backends. In the example, the route matches all traffic. | -| `policies` | Policies configure traffic policies on routes that shape how traffic is sent to the backends. In the example, a basic CORS policy is configured to allow all origins and the `mcp-protocol-version` header. This way, the configuration works with the [MCP inspector tool](https://modelcontextprotocol.io/docs/tools/inspector). | -| `backends` | Backends configure the backing destination where the traffic is sent to. Backends can be MCP servers, A2A agents, or OpenAPI servers. In this example, the backend is an MCP server. | -| `targets` | Targets configure the details of the backend, such as the MCP server. In this example, the target is the sample, open source MCP test server, `server-everything`. The server runs a bunch of tools in a single process that are useful for testing. | -| `stdio` | To run the server, you use the standard input/output (`stdio`) capability of the agentgateway, which allows you to pass in the command and command arguments that you want to use. In this example, the `npx` command is used. The `npx` command utility lets you run a Node.js package (`@modelcontextprotocol/server-everything`) without installing it. If you do not have `npx` on your machine, follow the [instructions to install Node.js](https://nodejs.org/en/download). | \ No newline at end of file diff --git a/assets/docs/snippets/gatewayclass.md b/assets/docs/snippets/gatewayclass.md deleted file mode 100644 index 9090b8f64..000000000 --- a/assets/docs/snippets/gatewayclass.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway diff --git a/assets/docs/snippets/gatewayparam-apiversion.md b/assets/docs/snippets/gatewayparam-apiversion.md deleted file mode 100644 index 7704c5234..000000000 --- a/assets/docs/snippets/gatewayparam-apiversion.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway.dev/v1alpha1 diff --git a/assets/docs/snippets/gatewayparam-group.md b/assets/docs/snippets/gatewayparam-group.md deleted file mode 100644 index 6c2081605..000000000 --- a/assets/docs/snippets/gatewayparam-group.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway.dev diff --git a/assets/docs/snippets/gatewayparameters-about.md b/assets/docs/snippets/gatewayparameters-about.md deleted file mode 100644 index 6d6142cc1..000000000 --- a/assets/docs/snippets/gatewayparameters-about.md +++ /dev/null @@ -1,9 +0,0 @@ -{{< reuse "agw-docs/snippets/gatewayparameters.md" >}} is a custom resource that specifies the configuration for the gateway proxies in your cluster. - -To spin up new gateway proxies, the {{< reuse "agw-docs/snippets/kgateway.md" >}} controller uses a [gateway proxy template](#gateway-proxy-template) and the configuration in the Helm chart. You can change the default configuration for your gateway proxies by creating a custom {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. You then use this {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource to spin up different types of gateway proxies. - -{{< callout type="info" >}} -To update the default values of your gateway proxy, change the values in the {{< reuse "agw-docs/snippets/kgateway.md" >}} Helm chart so that they persist between upgrades, or create your own {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource that holds your custom values. Note that you are responsible to maintain any {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resources that you manually created. -{{< /callout >}} - -For example, you might want to pair your gateway with a Network Load Balancer (NLB) instance in AWS. To properly pair and configure the gateway with an NLB, specific annotations on the gateway proxy are required. These annotations are not included in the default gateway proxy configuration. To add them, you can create a separate {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource where you add these annotations. For more customization options, see [Customize the gateway]({{< link-hextra path="/setup/customize/" >}}). \ No newline at end of file diff --git a/assets/docs/snippets/gatewayparameters.md b/assets/docs/snippets/gatewayparameters.md deleted file mode 100644 index 6993b9f3a..000000000 --- a/assets/docs/snippets/gatewayparameters.md +++ /dev/null @@ -1 +0,0 @@ -AgentgatewayParameters diff --git a/assets/docs/snippets/gemini-setup.md b/assets/docs/snippets/gemini-setup.md deleted file mode 100644 index dc7afd218..000000000 --- a/assets/docs/snippets/gemini-setup.md +++ /dev/null @@ -1,121 +0,0 @@ -1. Save your Gemini API key as an environment variable. To retrieve your API key, [log in to the Google AI Studio and select **API Keys**](https://aistudio.google.com/app/apikey). - - ```bash - export GOOGLE_KEY= - ``` - -2. Create a secret to authenticate to Google. - - ```yaml - kubectl apply -f - <}} - type: Opaque - stringData: - Authorization: $GOOGLE_KEY - EOF - ``` - -3. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure an LLM provider that references the AI API key secret. - ```yaml - kubectl apply -f- <}} - metadata: - name: google - namespace: {{< reuse "agw-docs/snippets/namespace.md" >}} - spec: - ai: - provider: - gemini: - model: gemini-2.5-flash-lite - policies: - auth: - secretRef: - name: google-secret - EOF - ``` - - {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}). - - | Setting | Description | - |-------------|-------------| - | `ai.provider.gemini` | Define the Gemini provider. | - | `gemini.model` | The model to use to generate responses. In this example, you use the `gemini-2.5-flash-lite` model. For more models, see the [Google AI docs](https://ai.google.dev/gemini-api/docs/models). | - | `policies.auth` | The authentication token to use to authenticate to the LLM provider. The example refers to the secret that you created in the previous step. | - -4. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "docs/snippets/backend.md" >}}. The following example sets up a route on the `/gemini` path to the {{< reuse "docs/snippets/backend.md" >}} that you previously created. Note that {{< reuse "/docs/snippets/kgateway.md" >}} automatically rewrites the endpoint that you set up (such as `/gemini`) to the appropriate chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "docs/snippets/backend.md" >}} resource. - - ```yaml - kubectl apply -f- <}} - spec: - parentRefs: - - name: agentgateway-proxy - rules: - - matches: - - path: - type: PathPrefix - value: /gemini - backendRefs: - - name: google - group: agentgateway.dev - kind: {{< reuse "agw-docs/snippets/backend.md" >}} - EOF - ``` - - -5. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API. - - {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - - ````sh - curl -vik "$INGRESS_GW_ADDRESS/gemini" -H content-type:application/json -d '{ - "model": "", - "messages": [ - {"role": "user", "content": "Explain how AI works in simple terms."} - ] - }' - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - curl -vik "localhost:8080/gemini" -H content-type:application/json -d '{ - "model": "", - "messages": [ - {"role": "user", "content": "Explain how AI works in simple terms."} - ] - }' - ```` - - {{% /tab %}} - {{< /tabs >}} - - Example output: - - ```json - {"id":"aGLEaMjbLp6p_uMPopeAoAc", - "choices": - [{"index":0,"message":{ - "content":"Imagine teaching a dog a trick. You show it what to do, reward it when it's right, and correct it when it's wrong. Eventually, the dog learns.\n\nAI is similar. We \"teach\" computers by showing them lots of examples. For example, to recognize cats in pictures, we show it thousands of pictures of cats, labeling each one \"cat.\" The AI learns patterns in these pictures – things like pointy ears, whiskers, and furry bodies – and eventually, it can identify a cat in a new picture it's never seen before.\n\nThis learning process uses math and algorithms (like a secret code of instructions) to find patterns and make predictions. Some AI is more like a dog learning tricks (learning from examples), and some is more like following a very detailed recipe (following pre-programmed rules).\n\nSo, in short: AI is about teaching computers to learn from data and make decisions or predictions, just like we teach dogs tricks.\n", - "role":"assistant" - }, - "finish_reason":"stop" - }], - "created":1757700714, - "model":"gemini-1.5-flash-latest", - "object":"chat.completion", - "usage":{ - "prompt_tokens":8, - "completion_tokens":205, - "total_tokens":213 - } - } - ``` \ No newline at end of file diff --git a/assets/docs/snippets/generic-listener.md b/assets/docs/snippets/generic-listener.md deleted file mode 100644 index 261d6a74a..000000000 --- a/assets/docs/snippets/generic-listener.md +++ /dev/null @@ -1 +0,0 @@ -Optionally, you can configure a listener that is specific to the Gateway. Note that due to a [Gateway API limitation](https://gateway-api.sigs.k8s.io/geps/gep-1713/#gateway-changes), you must configure at least one listener on the Gateway resource, even if the listener is not used and is a generic, "dummy" listener. This generic listener cannot conflict with the listener that you configure in the ListenerSet, such as using the same port or name. \ No newline at end of file diff --git a/assets/docs/snippets/get-started.md b/assets/docs/snippets/get-started.md deleted file mode 100644 index 6987dff94..000000000 --- a/assets/docs/snippets/get-started.md +++ /dev/null @@ -1,43 +0,0 @@ -1. Deploy the Kubernetes Gateway API CRDs. - - {{< tabs items="Standard, Experimental" tabTotal="2" >}} - {{% tab tabName="Standard" %}} - ```sh - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml - ``` - {{% /tab %}} - {{% tab tabName="Experimental" %}} - CRDs in the experimental channel are required to use some experimental features in the Gateway API. Guides that require experimental CRDs note this requirement in their prerequisites. - ```sh - kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml - ``` - {{% /tab %}} - {{< /tabs >}} - -2. Deploy the kgateway CRDs by using Helm. - ```sh - helm upgrade -i kgateway-crds oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds \ - --create-namespace --namespace kgateway-system \ - --version v{{< reuse "agw-docs/versions/n-patch.md" >}} - ``` - -3. Install kgateway by using Helm. - ```sh - helm upgrade -i kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway \ - --namespace kgateway-system \ - --version v{{< reuse "agw-docs/versions/n-patch.md" >}} \ - --set controller.image.pullPolicy=Always - ``` - -4. Make sure that the `kgateway` control plane is running. - - ```sh - kubectl get pods -n kgateway-system - ``` - - Example output: - - ```console - NAME READY STATUS RESTARTS AGE - kgateway-5495d98459-46dpk 1/1 Running 0 19s - ``` \ No newline at end of file diff --git a/assets/docs/snippets/header-control-options.md b/assets/docs/snippets/header-control-options.md deleted file mode 100644 index 2eaab4c5b..000000000 --- a/assets/docs/snippets/header-control-options.md +++ /dev/null @@ -1,4 +0,0 @@ -You can configure the header modifier filter at two levels: - -* **HTTPRoute**: For the native way in Kubernetes Gateway API, configure a header modifier filter in the HTTPRoute. You can choose to apply the header modifier filter to all the routes that are defined in the HTTPRoute, or to a selection of `backendRefs`. This route-level policy takes precedence over any {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that you might configure. For more information, see the [Kubernetes Gateway API docs](https://gateway-api.sigs.k8s.io/guides/http-header-modifier/). -* **{{< reuse "agw-docs/snippets/trafficpolicy.md" >}} (Envoy-based kgateway proxy only)**: For more flexibility to reuse the header modifier filter across HTTPRoutes, specific routes and Gateways, configure a header modifier filter in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. You can attach a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to a Gateway, all HTTPRoutes via `targetRefs`, or an individual route via `extensionRef`. To attach to a `backendRef`, use a header modifier filter in the HTTPRoute instead. For more information about attachment and merging rules, see the [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}} concept docs]({{< link-hextra path="/about/policies/trafficpolicy/" >}}). diff --git a/assets/docs/snippets/helm-kgateway-crds.md b/assets/docs/snippets/helm-kgateway-crds.md deleted file mode 100644 index cb570bfb5..000000000 --- a/assets/docs/snippets/helm-kgateway-crds.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway-crds diff --git a/assets/docs/snippets/helm-kgateway.md b/assets/docs/snippets/helm-kgateway.md deleted file mode 100644 index 9090b8f64..000000000 --- a/assets/docs/snippets/helm-kgateway.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway diff --git a/assets/docs/snippets/helm-path.md b/assets/docs/snippets/helm-path.md deleted file mode 100644 index b58508c6a..000000000 --- a/assets/docs/snippets/helm-path.md +++ /dev/null @@ -1 +0,0 @@ -ghcr.io/kgateway-dev diff --git a/assets/docs/snippets/inference-diagram.md b/assets/docs/snippets/inference-diagram.md deleted file mode 100644 index 5bf734db3..000000000 --- a/assets/docs/snippets/inference-diagram.md +++ /dev/null @@ -1,14 +0,0 @@ -```mermaid -graph LR - Client -->|inference request| agentgateway - agentgateway -->|routes to| InferencePool - subgraph - subgraph InferencePool - direction LR - InferenceModel_v1 - InferenceModel_v2 - InferenceModel_v3 - end - agentgateway - end -``` \ No newline at end of file diff --git a/assets/docs/snippets/jaeger.md b/assets/docs/snippets/jaeger.md deleted file mode 100644 index add53c99c..000000000 --- a/assets/docs/snippets/jaeger.md +++ /dev/null @@ -1,10 +0,0 @@ -Use [`docker compose`](https://docs.docker.com/compose/install/linux/) to spin up a Jaeger instance with the following components: -* An OpenTelemetry collector that receives traces from the agentgateway. The collector is exposed on `http://localhost:4317`. -* A Jaeger agent that receives the collected traces. The agent is exposed on `http://localhost:14268`. -* A Jaeger UI that is exposed on `http://localhost:16686`. - -```sh -docker compose -f - up -d <}} -EOF -``` \ No newline at end of file diff --git a/assets/docs/snippets/k8s-gateway-api-name.md b/assets/docs/snippets/k8s-gateway-api-name.md deleted file mode 100644 index 6182e134b..000000000 --- a/assets/docs/snippets/k8s-gateway-api-name.md +++ /dev/null @@ -1 +0,0 @@ -Kubernetes Gateway API \ No newline at end of file diff --git a/assets/docs/snippets/k8sgwapi-exp.md b/assets/docs/snippets/k8sgwapi-exp.md deleted file mode 100644 index 8d25eaab9..000000000 --- a/assets/docs/snippets/k8sgwapi-exp.md +++ /dev/null @@ -1,29 +0,0 @@ -The following features are experimental in the upstream Kubernetes Gateway API project, and are subject to change. - -| Feature | Minimum Gateway API version | -| --- | --- | -| [ListenerSets]({{< link-hextra path="/setup/listeners/overview/#listenersets" >}}) | 1.3 | -| [TCPRoutes]({{< link-hextra path="/setup/listeners/tcp/" >}})| 1.3 | -| [BackendTLSPolicy]({{< link-hextra path="/security/backend-tls/" >}})| 1.4 | -| [CORS policies]({{< link-hextra path="/security/cors/" >}}) | 1.2 | -| [Retries]({{< link-hextra path="/resiliency/retry/" >}}) | 1.2 | -| [Session persistence]({{< link-hextra path="/traffic-management/session-affinity/session-persistence" >}}) | 1.3 | -| [HTTPRoute rule attachment option]({{< link-hextra path="/about/policies/trafficpolicy/#attach-to-rule" >}}) | 1.3 | - - -{{< callout type="warning" >}} -**Experimental feature gate**: To use experimental Gateway API features in kgateway version 2.2 or later, you must enable the `KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES` environment variable in your kgateway controller deployment. This setting defaults to `false` and must be explicitly enabled. For example, you might upgrade your installation with the following Helm value: - -```yaml -controller: - extraEnv: - KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES: "true" -``` -{{< /callout >}} - - -**Sample command for version {{< reuse "agw-docs/versions/k8s-gw-version.md" >}}**: Note that some CRDs are prefixed with `X` to indicate that the entire CRD is experimental and subject to change. - -```sh -kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml -``` diff --git a/assets/docs/snippets/key-benefits.md b/assets/docs/snippets/key-benefits.md deleted file mode 100644 index 59a9d949f..000000000 --- a/assets/docs/snippets/key-benefits.md +++ /dev/null @@ -1,12 +0,0 @@ -* **Unified data plane**: Agentgateway is a unified data plane to manage agent connectivity with support for agent protocols including MCP and A2A, and the ability to integrate existing REST APIs as agent-native tools. -* **Highly performant**: Built in Rust, agentgateway is designed to handle any scale. It is optimized for high throughput, low latency, reliability, and stability when handling long-lived connections and fan-out patterns. -* **Any agent framework**: Agentgateway is compatible with any agentic framework supporting MCP and A2A protocols, including LangGraph, AutoGen, kagent, Claude Desktop, and OpenAI SDK. You can also use agentgateway to expose a REST API as an agent-native tool. -* **Platform-agnostic**: Agentgateway can run in any environment, including bare metal, virtual machine, containers, and Kubernetes. -* **Multiplexing and tool federation**: Agentgateway provides a single endpoint to federate multiple backend MCP servers and virtualize tool servers on a per-client basis. -* **Automatic protocol upgrades/fallbacks**: Agentgateway is built to negotiate and gracefully handle protocol upgrades and fallbacks to avoid client or server failures as the MCP/A2A protocols evolve. -* **Authentication and authorization**: Built-in JWT authentication and a robust RBAC system allow you to control access to MCP servers, tools and agents, and to protect against [tool poisoning attacks](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks). -* **Built-in observability**: Agentgateway comes with built-in metrics and tracing capabilities that allow you to monitor the MCP client and backend tool interactions. -* **Self-service portal**: Agentgateway provides a built-in self-service developer portal that allows agent developers to easily connect, discover, federate, integrate, and secure agents and tools in any environment, including bare metal, VMs, containers, and Kubernetes. -* **Open source**: Agentgateway is open source, and licensed under the Apache 2.0 license. -* **Conformant to the Gateway API project**: Agentgateway is conformant to the Kubernetes Gateway API project, which allows you to use it as a gateway with any Gateway API implementation. -* **Dynamic configuration updates**: Agentgateway can be updated via an xDS interface without any downtime. \ No newline at end of file diff --git a/assets/docs/snippets/keycloak.md b/assets/docs/snippets/keycloak.md deleted file mode 100644 index 963e1c8f9..000000000 --- a/assets/docs/snippets/keycloak.md +++ /dev/null @@ -1,124 +0,0 @@ -## Install Keycloak {#install} - -You might want to test how to restrict access to your applications to authenticated users, such as with external auth or JWT policies. You can install Keycloak in your cluster as an OpenID Connect (OIDC) provider. - -The following steps install Keycloak in your cluster, and configure two user credentials as follows. -* Username: `user1`, password: `password`, email: `user1@example.com` -* Username: `user2`, password: `password`, email: `user2@solo.io` - -Install and configure Keycloak: - -1. Create a namespace for your Keycloak deployment. - ```shell - kubectl create namespace keycloak - ``` -2. Create the Keycloak deployment. - ```shell - kubectl -n keycloak apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/oidc/keycloak.yaml - ``` -3. Wait for the Keycloak rollout to finish. - ```shell - kubectl -n keycloak rollout status deploy/keycloak - ``` -4. Set the Keycloak endpoint details from the load balancer service. If you are running locally in kind and need a local IP address for the load balancer service, consider using [`cloud-provider-kind`](https://github.com/kubernetes-sigs/cloud-provider-kind). - ```shell - export ENDPOINT_KEYCLOAK=$(kubectl -n keycloak get service keycloak -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}'):8080 - export HOST_KEYCLOAK=$(echo ${ENDPOINT_KEYCLOAK} | cut -d: -f1) - export PORT_KEYCLOAK=$(echo ${ENDPOINT_KEYCLOAK} | cut -d: -f2) - export KEYCLOAK_URL=http://${ENDPOINT_KEYCLOAK} - echo $KEYCLOAK_URL - ``` -5. Set the Keycloak admin token. If you see a parsing error, try running the `curl` command by itself. You might notice that your internet provider or network rules are blocking the requests. If so, you can update your security settings or change the network so that the request can be processed. - ```shell - export KEYCLOAK_TOKEN=$(curl -d "client_id=admin-cli" -d "username=admin" -d "password=admin" -d "grant_type=password" "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" | jq -r .access_token) - echo $KEYCLOAK_TOKEN - ``` - -6. Use the admin token to configure Keycloak with the two users for testing purposes. If you get a `401 Unauthorized` error, run the previous command and try again. - ```shell - # Create initial token to register the client - read -r client token <<<$(curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"expiration": 0, "count": 1}' $KEYCLOAK_URL/admin/realms/master/clients-initial-access | jq -r '[.id, .token] | @tsv') - export KEYCLOAK_CLIENT=${client} - echo $KEYCLOAK_CLIENT - - # Register the client - read -r id secret <<<$(curl -k -X POST -d "{ \"clientId\": \"${KEYCLOAK_CLIENT}\" }" -H "Content-Type:application/json" -H "Authorization: bearer ${token}" ${KEYCLOAK_URL}/realms/master/clients-registrations/default| jq -r '[.id, .secret] | @tsv') - export KEYCLOAK_SECRET=${secret} - echo $KEYCLOAK_SECRET - - # Add allowed redirect URIs - curl -k -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X PUT -H "Content-Type: application/json" -d '{"serviceAccountsEnabled": true, "directAccessGrantsEnabled": true, "authorizationServicesEnabled": true, "redirectUris": ["*"]}' $KEYCLOAK_URL/admin/realms/master/clients/${id} - - # Add the group attribute in the JWT token returned by Keycloak - curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"name": "group", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-attribute-mapper", "config": {"claim.name": "group", "jsonType.label": "String", "user.attribute": "group", "id.token.claim": "true", "access.token.claim": "true"}}' $KEYCLOAK_URL/admin/realms/master/clients/${id}/protocol-mappers/models - - # Create first user - curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"username": "user1", "email": "user1@example.com", "firstName": "Alice", "lastName": "Doe", "enabled": true, "attributes": {"group": "users"}, "credentials": [{"type": "password", "value": "password", "temporary": false}]}' $KEYCLOAK_URL/admin/realms/master/users - - # Create second user - curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"username": "user2", "email": "user2@solo.io", "firstName": "Bob", "lastName": "Doe", "enabled": true, "attributes": {"group": "users"}, "credentials": [{"type": "password", "value": "password", "temporary": false}]}' $KEYCLOAK_URL/admin/realms/master/users - - # Remove the trusted-hosts client registration policies (testing-purpose only) - trusted_hosts=$(curl -v -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" \ - "${KEYCLOAK_URL}/admin/realms/master/components?type=org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" \ - | jq -r ' - if type=="array" then - .[] | select(.providerId=="trusted-hosts") | .id - else - empty - end - ') - - curl -X DELETE \ - -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" \ - "${KEYCLOAK_URL}/admin/realms/master/components/${trusted_hosts}" - - # Remove the allowed-client-templates client registration policies (testing-purpose only) - - allowed_client_templates=$(curl -v \ - -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" \ - "${KEYCLOAK_URL}/admin/realms/master/components?type=org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" \ - | jq -r ' - .[] - | select(.providerId=="allowed-client-templates" and .subType=="anonymous") - | .id - ') - - curl -X DELETE \ - -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" \ - "${KEYCLOAK_URL}/admin/realms/master/components/${allowed_client_templates}" - ``` - -7. Open the Keycloak frontend. - ``` - open $KEYCLOAK_URL - ``` - -8. Log in to the admin console, and enter `admin` as the username and `admin` as your password. - -9. In the Keycloak admin console, go to **Users**, and verify that the users that created earlier are displayed. You might need to click on **View all users** to see them. - -10. In the Keycloak admin console, go to **Clients**, and verify that you can see a client ID that equals the output of `$KEYCLOAK_CLIENT`. - -## Retrieve JWKS path and issuer URL {#configure} - -You might integrate OIDC with your apps. In such cases, you might need particular details from the OIDC provider to fully set up your apps. To use Keycloak for OAuth protection of these apps, you need certain settings and information from Keycloak. - -The following instructions assume that you are still logged into the **Administration Console** from the previous step. - -1. Confirm that you have the following environmental variables set. If not, refer to [Step 1: Install Keycloak](#install) section. - ```shell - echo $KEYCLOAK_URL - ``` - -2. Get the issuer and JWKS path. The agentgateway proxy uses these values to validate the JWTs. - 1. From the sidebar menu options, click **Realm Settings**. - 2. From the **General** tab, scroll down to the **Endpoints** section and open the **OpenID Endpoint Configuration** link. In a new tab, your browser opens to a URL similar to `http://$KEYCLOAK_URL:8080/realms/master/.well-known/openid-configuration`. - 3. In the OpenID configuration, search for the `issuer` field. Save the value as an environment variable, such as the following example. - ```sh - export KEYCLOAK_ISSUER=$KEYCLOAK_URL/realms/master - ``` - 4. In the OpenID configuration, search for the `jwks_uri` field, and copy the path without the Keycloak URL that you retrieved earlier. For example, the path might be set to `/realms/master/protocol/openid-connect/certs`. - ```shell - export KEYCLOAK_JWKS_PATH=/realms/master/protocol/openid-connect/certs - ``` \ No newline at end of file diff --git a/assets/docs/snippets/kgateway-about.md b/assets/docs/snippets/kgateway-about.md deleted file mode 100644 index 2ba05951e..000000000 --- a/assets/docs/snippets/kgateway-about.md +++ /dev/null @@ -1 +0,0 @@ -{{< reuse "agw-docs/snippets/kgateway-capital.md" >}} is a control plane that implements the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/) for both microservices and AI workloads. The control plane translates your Kubernetes Gateway API resources into the configuration that the underlying data plane proxy can understand. The proxy layer is handled by kgateway's implementation of [Envoy](https://www.envoyproxy.io/) for microservices or [agentgateway](https://agentgateway.dev/) for AI workloads. \ No newline at end of file diff --git a/assets/docs/snippets/kgateway-and-data-plane.md b/assets/docs/snippets/kgateway-and-data-plane.md deleted file mode 100644 index 3a0e314ef..000000000 --- a/assets/docs/snippets/kgateway-and-data-plane.md +++ /dev/null @@ -1 +0,0 @@ -kgateway with the agentgateway data plane diff --git a/assets/docs/snippets/kgateway-callout.md b/assets/docs/snippets/kgateway-callout.md deleted file mode 100644 index c8bf1e071..000000000 --- a/assets/docs/snippets/kgateway-callout.md +++ /dev/null @@ -1,3 +0,0 @@ -{{< callout icon="kgateway" >}} -Want to use agentgateway in a Kubernetes environment with the Gateway API? Check out the [agentgateway on Kubernetes docs](https://agentgateway.dev/docs/kubernetes/). -{{< /callout >}} \ No newline at end of file diff --git a/assets/docs/snippets/kgateway-capital.md b/assets/docs/snippets/kgateway-capital.md deleted file mode 100644 index bdded7da3..000000000 --- a/assets/docs/snippets/kgateway-capital.md +++ /dev/null @@ -1 +0,0 @@ -Kgateway \ No newline at end of file diff --git a/assets/docs/snippets/kgateway.md b/assets/docs/snippets/kgateway.md deleted file mode 100644 index 16008aa0e..000000000 --- a/assets/docs/snippets/kgateway.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway \ No newline at end of file diff --git a/assets/docs/snippets/kgwctl-global-flags.md b/assets/docs/snippets/kgwctl-global-flags.md deleted file mode 100644 index 5b0ed3558..000000000 --- a/assets/docs/snippets/kgwctl-global-flags.md +++ /dev/null @@ -1,23 +0,0 @@ -## Global flags - -```yaml ---as string The username to impersonate for the operation. The username can be a regular user or a service account in a namespace. ---as-group stringArray The group to impersonate for the operation. This flag can be repeated to specify multiple groups. ---as-uid string The UID to impersonate for the operation. ---cache-dir string The default cache directory. (default "/Users/[user]/.kube/cache") ---certificate-authority string The path to a file that contains the certificate for the Certificate Authority. ---client-certificate string The path to a client certificate file to use to authenticate with the Kubernetes API server. ---client-key string The path to a client key file to use for TLS connections to the Kubernetes API server. ---cluster string The name of the cluster to use. ---context string The name of the kubeconfig context to use. ---disable-compression If true, opt out of response compression for all requests to the server. ---insecure-skip-tls-verify If true, the server's certificate is not checked for validity. ---kubeconfig string The path to the kubeconfig file to use for CLI requests. --n, --namespace string The namespace scope for this CLI request. ---request-timeout string The length of time to wait before a server request is considered failed. Non-zero values must contain a corresponding time unit, such as 1s, 2m, 3h, etc. If set to zero ("0"), no timeouts are applied to CLI requests. (default "0") --s, --server string The address and port of the Kubernetes API server. ---tls-server-name string The server name to use for server certificate validation. If not provided, the hostname that is used to contact the Kubernetes API server is used. ---token string The bearer token for authentication to the API server. ---user string The name of the kubeconfig user to use. --v, --v int The number for the log level verbosity. (defaults to 0) -``` \ No newline at end of file diff --git a/assets/docs/snippets/latest/metrics-control-plane.md b/assets/docs/snippets/latest/metrics-control-plane.md deleted file mode 100644 index c6137bdd0..000000000 --- a/assets/docs/snippets/latest/metrics-control-plane.md +++ /dev/null @@ -1,24 +0,0 @@ -Name|Type|Labels|Help ---|--|--|-- -kgateway_controller_reconcile_duration_seconds|histogram|controller, name, namespace|Reconcile duration for controller -kgateway_controller_reconciliations_running|gauge|controller, name, namespace|Number of reconciliations currently running -kgateway_controller_reconciliations_total|counter|controller, name, namespace, result|Total number of controller reconciliations -kgateway_resources_managed|gauge|namespace, parent, resource|Current number of resources managed -kgateway_resources_status_sync_duration_seconds|histogram|gateway, namespace, resource|Duration of time for a resource update to receive a status report -kgateway_resources_status_syncs_completed_total|counter|gateway, namespace, resource|Total number of status syncs completed for resources -kgateway_resources_status_syncs_started_total|counter|gateway, namespace, resource|Total number of status syncs started -kgateway_resources_updates_dropped_total|counter||Total number of resources metrics updates dropped. If this metric is ever greater than 0, all resources subsystem metrics should be considered invalid until process restart -kgateway_routing_domains|gauge|namespace, gateway, port|Number of domains per listener -kgateway_status_syncer_status_sync_duration_seconds|histogram|name, namespace, syncer|Status sync duration -kgateway_status_syncer_status_syncs_total|counter|name, namespace, syncer, result|Total number of status syncs -kgateway_translator_translation_duration_seconds|histogram|name, namespace, translator|Translation duration -kgateway_translator_translations_running|gauge|name, namespace, translator|Current number of translations running -kgateway_translator_translations_total|counter|name, namespace, translator, result|Total number of translations -kgateway_xds_auth_rq_failure_total|counter||Total number of failed xDS auth requests -kgateway_xds_auth_rq_success_total|counter||Total number of successful xDS auth requests -kgateway_xds_auth_rq_total|counter||Total number of xDS auth requests -kgateway_xds_snapshot_resources|gauge|gateway, namespace, resource|Current number of resources in XDS snapshot -kgateway_xds_snapshot_sync_duration_seconds|histogram|gateway, namespace|Duration of time for a gateway resource update to be synced in an XDS snapshot -kgateway_xds_snapshot_syncs_total|counter|gateway, namespace|Total number of XDS snapshot syncs -kgateway_xds_snapshot_transform_duration_seconds|histogram|gateway, namespace|XDS snapshot transform duration -kgateway_xds_snapshot_transforms_total|counter|gateway, namespace, result|Total number of XDS snapshot transforms diff --git a/assets/docs/snippets/listeners-https-create-cert.md b/assets/docs/snippets/listeners-https-create-cert.md deleted file mode 100644 index 4663a6a7d..000000000 --- a/assets/docs/snippets/listeners-https-create-cert.md +++ /dev/null @@ -1,47 +0,0 @@ -1. Create a directory to store your TLS credentials in. - ```sh - mkdir example_certs - ``` - -2. Create a self-signed root certificate. The following command creates a root certificate that is valid for a year and can serve any hostname. You use this certificate to sign the server certificate for the gateway later. For other command options, see the [OpenSSL docs](https://www.openssl.org/docs/manmaster/man1/openssl-req.html). - ```sh - # root cert - openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=any domain/CN=*' -keyout example_certs/root.key -out example_certs/root.crt - ``` - -3. Create an OpenSSL configuration that matches the HTTPS hostname you plan to use. Replace every `example.com` reference with the base domain that your listener serves. - ```sh - cat <<'EOF' > example_certs/gateway.cnf - [ req ] - default_bits = 2048 - prompt = no - default_md = sha256 - distinguished_name = dn - req_extensions = req_ext - [ dn ] - CN = *.example.com - O = any domain - [ req_ext ] - subjectAltName = @alt_names - [ alt_names ] - DNS.1 = *.example.com - DNS.2 = example.com - EOF - ``` - -4. Use the configuration and root certificate to create and sign the gateway certificate. - ```sh - openssl req -new -nodes -keyout example_certs/gateway.key -out example_certs/gateway.csr -config example_certs/gateway.cnf - openssl x509 -req -sha256 -days 365 \ - -CA example_certs/root.crt -CAkey example_certs/root.key -set_serial 0 \ - -in example_certs/gateway.csr -out example_certs/gateway.crt \ - -extfile example_certs/gateway.cnf -extensions req_ext - ``` - -5. Create a Kubernetes secret to store your server TLS certificate. You create the secret in the same cluster and namespace that the gateway is deployed to. - ```sh - kubectl create secret tls -n {{< reuse "agw-docs/snippets/namespace.md" >}} https \ - --key example_certs/gateway.key \ - --cert example_certs/gateway.crt - kubectl label secret https gateway=https --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} - ``` diff --git a/assets/docs/snippets/llm-providers.md b/assets/docs/snippets/llm-providers.md deleted file mode 100644 index dc2459be7..000000000 --- a/assets/docs/snippets/llm-providers.md +++ /dev/null @@ -1,16 +0,0 @@ -### Cloud providers {#cloud-providers} - -Kgateway supports the following AI cloud providers: - -* [Anthropic](https://docs.anthropic.com/en/release-notes/api) -* [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/) -* [Gemini](https://ai.google.dev/gemini-api/docs) -* [OpenAI](https://platform.openai.com/docs/overview). You can also use `openai` support for LLM providers that use the OpenAI API, such as [DeepSeek](https://api-docs.deepseek.com/) and [Mistral](https://docs.mistral.ai/getting-started/quickstart/). -* [Vertex AI](https://cloud.google.com/vertex-ai/docs) - -### Local providers {#local-providers} - -You can use kgateway with a local LLM provider, such as the following common options: - -* [Ollama]({{< link-hextra path="/ai/ollama/" >}}) for local LLM development. -* [Gateway API Inference Extension project]({{< link-hextra path="/integrations/inference-extension/" >}}) to route requests to local LLM workloads that run in your cluster. \ No newline at end of file diff --git a/assets/docs/snippets/main/metrics-control-plane.md b/assets/docs/snippets/main/metrics-control-plane.md deleted file mode 100644 index c9b07fc22..000000000 --- a/assets/docs/snippets/main/metrics-control-plane.md +++ /dev/null @@ -1,27 +0,0 @@ -Name|Type|Labels|Help ---|--|--|-- -kgateway_agentgateway_xds_rejects_total|counter||Total number of xDS responses rejected by agentgateway proxy -kgateway_controller_reconcile_duration_seconds|histogram|controller, name, namespace|Reconcile duration for controller -kgateway_controller_reconciliations_running|gauge|controller, name, namespace|Number of reconciliations currently running -kgateway_controller_reconciliations_total|counter|controller, name, namespace, result|Total number of controller reconciliations -kgateway_envoy_xds_rejects_active|gauge|gateway_namespace, gateway_name, type_url|Number of xDS responses currently rejected by envoy proxy -kgateway_envoy_xds_rejects_total|counter|gateway_namespace, gateway_name, type_url|Total number of xDS responses rejected by envoy proxy -kgateway_resources_managed|gauge|namespace, parent, resource|Current number of resources managed -kgateway_resources_status_sync_duration_seconds|histogram|gateway, namespace, resource|Duration of time for a resource update to receive a status report -kgateway_resources_status_syncs_completed_total|counter|gateway, namespace, resource|Total number of status syncs completed for resources -kgateway_resources_status_syncs_started_total|counter|gateway, namespace, resource|Total number of status syncs started -kgateway_resources_updates_dropped_total|counter||Total number of resources metrics updates dropped. If this metric is ever greater than 0, all resources subsystem metrics should be considered invalid until process restart -kgateway_routing_domains|gauge|namespace, gateway, port|Number of domains per listener -kgateway_status_syncer_status_sync_duration_seconds|histogram|name, namespace, syncer|Status sync duration -kgateway_status_syncer_status_syncs_total|counter|name, namespace, syncer, result|Total number of status syncs -kgateway_translator_translation_duration_seconds|histogram|name, namespace, translator|Translation duration -kgateway_translator_translations_running|gauge|name, namespace, translator|Current number of translations running -kgateway_translator_translations_total|counter|name, namespace, translator, result|Total number of translations -kgateway_xds_auth_rq_failure_total|counter||Total number of failed xDS auth requests -kgateway_xds_auth_rq_success_total|counter||Total number of successful xDS auth requests -kgateway_xds_auth_rq_total|counter||Total number of xDS auth requests -kgateway_xds_snapshot_resources|gauge|gateway, namespace, resource|Current number of resources in XDS snapshot -kgateway_xds_snapshot_sync_duration_seconds|histogram|gateway, namespace|Duration of time for a gateway resource update to be synced in an XDS snapshot -kgateway_xds_snapshot_syncs_total|counter|gateway, namespace|Total number of XDS snapshot syncs -kgateway_xds_snapshot_transform_duration_seconds|histogram|gateway, namespace|XDS snapshot transform duration -kgateway_xds_snapshot_transforms_total|counter|gateway, namespace, result|Total number of XDS snapshot transforms diff --git a/assets/docs/snippets/mcp-policy-note.md b/assets/docs/snippets/mcp-policy-note.md deleted file mode 100644 index 5fcaed5cb..000000000 --- a/assets/docs/snippets/mcp-policy-note.md +++ /dev/null @@ -1 +0,0 @@ -This policy works only for [MCP](https://modelcontextprotocol.io/) traffic. Note that all standard HTTP policies also apply to MCP traffic. \ No newline at end of file diff --git a/assets/docs/snippets/metrics-control-plane.md b/assets/docs/snippets/metrics-control-plane.md deleted file mode 100644 index 7f891565a..000000000 --- a/assets/docs/snippets/metrics-control-plane.md +++ /dev/null @@ -1,21 +0,0 @@ -Name|Type|Labels|Help ---|--|--|-- -kgateway_controller_reconcile_duration_seconds|histogram|controller, name, namespace|Reconcile duration for controller -kgateway_controller_reconciliations_running|gauge|controller, name, namespace|Number of reconciliations currently running -kgateway_controller_reconciliations_total|counter|controller, name, namespace, result|Total number of controller reconciliations -kgateway_resources_managed|gauge|namespace, parent, resource|Current number of resources managed -kgateway_resources_status_sync_duration_seconds|histogram|gateway, namespace, resource|Duration of time for a resource update to receive a status report -kgateway_resources_status_syncs_completed_total|counter|gateway, namespace, resource|Total number of status syncs completed for resources -kgateway_resources_status_syncs_started_total|counter|gateway, namespace, resource|Total number of status syncs started -kgateway_resources_updates_dropped_total|counter||Total number of resources metrics updates dropped. If this metric is ever greater than 0, all resources subsystem metrics should be considered invalid until process restart -kgateway_routing_domains|gauge|namespace, gateway, port|Number of domains per listener -kgateway_status_syncer_status_sync_duration_seconds|histogram|name, namespace, syncer|Status sync duration -kgateway_status_syncer_status_syncs_total|counter|name, namespace, syncer, result|Total number of status syncs -kgateway_translator_translation_duration_seconds|histogram|name, namespace, translator|Translation duration -kgateway_translator_translations_running|gauge|name, namespace, translator|Current number of translations running -kgateway_translator_translations_total|counter|name, namespace, translator, result|Total number of translations -kgateway_xds_snapshot_resources|gauge|gateway, namespace, resource|Current number of resources in XDS snapshot -kgateway_xds_snapshot_sync_duration_seconds|histogram|gateway, namespace|Duration of time for a gateway resource update to be synced in an XDS snapshot -kgateway_xds_snapshot_syncs_total|counter|gateway, namespace|Total number of XDS snapshot syncs -kgateway_xds_snapshot_transform_duration_seconds|histogram|gateway, namespace|XDS snapshot transform duration -kgateway_xds_snapshot_transforms_total|counter|gateway, namespace, result|Total number of XDS snapshot transforms diff --git a/assets/docs/snippets/namespace.md b/assets/docs/snippets/namespace.md deleted file mode 100644 index 34eea3c85..000000000 --- a/assets/docs/snippets/namespace.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway-system diff --git a/assets/docs/snippets/one-install.md b/assets/docs/snippets/one-install.md deleted file mode 100644 index 68c8247f1..000000000 --- a/assets/docs/snippets/one-install.md +++ /dev/null @@ -1 +0,0 @@ -Keep in mind that you can only have one installation of {{< reuse "/agw-docs/snippets/kgateway.md" >}} at a time. Installing the product twice makes cluster-scoped resources fail, such as GatewayClass. You can still create multiple Gateway resources with different HTTP and HTTPS listeners so that you can have multiple gateway proxies. \ No newline at end of file diff --git a/assets/docs/snippets/osa-provided.md b/assets/docs/snippets/osa-provided.md deleted file mode 100644 index 7d4d47de5..000000000 --- a/assets/docs/snippets/osa-provided.md +++ /dev/null @@ -1,51 +0,0 @@ -Name|Version|License ----|---|--- -[avast/retry-go](https://github.com/avast/retry-go)|v2.4.3+incompatible|MIT License -[retry-go/v4](https://github.com/avast/retry-go)|v4.3.3|MIT License -[xds/go](https://github.com/cncf/xds)|v0.0.0-20250121191232-2f005788dc42|Apache License 2.0 -[envoyproxy/go-control-plane](https://github.com/envoyproxy/go-control-plane)|v0.13.5-0.20250123154839-2a6715911fec|Apache License 2.0 -[go-control-plane/contrib](https://github.com/envoyproxy/go-control-plane)|v1.32.5-0.20250207140015-90270e3c85fd|Apache License 2.0 -[go-control-plane/envoy](https://github.com/envoyproxy/go-control-plane)|v1.32.5-0.20250211152746-ef139ef8ea6b|Apache License 2.0 -[go-control-plane/ratelimit](https://github.com/envoyproxy/go-control-plane)|v0.1.0|Apache License 2.0 -[fgrosse/zaptest](https://github.com/fgrosse/zaptest)|v1.1.0|MIT License -[fsnotify/fsnotify](https://github.com/fsnotify/fsnotify)|v1.8.0|BSD 3-clause "New" or "Revised" License -[ghodss/yaml](https://github.com/ghodss/yaml)|v1.0.1-0.20190212211648-25d852aebe32|MIT License -[go-logr/logr](https://github.com/go-logr/logr)|v1.4.2|Apache License 2.0 -[go-logr/zapr](https://github.com/go-logr/zapr)|v1.3.0|Apache License 2.0 -[google/go-cmp](https://github.com/google/go-cmp)|v0.6.0|BSD 3-clause "New" or "Revised" License -[grpc-ecosystem/go-grpc-middleware](https://github.com/grpc-ecosystem/go-grpc-middleware)|v1.4.0|Apache License 2.0 -[kelseyhightower/envconfig](https://github.com/kelseyhightower/envconfig)|v1.4.0|MIT License -[mitchellh/hashstructure](https://github.com/mitchellh/hashstructure)|v1.0.0|MIT License -[ginkgo/v2](https://github.com/onsi/ginkgo)|v2.22.2|MIT License -[onsi/gomega](https://github.com/onsi/gomega)|v1.36.2|MIT License -[pkg/errors](https://github.com/pkg/errors)|v0.9.1|BSD 2-clause "Simplified" License -[rotisserie/eris](https://github.com/rotisserie/eris)|v0.5.4|MIT License -[spf13/afero](https://github.com/spf13/afero)|v1.12.0|Apache License 2.0 -[spf13/cobra](https://github.com/spf13/cobra)|v1.8.1|Apache License 2.0 -[stretchr/testify](https://github.com/stretchr/testify)|v1.10.0|MIT License -[go.opencensus.io](https://go.opencensus.io)|v0.24.0|Apache License 2.0 -[go.uber.org/zap](https://go.uber.org/zap)|v1.27.0|MIT License -[x/exp](https://golang.org/x/exp)|v0.0.0-20241215155358-4a5509556b9e|BSD 3-clause "New" or "Revised" License -[x/net](https://golang.org/x/net)|v0.37.0|BSD 3-clause "New" or "Revised" License -[google.golang.org/grpc](https://google.golang.org/grpc)|v1.70.0|Apache License 2.0 -[google.golang.org/protobuf](https://google.golang.org/protobuf)|v1.36.5|BSD 3-clause "New" or "Revised" License -[helm/v3](https://helm.sh/helm/v3)|v3.17.0|Apache License 2.0 -[istio.io/api](https://istio.io/api)|v1.25.0-alpha.0.0.20250210220544-0b64afd2de85|Apache License 2.0 -[istio.io/client-go](https://istio.io/client-go)|v1.25.0-alpha.0.0.20250210220843-5a4065fded65|Apache License 2.0 -[istio.io/istio](https://istio.io/istio)|v0.0.0-20250212203644-c2ac935c5888|Apache License 2.0 -[k8s.io/api](https://k8s.io/api)|v0.32.2|Apache License 2.0 -[k8s.io/apiextensions-apiserver](https://k8s.io/apiextensions-apiserver)|v0.32.2|Apache License 2.0 -[k8s.io/apimachinery](https://k8s.io/apimachinery)|v0.32.2|Apache License 2.0 -[k8s.io/client-go](https://k8s.io/client-go)|v0.32.2|Apache License 2.0 -[k8s.io/kube-openapi](https://k8s.io/kube-openapi)|v0.0.0-20250304201544-e5f78fe3ede9|Apache License 2.0 -[k8s.io/utils](https://k8s.io/utils)|v0.0.0-20241210054802-24370beab758|Apache License 2.0 -[knative.dev/pkg](https://knative.dev/pkg)|v0.0.0-20211206113427-18589ac7627e|Apache License 2.0 -[sigs.k8s.io/controller-runtime](https://sigs.k8s.io/controller-runtime)|v0.20.0|Apache License 2.0 -[sigs.k8s.io/gateway-api](https://sigs.k8s.io/gateway-api)|v1.2.1|Apache License 2.0 -[structured-merge-diff/v4](https://sigs.k8s.io/structured-merge-diff/v4)|v4.6.0|Apache License 2.0 -[sigs.k8s.io/yaml](https://sigs.k8s.io/yaml)|v1.4.0|MIT License -[cmd/goimports](https://golang.org/x/tools/cmd/goimports)|latest|MIT License -[gogo/protobuf](https://github.com/gogo/protobuf)|latest|MIT License -[envoyproxy/envoy](https://github.com/envoyproxy/envoy)|latest|Apache License 2.0 -[envoyproxy/protoc-gen-validate](https://github.com/envoyproxy/protoc-gen-validate)|latest|Apache License 2.0 -[paulvollmer/2gobytes](https://github.com/paulvollmer/2gobytes)|latest|MIT License diff --git a/assets/docs/snippets/otel-prereq.md b/assets/docs/snippets/otel-prereq.md deleted file mode 100644 index f6ec85999..000000000 --- a/assets/docs/snippets/otel-prereq.md +++ /dev/null @@ -1,61 +0,0 @@ -Deploy an open source observability stack based on OpenTelemetry (OTel) that includes the following components: - -- **Logs**: Centralized log collection and storage with Grafana [Loki](https://github.com/grafana/loki). -- **Traces**: Distributed tracing with Grafana [Tempo](https://github.com/grafana/tempo). -- **Metrics**: Time-series metrics collection with [Prometheus](https://github.com/prometheus/prometheus). -- **Collection**: Unified telemetry collection with [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector). -- **Visualization**: Comprehensive dashboards with [Grafana](https://github.com/grafana/grafana). - -## About - -Observability tools are essential to gain insight into the health and performance of your gateway proxies. [OpenTelemetry](https://opentelemetry.io/) (OTel) is a flexible, open source framework that provides a set of APIs, libraries, and instrumentation to help capture and export observability data. However, you can follow a similar process as this guide to use the tools that you prefer. - -### Observability data types {#data-types} - -Observability is built on three core pillars as described in the following table. By combining these three data types, you get a complete picture of your system's health and performance. - -| Pillar | Description | -| -- | -- | -| Logs | Discrete events that happen at a specific time with detailed context. | -| Metrics | Numerical measurements aggregated over time intervals. | -| Traces | Records of requests as they flow through distributed systems. | - -### Architecture - -Review the following diagram to understand the architecture of the observability stack. - -The gateway proxy acts as the primary telemetry generator, while the OTel Collectors serve as the central routing hub for all observability data. - -```mermaid -flowchart TD - A["1- Application Traffic"] --> B["2- Gateway proxy"] - B --> C["3- OTel Collectors"] - C --> D["4- Storage Backends"] - D --> D1["Logs (Loki)"] - D --> D2["Traces (Tempo)"] - D --> D3["Metrics (Prometheus)"] - D1 --> E["5- Visualization (Grafana)"] - D2 --> E - D3 --> E -``` -Architecture data flow: -1. **Application Traffic**: Applications send requests to the gateway proxy. -2. **Gateway Processing**: The gateway proxy processes requests and generates telemetry data in the form of logs, traces, and metrics. -3. **Telemetry Collection**: The OTel Collectors receive telemetry data from the gateway proxy. -4. **Data Storage**: The OTel Collectors route data to the appropriate storage backends: - - **Logs** go to Loki for log aggregation and storage. - - **Traces** go to Tempo for distributed tracing storage. - - **Metrics** go to Prometheus for time-series metrics storage. -5. **Visualization**: Grafana queries the storage backends as data sources to create unified dashboards. - -### More considerations {#more-considerations} - -**Push model**: This guide sets up the OTel collectors to push metrics to the storage backends (`push` model), vs. setting up the backends such as Prometheus to scrape metrics from the collector pod (`pull` model). The `push` model is used because it shows the ease and consistency of using OTel for demonstration purposes. It also supports Native Histograms out of the box, which the `pull` model does not due to [a known OTel issue with the Prometheus exporter](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/33703). - -**Debug exporter**: The example pipelines in all three OTel collectors set up the `debug` exporter. This exporter is useful for testing and validation purposes. However, for production scenarios, remove this exporter to avoid performance impacts. - -**Prometheus exporter**: If you prefer the `pull` model to the `push` model, you can use `prometheusexporter`'s `promexporter` port with Prometheus to scrape metrics from the collector pod, such as configured in the example later. Also, if you use the `pull` model, make sure to configure Prometheus to handle Native Histograms and scrape the metrics directly as for this model OTel's `prometheusexporter` is not yet supported, per the [known issue](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/33703) previously mentioned. - -## Before you begin - -{{< reuse "agw-docs/snippets/prereq.md" >}} \ No newline at end of file diff --git a/assets/docs/snippets/pod-name.md b/assets/docs/snippets/pod-name.md deleted file mode 100644 index 9090b8f64..000000000 --- a/assets/docs/snippets/pod-name.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway diff --git a/assets/docs/snippets/policies-gateway-api.md b/assets/docs/snippets/policies-gateway-api.md deleted file mode 100644 index d4132b905..000000000 --- a/assets/docs/snippets/policies-gateway-api.md +++ /dev/null @@ -1 +0,0 @@ -Many of these policies are directly from the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/reference/spec/#httprouterule) and behave the same as those policies. \ No newline at end of file diff --git a/assets/docs/snippets/policy-apply.md b/assets/docs/snippets/policy-apply.md deleted file mode 100644 index 6e5f9440b..000000000 --- a/assets/docs/snippets/policy-apply.md +++ /dev/null @@ -1,9 +0,0 @@ -The guides in this section show example configuration for different types of policies. Policies are applied to routes, which are part of a listener on a bind. - -```yaml -binds: -- port: 3000 - listeners: - - routes: - - policies: -``` \ No newline at end of file diff --git a/assets/docs/snippets/policy-inheritance-native.md b/assets/docs/snippets/policy-inheritance-native.md deleted file mode 100644 index 53bb506f6..000000000 --- a/assets/docs/snippets/policy-inheritance-native.md +++ /dev/null @@ -1,4 +0,0 @@ -Kubernetes Gateway API policies that can be defined on an HTTPRoute, such as timeouts and retries, are inherited as follows: - -* Policies that are defined on a parent HTTPRoute are automatically inherited by all child or grandchild HTTPRoutes. -* If the child or grandchild HTTPRoute defines a policy, this policy takes precedence and overrides the policy that is set on the parent. \ No newline at end of file diff --git a/assets/docs/snippets/policy-inheritance.md b/assets/docs/snippets/policy-inheritance.md deleted file mode 100644 index ddc7baea2..000000000 --- a/assets/docs/snippets/policy-inheritance.md +++ /dev/null @@ -1,8 +0,0 @@ -The following policy inheritance and override rules apply for TrafficPolicies: -* Policies that are defined in a TrafficPolicy resource and applied to a parent HTTPRoute resource are automatically inherited by all child and grandchild HTTPRoutes along the route delegation chain. -* If the TrafficPolicy applies to a child or grandchild HTTPRoute and defines a top-level policy that is different from the policy that is defined on the parent, the policies are merged and both the parent and child/grandchild policies are applied. For example, if the parent applies a rate limiting policy and the child applies a transformation policy, both policies are applied. -* If the TrafficPolicy applies to a child or grandchild HTTPRoute and defines the same top-level policy, the policy of the child takes precedence and the policy on the parent is ignored. Note that you can add the `kgateway.dev/inherited-policy-priority: ShallowMergePreferParent` annotation to the parent HTTPRoute to preserve the top-level parent policies on delegated routes. -* If you used [multiple attachment options]({{< link-hextra path="/about/policies/trafficpolicy/#policy-priority-and-merging-rules" >}}) to apply a TrafficPolicy with the same top-level policy to a parent or child HTTPRoute, only the policy with the highest priority is applied. The priority is determined by the attachment option that you chose. The following options are sorted from highest to lowest. - * Policy defined in a TrafficPolicy and attached to an HTTPRoute via the HTTPRoute's `extensionRef` filter - * Policy defined in a TrafficPolicy resource and attached to an HTTPRouteRule via the `targetRef.sectionName` option - * Policy defined in a TrafficPolicy resource and attached to an HTTPRoute via the `targetRef` option \ No newline at end of file diff --git a/assets/docs/snippets/prereq-1-3-channel-experimental.md b/assets/docs/snippets/prereq-1-3-channel-experimental.md deleted file mode 100644 index 9bb72a2bc..000000000 --- a/assets/docs/snippets/prereq-1-3-channel-experimental.md +++ /dev/null @@ -1,31 +0,0 @@ -1. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway. - -2. Follow the [Sample app guide]({{< link-hextra path="/install/sample-app/" >}}) to create a gateway proxy with an HTTP listener and deploy the httpbin sample app. - -3. Get the external address of the gateway and save it in an environment variable. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - {{% /tab %}} - {{< /tabs >}} - -4. **Important**: Install the experimental channel of version 1.3 of the Kubernetes Gateway API to use this feature. - ```shell - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml - ``` - -5. **Important**: To use experimental Gateway API features in kgateway, you must enable the `KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES` environment variable in your kgateway controller deployment. This setting defaults to `false` and must be explicitly enabled. For example, if you installed kgateway via Helm, add the following to your Helm values and upgrade your installation. - - ```yaml - controller: - extraEnv: - KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES: "true" - ``` \ No newline at end of file diff --git a/assets/docs/snippets/prereq-1-3-channel.md b/assets/docs/snippets/prereq-1-3-channel.md deleted file mode 100644 index 0c6c35dba..000000000 --- a/assets/docs/snippets/prereq-1-3-channel.md +++ /dev/null @@ -1,24 +0,0 @@ -1. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway. - -2. Follow the [Sample app guide]({{< link-hextra path="/install/sample-app/" >}}) to create a gateway proxy with an HTTP listener and deploy the httpbin sample app. - -3. Get the external address of the gateway and save it in an environment variable. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - {{% /tab %}} - {{< /tabs >}} - -4. **Important**: Install the standard channel of version 1.3 of the Kubernetes Gateway API to use this feature. - - ```shell - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/standard-install.yaml - ``` \ No newline at end of file diff --git a/assets/docs/snippets/prereq-agentgateway.md b/assets/docs/snippets/prereq-agentgateway.md deleted file mode 100644 index 0c6fc3ee2..000000000 --- a/assets/docs/snippets/prereq-agentgateway.md +++ /dev/null @@ -1 +0,0 @@ -[Install the `agentgateway` binary]({{< link-hextra path="/quickstart/#binary" >}}). \ No newline at end of file diff --git a/assets/docs/snippets/prereq-delegation.md b/assets/docs/snippets/prereq-delegation.md deleted file mode 100644 index e393760bb..000000000 --- a/assets/docs/snippets/prereq-delegation.md +++ /dev/null @@ -1,63 +0,0 @@ -1. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway. - -2. Create a Gateway resource and configure an HTTP listener. The following Gateway can serve HTTPRoute resources from all namespaces. - - ```yaml - kubectl apply -f- <}} - {{% tab %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab %}} - ```sh - kubectl port-forward deployment/http -n kgateway-system 8080:8080 - ``` - {{% /tab %}} - {{< /tabs >}} - -4. Create the namespaces for `team1` and `team2`. - ```sh - kubectl create namespace team1 - kubectl create namespace team2 - ``` - -5. Deploy the httpbin app into both namespaces. - ```sh - kubectl -n team1 apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml - kubectl -n team2 apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway.dev/main/assets/agw-docs/examples/httpbin.yaml - ``` - -6. Verify that the httpbin apps are up and running. - ```sh - kubectl get pods -n team1 - kubectl get pods -n team2 - ``` - - Example output: - ``` - NAME READY STATUS RESTARTS AGE - httpbin-f46cc8b9b-bzl9z 3/3 Running 0 7s - NAME READY STATUS RESTARTS AGE - httpbin-f46cc8b9b-nhtmg 3/3 Running 0 6s - ``` \ No newline at end of file diff --git a/assets/docs/snippets/prereq-docker.md b/assets/docs/snippets/prereq-docker.md deleted file mode 100644 index 921d1a62f..000000000 --- a/assets/docs/snippets/prereq-docker.md +++ /dev/null @@ -1 +0,0 @@ -Make sure that you have `docker`, such as by installing [Docker Desktop](https://docs.docker.com/desktop/). \ No newline at end of file diff --git a/assets/docs/snippets/prereq-listeners.md b/assets/docs/snippets/prereq-listeners.md deleted file mode 100644 index fad585c9d..000000000 --- a/assets/docs/snippets/prereq-listeners.md +++ /dev/null @@ -1,7 +0,0 @@ -1. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}. - -2. Deploy a [sample httpbin app]({{< link-hextra path="/install/sample-app/" >}}). - -3. {{% reuse "agw-docs/snippets/prereq-listenerset.md" %}} - - **ListenerSets**: {{< reuse "agw-docs/versions/warn-2-1-only.md" >}} Also, you must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later. \ No newline at end of file diff --git a/assets/docs/snippets/prereq-listenerset.md b/assets/docs/snippets/prereq-listenerset.md deleted file mode 100644 index 16c38df09..000000000 --- a/assets/docs/snippets/prereq-listenerset.md +++ /dev/null @@ -1 +0,0 @@ -Decide whether to set up a listener inline on the Gateway resource or as a separate ListenerSet resource. For more information, see the [Listener overview]({{< link-hextra path="/setup/listeners/overview" >}}). \ No newline at end of file diff --git a/assets/docs/snippets/prereq-uv.md b/assets/docs/snippets/prereq-uv.md deleted file mode 100644 index 04f0586fe..000000000 --- a/assets/docs/snippets/prereq-uv.md +++ /dev/null @@ -1 +0,0 @@ -[Install the `uv` Python package manager](https://docs.astral.sh/uv/getting-started/installation/). \ No newline at end of file diff --git a/assets/docs/snippets/prereq-x-channel.md b/assets/docs/snippets/prereq-x-channel.md deleted file mode 100644 index 55c434ec6..000000000 --- a/assets/docs/snippets/prereq-x-channel.md +++ /dev/null @@ -1,32 +0,0 @@ -1. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway. - -2. Follow the [Sample app guide]({{< link-hextra path="/install/sample-app/" >}}) to create a gateway proxy with an HTTP listener and deploy the httpbin sample app. - -3. Get the external address of the gateway and save it in an environment variable. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - {{% /tab %}} - {{< /tabs >}} - -4. **Important**: Install the experimental channel of the Kubernetes Gateway API to use this feature. - - ```shell - kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml - ``` - -5. **Important**: To use experimental Gateway API features in kgateway, you must enable the `KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES` environment variable in your kgateway controller deployment. This setting defaults to `false` and must be explicitly enabled. For example, if you installed kgateway via Helm, add the following to your Helm values and upgrade your installation. - - ```yaml - controller: - extraEnv: - KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES: "true" - ``` diff --git a/assets/docs/snippets/prereq.md b/assets/docs/snippets/prereq.md deleted file mode 100644 index f4a5ce0ec..000000000 --- a/assets/docs/snippets/prereq.md +++ /dev/null @@ -1,18 +0,0 @@ -1. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway. - -2. Follow the [Sample app guide]({{< link-hextra path="/install/sample-app/" >}}) to create a gateway proxy with an HTTP listener and deploy the httpbin sample app. - -3. Get the external address of the gateway and save it in an environment variable. - {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}} - {{% tab tabName="Cloud Provider LoadBalancer" %}} - ```sh - export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") - echo $INGRESS_GW_ADDRESS - ``` - {{% /tab %}} - {{% tab tabName="Port-forward for local testing" %}} - ```sh - kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080 - ``` - {{% /tab %}} - {{< /tabs >}} diff --git a/assets/docs/snippets/provider-azure-base-configuration.md b/assets/docs/snippets/provider-azure-base-configuration.md deleted file mode 100644 index 1a7871331..000000000 --- a/assets/docs/snippets/provider-azure-base-configuration.md +++ /dev/null @@ -1,6 +0,0 @@ -| Setting | Description | -|---------|-------------| -| `ai.name` | The name of the LLM provider for this AI backend. | -| `ai.hostOverride` | Override the hostname to point to your Azure AI service endpoint. | -| `ai.pathOverride` | Override the path to match your Azure AI service API endpoint. | -| `ai.provider.openAI.model` | Optionally set the model to use for requests. If set, any models in the request are overwritten. If not set, the request must include the model to use. | diff --git a/assets/docs/snippets/proxy-agentgateway.md b/assets/docs/snippets/proxy-agentgateway.md deleted file mode 100644 index cbb8c3f4b..000000000 --- a/assets/docs/snippets/proxy-agentgateway.md +++ /dev/null @@ -1 +0,0 @@ -{{< icon "agentgateway" >}} The steps in this section use the agentgateway data plane. The steps do not work with the Envoy-based kgateway data plane. \ No newline at end of file diff --git a/assets/docs/snippets/proxy-kgateway.md b/assets/docs/snippets/proxy-kgateway.md deleted file mode 100644 index f12c01a87..000000000 --- a/assets/docs/snippets/proxy-kgateway.md +++ /dev/null @@ -1 +0,0 @@ -{{< icon "kgateway" >}} The steps in this section use the Envoy-based kgateway data plane. The steps do not work with the agentgateway data plane. \ No newline at end of file diff --git a/assets/docs/snippets/ratelimit-requesttime.md b/assets/docs/snippets/ratelimit-requesttime.md deleted file mode 100644 index 7329c2a45..000000000 --- a/assets/docs/snippets/ratelimit-requesttime.md +++ /dev/null @@ -1,2 +0,0 @@ -* When `tokenize: true` _is not set_ or is set to `false` on the AI backend, the number of tokens that are used for the request cannot be calculated. Because of this, the request is always allowed, unless the rate limit is set to 0 tokens. The LLM typically returns the number of tokens that were used for the request when sending the response. Agentgateway verifies the number of tokens that were used in the request and the response to determine whether the rate limit was reached. By default, `tokenize` is set to false. -* When `tokenize: true` _is set_, agentgateway estimates the number of tokens at request time. Because of that, the request is only allowed if the estimated number of tokens does not exceed the set rate limit. \ No newline at end of file diff --git a/assets/docs/snippets/ratelimit-responsetime.md b/assets/docs/snippets/ratelimit-responsetime.md deleted file mode 100644 index 43a8c759c..000000000 --- a/assets/docs/snippets/ratelimit-responsetime.md +++ /dev/null @@ -1,3 +0,0 @@ -When the LLM returns a response, it typically provides the number of tokens that were used during the request and response. Agentgateway uses these numbers to determine if the rate limit was reached. - -Note that this determination happens _after_ the response is returned. Even, if the number of tokens that are used in the response exceeds the number of allowed tokens, the response is still returned to the user. Only subsequent requests are rate limited. If `tokenize: true` is set on the AI backend and tokens were estimated during the request, agentgateway verifies the actual number of tokens that were used for the request when the LLM returns its response. In the case the initial estimation was off, agentgateway adjusts the number of used tokens to count these against the set rate limit. \ No newline at end of file diff --git a/assets/docs/snippets/reserved-ports.md b/assets/docs/snippets/reserved-ports.md deleted file mode 100644 index 1b2cf4aab..000000000 --- a/assets/docs/snippets/reserved-ports.md +++ /dev/null @@ -1,15 +0,0 @@ -The following ports are reserved by {{< reuse "agw-docs/snippets/kgateway-capital.md" >}} and cannot be used when configuring your gateway proxy. - -| Port | Description | -| -- | -- | -| 19000 | The Envoy admin port. Gateway proxies expose an admin interface on this port that you can use to access important proxy information, such as the config dump, heap dump, healthchecks, and memory allocation. | -| 15000 | The agentgateway admin port. Agentgateway proxies expose several endpoints on this port that you can use to access important proxy information, such as the config dump (`15000/config_dump`) and a read-only user interface (`15000/ui`). | -| 8082 | The readiness port. This port can be used to determine if the gateway proxy is ready to receive traffic. | -| 9091 | The Prometheus scraping port. Gateway proxies expose all metrics on this port so that Prometheus can scrape them. | - -Note that if you configure one of these ports, the gateway proxy still deploys. However, you see error messages, such as the following in the logs. -```sh -err="failed to apply object apps/v1, Kind=Deployment example-gateway: failed to create typed patch object -(gwtest/example-gateway; apps/v1, Kind=Deployment): .spec.template.spec.containers[name=\"kgateway-proxy\"]. -ports: duplicate entries for key [containerPort=9091,protocol=\"TCP\"]" -``` \ No newline at end of file diff --git a/assets/docs/snippets/review-configuration.md b/assets/docs/snippets/review-configuration.md deleted file mode 100644 index d0651555f..000000000 --- a/assets/docs/snippets/review-configuration.md +++ /dev/null @@ -1 +0,0 @@ -Review the following example configuration. \ No newline at end of file diff --git a/assets/docs/snippets/review-table.md b/assets/docs/snippets/review-table.md deleted file mode 100644 index 2ab68fa45..000000000 --- a/assets/docs/snippets/review-table.md +++ /dev/null @@ -1 +0,0 @@ -Review the following table to understand this configuration. \ No newline at end of file diff --git a/assets/docs/snippets/setup-ambient-mesh.md b/assets/docs/snippets/setup-ambient-mesh.md deleted file mode 100644 index f73f73980..000000000 --- a/assets/docs/snippets/setup-ambient-mesh.md +++ /dev/null @@ -1 +0,0 @@ -Set up an ambient mesh in your cluster to secure service-to-service communication with mutual TLS by following the [ambientmesh.io quickstart documentation](https://ambientmesh.io/docs/quickstart/). \ No newline at end of file diff --git a/assets/docs/snippets/trafficpolicies.md b/assets/docs/snippets/trafficpolicies.md deleted file mode 100644 index fdb0c08ff..000000000 --- a/assets/docs/snippets/trafficpolicies.md +++ /dev/null @@ -1 +0,0 @@ -AgentgatewayPolicies diff --git a/assets/docs/snippets/trafficpolicy-apiversion.md b/assets/docs/snippets/trafficpolicy-apiversion.md deleted file mode 100644 index 7704c5234..000000000 --- a/assets/docs/snippets/trafficpolicy-apiversion.md +++ /dev/null @@ -1 +0,0 @@ -agentgateway.dev/v1alpha1 diff --git a/assets/docs/snippets/trafficpolicy-group.md b/assets/docs/snippets/trafficpolicy-group.md deleted file mode 100644 index eecaf26c2..000000000 --- a/assets/docs/snippets/trafficpolicy-group.md +++ /dev/null @@ -1 +0,0 @@ -gateway.kgateway.dev \ No newline at end of file diff --git a/assets/docs/snippets/trafficpolicy.md b/assets/docs/snippets/trafficpolicy.md deleted file mode 100644 index 6f58ebbd9..000000000 --- a/assets/docs/snippets/trafficpolicy.md +++ /dev/null @@ -1 +0,0 @@ -AgentgatewayPolicy diff --git a/assets/docs/snippets/waypoint-class.md b/assets/docs/snippets/waypoint-class.md deleted file mode 100644 index c647b4cde..000000000 --- a/assets/docs/snippets/waypoint-class.md +++ /dev/null @@ -1 +0,0 @@ -kgateway-waypoint \ No newline at end of file diff --git a/assets/docs/snippets/wizard-steps.md b/assets/docs/snippets/wizard-steps.md deleted file mode 100644 index 87fd25f53..000000000 --- a/assets/docs/snippets/wizard-steps.md +++ /dev/null @@ -1,50 +0,0 @@ -Agentgateway provides a built-in UI with a wizard to walk you through your first configuration. - -The following steps are equivalent to creating this basic configuration file. - -1. From the terminal, start agentgateway. - ```sh - agentgateway - ``` - -2. In your browser, [open the agentgateway UI on port 15000](http://localhost:15000/ui/). The first time, you are greeted with a wizard that walks you through creating your first configuration. Click **Start Setup** to continue. - {{< reuse-image src="img/ui-wizard.png" >}} - -3. From the **Configure Listener** tab, set up your first listener as follows: - - * Listener name: `default` - * Protocol: `HTTP` - * Hostname: `localhost` - * Port: `3000` - * Click **Next** to continue. - - {{< reuse-image src="img/ui-wizard-listeners.png" >}} - -4. From the **Configure Route** tab, leave the default configuration to allow path matching from all hostnames on `GET` and `POST` methods. Then click **Next** to continue. - - {{< reuse-image src="img/ui-wizard-routes.png" >}} - -5. From the **Configure Backend** tab, set up your first MCP backend as follows: - - * Backend Type: `MCP` - * MCP Backend Name: `default` - * Target Type: `Stdio` - * Target Name: `everything` - * Command: `npx` - * Arguments: `@modelcontextprotocol/server-everything` - * Click **Next** to continue. - - {{< reuse-image src="img/ui-wizard-backends.png" >}} - -6. From the **Configure Policies** tab, set up a basic CORS policy as follows. This way, the configuration works with the [MCP inspector tool](https://modelcontextprotocol.io/docs/tools/inspector). - - * Allowed Origins: `*` - * Allowed Methods: `GET,POST,PUT,DELETE,OPTIONS` - * Allowed Headers: `mcp-protocol-version` - * Click **Next** to continue. - - {{< reuse-image src="img/ui-wizard-policies.png" >}} - -7. From the **Review Configuration** tab, make sure that the `Ready to Deploy` message is displayed. Then click **Complete Setup**. - - {{< reuse-image src="img/ui-wizard-review.png" >}} \ No newline at end of file diff --git a/assets/docs/versions/github-branch.md b/assets/docs/versions/github-branch.md deleted file mode 100644 index 88d050b19..000000000 --- a/assets/docs/versions/github-branch.md +++ /dev/null @@ -1 +0,0 @@ -main \ No newline at end of file diff --git a/assets/docs/versions/github-kgateway-deployment.md b/assets/docs/versions/github-kgateway-deployment.md deleted file mode 100644 index e05a67a5b..000000000 --- a/assets/docs/versions/github-kgateway-deployment.md +++ /dev/null @@ -1 +0,0 @@ -/pkg/kgateway/helm/envoy/templates/deployment.yaml diff --git a/assets/docs/versions/helm-version-flag.md b/assets/docs/versions/helm-version-flag.md deleted file mode 100644 index bfbba6684..000000000 --- a/assets/docs/versions/helm-version-flag.md +++ /dev/null @@ -1 +0,0 @@ -v{{< reuse "agw-docs/versions/n-patch.md" >}} \ No newline at end of file diff --git a/assets/docs/versions/helm-version-upgrade.md b/assets/docs/versions/helm-version-upgrade.md deleted file mode 100644 index 955afe8e6..000000000 --- a/assets/docs/versions/helm-version-upgrade.md +++ /dev/null @@ -1 +0,0 @@ -v$NEW_VERSION \ No newline at end of file diff --git a/assets/docs/versions/istio_patch.md b/assets/docs/versions/istio_patch.md deleted file mode 100644 index f2538f8b5..000000000 --- a/assets/docs/versions/istio_patch.md +++ /dev/null @@ -1 +0,0 @@ -1.25.0 \ No newline at end of file diff --git a/assets/docs/versions/istio_revision.md b/assets/docs/versions/istio_revision.md deleted file mode 100644 index fd2f355c3..000000000 --- a/assets/docs/versions/istio_revision.md +++ /dev/null @@ -1 +0,0 @@ -1-25 \ No newline at end of file diff --git a/assets/docs/versions/k8s-gateway-api.md b/assets/docs/versions/k8s-gateway-api.md deleted file mode 100644 index 589268e6f..000000000 --- a/assets/docs/versions/k8s-gateway-api.md +++ /dev/null @@ -1 +0,0 @@ -1.3.0 \ No newline at end of file diff --git a/assets/docs/versions/k8s-gw-version.md b/assets/docs/versions/k8s-gw-version.md deleted file mode 100644 index e21e727f9..000000000 --- a/assets/docs/versions/k8s-gw-version.md +++ /dev/null @@ -1 +0,0 @@ -1.4.0 \ No newline at end of file diff --git a/assets/docs/versions/kgwctl.md b/assets/docs/versions/kgwctl.md deleted file mode 100644 index db9376fb7..000000000 --- a/assets/docs/versions/kgwctl.md +++ /dev/null @@ -1 +0,0 @@ -0.0.1-alpha4 \ No newline at end of file diff --git a/assets/docs/versions/max-kube.md b/assets/docs/versions/max-kube.md deleted file mode 100644 index 92443952a..000000000 --- a/assets/docs/versions/max-kube.md +++ /dev/null @@ -1 +0,0 @@ -1.31 \ No newline at end of file diff --git a/assets/docs/versions/mcp-inspector.md b/assets/docs/versions/mcp-inspector.md deleted file mode 100644 index 47d04a528..000000000 --- a/assets/docs/versions/mcp-inspector.md +++ /dev/null @@ -1 +0,0 @@ -0.18.0 \ No newline at end of file diff --git a/assets/docs/versions/n-patch.md b/assets/docs/versions/n-patch.md deleted file mode 100644 index 2bb6a820b..000000000 --- a/assets/docs/versions/n-patch.md +++ /dev/null @@ -1 +0,0 @@ -0.11.3 \ No newline at end of file diff --git a/assets/docs/versions/otel-stack-collector.md b/assets/docs/versions/otel-stack-collector.md deleted file mode 100644 index 9198f9c7a..000000000 --- a/assets/docs/versions/otel-stack-collector.md +++ /dev/null @@ -1 +0,0 @@ -0.127.2 \ No newline at end of file diff --git a/assets/docs/versions/otel-stack-loki.md b/assets/docs/versions/otel-stack-loki.md deleted file mode 100644 index 57f7599b1..000000000 --- a/assets/docs/versions/otel-stack-loki.md +++ /dev/null @@ -1 +0,0 @@ -6.24.0 \ No newline at end of file diff --git a/assets/docs/versions/otel-stack-prometheus.md b/assets/docs/versions/otel-stack-prometheus.md deleted file mode 100644 index c090543e7..000000000 --- a/assets/docs/versions/otel-stack-prometheus.md +++ /dev/null @@ -1 +0,0 @@ -75.6.1 \ No newline at end of file diff --git a/assets/docs/versions/otel-stack-tempo.md b/assets/docs/versions/otel-stack-tempo.md deleted file mode 100644 index 71bd5d9ee..000000000 --- a/assets/docs/versions/otel-stack-tempo.md +++ /dev/null @@ -1 +0,0 @@ -1.16.0 \ No newline at end of file diff --git a/assets/docs/versions/patch-dev.md b/assets/docs/versions/patch-dev.md deleted file mode 100644 index 4dc8de8fb..000000000 --- a/assets/docs/versions/patch-dev.md +++ /dev/null @@ -1 +0,0 @@ -2.2.0-main \ No newline at end of file diff --git a/assets/docs/versions/patch_n+1.md b/assets/docs/versions/patch_n+1.md deleted file mode 100644 index 4dc8de8fb..000000000 --- a/assets/docs/versions/patch_n+1.md +++ /dev/null @@ -1 +0,0 @@ -2.2.0-main \ No newline at end of file diff --git a/assets/docs/versions/patch_n-1.md b/assets/docs/versions/patch_n-1.md deleted file mode 100644 index 8f9174b4d..000000000 --- a/assets/docs/versions/patch_n-1.md +++ /dev/null @@ -1 +0,0 @@ -2.1.2 \ No newline at end of file diff --git a/assets/docs/versions/short.md b/assets/docs/versions/short.md deleted file mode 100644 index 616187889..000000000 --- a/assets/docs/versions/short.md +++ /dev/null @@ -1 +0,0 @@ -2.2 \ No newline at end of file diff --git a/assets/docs/versions/warn-1-3-only-experimental.md b/assets/docs/versions/warn-1-3-only-experimental.md deleted file mode 100644 index 1fdea0492..000000000 --- a/assets/docs/versions/warn-1-3-only-experimental.md +++ /dev/null @@ -1 +0,0 @@ -This feature is available in the upstream Kubernetes Gateway API 1.3 (experimental) or later. \ No newline at end of file diff --git a/assets/docs/versions/warn-1-3-only.md b/assets/docs/versions/warn-1-3-only.md deleted file mode 100644 index e75ace858..000000000 --- a/assets/docs/versions/warn-1-3-only.md +++ /dev/null @@ -1 +0,0 @@ -This feature is available in the upstream Kubernetes Gateway API 1.3 or later. \ No newline at end of file diff --git a/assets/docs/versions/warn-2-1-only.md b/assets/docs/versions/warn-2-1-only.md deleted file mode 100644 index 356da8ddb..000000000 --- a/assets/docs/versions/warn-2-1-only.md +++ /dev/null @@ -1 +0,0 @@ -This feature is available in kgateway version 2.1.x or later. \ No newline at end of file diff --git a/assets/docs/versions/warn-experimental.md b/assets/docs/versions/warn-experimental.md deleted file mode 100644 index ee1ec02b4..000000000 --- a/assets/docs/versions/warn-experimental.md +++ /dev/null @@ -1 +0,0 @@ -This feature is experimental in the upstream Kubernetes Gateway API and subject to change. \ No newline at end of file diff --git a/scripts/crd-ref-docs-config.yaml b/scripts/crd-ref-docs-config.yaml index a4d91c9ba..347ac10c6 100644 --- a/scripts/crd-ref-docs-config.yaml +++ b/scripts/crd-ref-docs-config.yaml @@ -7,6 +7,9 @@ processor: - metav1.ObjectMeta - metav1.TypeMeta - metav1.ListMeta + # Exclude Kubernetes List resource types (e.g. AgentgatewayBackendList) + # - they duplicate the main resource with just metadata + items + - "(AgentgatewayBackend|AgentgatewayParameters|AgentgatewayPolicy)List$" renderer: kubernetesVersion: "1.31"