From 3ff62394b6627d5aa3154ba2449f9380024ed2d3 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Wed, 23 Oct 2024 14:14:30 -0700 Subject: [PATCH 01/20] Add SnippetsFilter guide --- examples/snippets-filter/README.md | 2 +- examples/snippets-filter/app.yaml | 65 ++++ .../coffee-snippets-filter.yaml | 10 + examples/snippets-filter/example.yaml | 86 ----- examples/snippets-filter/gateway.yaml | 11 + examples/snippets-filter/httproutes.yaml | 49 +++ .../snippets-filter/tea-snippets-filter.yaml | 10 + .../traffic-management/snippets-filters.md | 345 ++++++++++++++++++ 8 files changed, 491 insertions(+), 87 deletions(-) create mode 100644 examples/snippets-filter/app.yaml create mode 100644 examples/snippets-filter/coffee-snippets-filter.yaml delete mode 100644 examples/snippets-filter/example.yaml create mode 100644 examples/snippets-filter/gateway.yaml create mode 100644 examples/snippets-filter/httproutes.yaml create mode 100644 examples/snippets-filter/tea-snippets-filter.yaml create mode 100644 site/content/how-to/traffic-management/snippets-filters.md diff --git a/examples/snippets-filter/README.md b/examples/snippets-filter/README.md index f09032d512..c523ec2c34 100644 --- a/examples/snippets-filter/README.md +++ b/examples/snippets-filter/README.md @@ -1,3 +1,3 @@ # SnippetsFilter -This directory contains example YAMLs for testing SnippetsFilter. Eventually, this will be converted into a how-to guide. +This directory contains the YAML files used in the [SnippetsFilter](https://docs.nginx.com/nginx-gateway-fabric/how-to/traffic-management/snippets-filters/) guide. diff --git a/examples/snippets-filter/app.yaml b/examples/snippets-filter/app.yaml new file mode 100644 index 0000000000..aec8731842 --- /dev/null +++ b/examples/snippets-filter/app.yaml @@ -0,0 +1,65 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: coffee +spec: + replicas: 1 + selector: + matchLabels: + app: coffee + template: + metadata: + labels: + app: coffee + spec: + containers: + - name: coffee + image: nginxdemos/nginx-hello:plain-text + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: coffee +spec: + ports: + - port: 80 + targetPort: 8080 + protocol: TCP + name: http + selector: + app: coffee +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: tea +spec: + replicas: 1 + selector: + matchLabels: + app: tea + template: + metadata: + labels: + app: tea + spec: + containers: + - name: tea + image: nginxdemos/nginx-hello:plain-text + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: tea +spec: + ports: + - port: 80 + targetPort: 8080 + protocol: TCP + name: http + selector: + app: tea diff --git a/examples/snippets-filter/coffee-snippets-filter.yaml b/examples/snippets-filter/coffee-snippets-filter.yaml new file mode 100644 index 0000000000..5202f302ea --- /dev/null +++ b/examples/snippets-filter/coffee-snippets-filter.yaml @@ -0,0 +1,10 @@ +apiVersion: gateway.nginx.org/v1alpha1 +kind: SnippetsFilter +metadata: + name: coffee-rate-limiting-sf +spec: + snippets: + - context: http + value: limit_req_zone $binary_remote_addr zone=coffeezone:10m rate=1r/s; + - context: http.server.location + value: limit_req zone=coffeezone burst=3 nodelay; diff --git a/examples/snippets-filter/example.yaml b/examples/snippets-filter/example.yaml deleted file mode 100644 index a244ca6b84..0000000000 --- a/examples/snippets-filter/example.yaml +++ /dev/null @@ -1,86 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: coffee -spec: - replicas: 1 - selector: - matchLabels: - app: coffee - template: - metadata: - labels: - app: coffee - spec: - containers: - - name: coffee - image: nginxdemos/nginx-hello:plain-text - ports: - - containerPort: 8080 ---- -apiVersion: v1 -kind: Service -metadata: - name: coffee -spec: - ports: - - port: 80 - targetPort: 8080 - protocol: TCP - name: http - selector: - app: coffee ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: Gateway -metadata: - name: gateway -spec: - gatewayClassName: nginx - listeners: - - name: http - port: 80 - protocol: HTTP - hostname: "*.example.com" ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: coffee -spec: - parentRefs: - - name: gateway - sectionName: http - hostnames: - - "cafe.example.com" - rules: - - matches: - - path: - type: PathPrefix - value: /coffee - filters: - - type: ExtensionRef - extensionRef: - group: gateway.nginx.org - kind: SnippetsFilter - name: test-all-contexts - backendRefs: - - name: coffee - port: 80 ---- -apiVersion: gateway.nginx.org/v1alpha1 -kind: SnippetsFilter -metadata: - name: test-all-contexts -spec: - snippets: - - context: main - value: worker_shutdown_timeout 120s; - - context: http - value: aio on; - - context: http.server - value: auth_delay 10s; - - context: http.server.location - value: | - allow 10.0.0.0/8; - deny all; diff --git a/examples/snippets-filter/gateway.yaml b/examples/snippets-filter/gateway.yaml new file mode 100644 index 0000000000..e2b7cfdecd --- /dev/null +++ b/examples/snippets-filter/gateway.yaml @@ -0,0 +1,11 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: gateway +spec: + gatewayClassName: nginx + listeners: + - name: http + port: 80 + protocol: HTTP + hostname: "*.example.com" diff --git a/examples/snippets-filter/httproutes.yaml b/examples/snippets-filter/httproutes.yaml new file mode 100644 index 0000000000..29c1f55e42 --- /dev/null +++ b/examples/snippets-filter/httproutes.yaml @@ -0,0 +1,49 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: coffee +spec: + parentRefs: + - name: gateway + sectionName: http + hostnames: + - "cafe.example.com" + rules: + - matches: + - path: + type: PathPrefix + value: /coffee + filters: + - type: ExtensionRef + extensionRef: + group: gateway.nginx.org + kind: SnippetsFilter + name: coffee-rate-limiting-sf + backendRefs: + - name: coffee + port: 80 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: tea +spec: + parentRefs: + - name: gateway + sectionName: http + hostnames: + - "cafe.example.com" + rules: + - matches: + - path: + type: PathPrefix + value: /tea + filters: + - type: ExtensionRef + extensionRef: + group: gateway.nginx.org + kind: SnippetsFilter + name: tea-rate-limiting-sf + backendRefs: + - name: tea + port: 80 diff --git a/examples/snippets-filter/tea-snippets-filter.yaml b/examples/snippets-filter/tea-snippets-filter.yaml new file mode 100644 index 0000000000..abcd2daec8 --- /dev/null +++ b/examples/snippets-filter/tea-snippets-filter.yaml @@ -0,0 +1,10 @@ +apiVersion: gateway.nginx.org/v1alpha1 +kind: SnippetsFilter +metadata: + name: tea-rate-limiting-sf +spec: + snippets: + - context: http + value: limit_req_zone $binary_remote_addr zone=teazone:10m rate=1r/s; + - context: http.server.location + value: limit_req zone=teazone burst=3; diff --git a/site/content/how-to/traffic-management/snippets-filters.md b/site/content/how-to/traffic-management/snippets-filters.md new file mode 100644 index 0000000000..e0aa8ec250 --- /dev/null +++ b/site/content/how-to/traffic-management/snippets-filters.md @@ -0,0 +1,345 @@ +--- +title: "Snippets Filters" +weight: 800 +toc: true +docs: "DOCS-000" +--- + +Learn how to use Snippets with the `SnippetsFilter` API. + +## Overview + +Snippets allow Cluster Operators to insert NGINX configuration into different contexts of the +NGINX configurations that NGINX Gateway Fabric generates. + +Snippets are for advanced NGINX users who need more control over the generated NGINX configuration, +and can be used in cases where Gateway API resources or NGINX extensions don't apply. + +## Disadvantages of Snippets + +Snippets are configured using the `SnippetsFilter` API, but are disabled by default due to their complexity and security implications. + +To use Snippets, set the `nginxGateway.snippetsFilters.enable` command line argument to true. + +Snippets have the following disadvantages: + +- *Complexity*. Snippets require you to: + - Understand NGINX Configuration primitives and implement a correct NGINX configuration. + - Understand how NGINX Gateway Fabric generates NGINX configuration so that a Snippet doesn’t interfere with the other features in the configuration. +- *Decreased robustness*. An incorrect Snippet can invalidate NGINX configuration, causing reload failures. Until the snippet is fixed, it will prevent any new configuration updates, including updates for the other Gateway resources. +- *Security implications*. Snippets give access to NGINX configuration primitives, which are not validated by NGINX Gateway Fabric. For example, a Snippet can configure NGINX to serve the TLS certificates and keys used for TLS termination for Gateway resources. + +{{< note >}} If the NGINX configuration includes an invalid Snippet, NGINX will continue to operate with the last valid configuration. {{< /note >}} + +Due to the described disadvantages of Snippets, we recommend exhausting all other means of NGINX configuration through Gateway API resources, +[first-class policies]({{< relref "overview/custom-policies.md" >}}), and other NGINX extensions before using Snippets. + +{{< note >}} If you end up using Snippets and run into situations where an NGINX directive fails to be applied, please create an issue in the +[NGINX Gateway Fabric Github repository](https://github.com/nginxinc/nginx-gateway-fabric). {{< /note >}} + +## Setup + +- [Install]({{< relref "/installation/" >}}) NGINX Gateway Fabric. +- Save the public IP address and port of NGINX Gateway Fabric into shell variables: + + ```text + GW_IP=XXX.YYY.ZZZ.III + GW_PORT= + ``` + + {{< note >}}In a production environment, you should have a DNS record for the external IP address that is exposed, and it should refer to the hostname that the gateway will forward for.{{< /note >}} + +- Create the coffee and tea example applications: + + ```yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.4.0/examples/snippets-filter/app.yaml + ``` + +- Create a Gateway: + + ```yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.4.0/examples/snippets-filter/gateway.yaml + ``` + +- Create HTTPRoutes for the coffee and tea applications: + + ```yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.4.0/examples/snippets-filter/httproutes.yaml + ``` + +- Test the configuration: + + You can send traffic to the coffee and tea applications using the external IP address and port for NGINX Gateway Fabric. + + Send a request to coffee: + + ```shell + curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee + ``` + + Send a request to tea + + ```shell + curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/tea + ``` + + Both requests should receive this response from the backend Pod: + + ```text + + 500 Internal Server Error + +

500 Internal Server Error

+
nginx
+ + + ``` + + Lets check out our HTTPRoutes to see what's causing this error: + + ```shell + kubectl describe httproutes.gateway.networking.k8s.io + ``` + + You should see the following conditions: + + ```text + Conditions: + Last Transition Time: 2024-10-22T23:43:11Z + Message: The route is accepted + Observed Generation: 1 + Reason: Accepted + Status: True + Type: Accepted + Last Transition Time: 2024-10-22T23:43:11Z + Message: spec.rules[0].filters[0].extensionRef: Not found: v1.LocalObjectReference{Group:"gateway.nginx.org", Kind:"SnippetsFilter", Name:"coffee-rate-limiting-sf"} + Observed Generation: 1 + Reason: InvalidFilter + Status: False + Type: ResolvedRefs + . + . + . + Conditions: + Last Transition Time: 2024-10-22T23:43:14Z + Message: The route is accepted + Observed Generation: 1 + Reason: Accepted + Status: True + Type: Accepted + Last Transition Time: 2024-10-22T23:43:14Z + Message: spec.rules[0].filters[0].extensionRef: Not found: v1.LocalObjectReference{Group:"gateway.nginx.org", Kind:"SnippetsFilter", Name:"tea-rate-limiting-sf"} + Observed Generation: 1 + Reason: InvalidFilter + Status: False + Type: ResolvedRefs + ``` + + This is because in the HTTPRoutes we created earlier, they both reference `SnippetsFilter` resources that do not currently + exist, and thus a 500 error code response will be returned on requests that are processed by these HTTPRoutes. + We will solve this in the next section when we add SnippetsFilters. + +## Configure rate limiting to the coffee application + +Lets configure rate limiting to our coffee application by adding the following `SnippetsFilter`: + +```yaml +kubectl apply -f - < +``` + +Verify that the coffee `HTTPRoute` which had an `InvalidFilter` condition earlier, no longer has that condition. + +```shell +kubectl describe httproutes.gateway.networking.k8s.io coffee +``` + +You should see the following conditions: + +```text +Conditions: + Last Transition Time: 2024-10-23T00:33:08Z + Message: The route is accepted + Observed Generation: 2 + Reason: Accepted + Status: True + Type: Accepted + Last Transition Time: 2024-10-23T00:33:08Z + Message: All references are resolved + Observed Generation: 2 + Reason: ResolvedRefs + Status: True + Type: ResolvedRefs +``` + +Next, test that the `SnippetsFilter` is configured and has successfully applied the rate limiting NGINX configuration changes. + +Send a request to coffee: + +```shell +curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee +``` + +This request should receive a response from the coffee Pod: + +```text +Server address: 10.244.0.9:8080 +Server name: coffee-76c7c85bbd-cf8nz +``` + +When processing a single request, the rate limiting configuration has no noticeable effect. Now lets try to exceed the +set rate limit by using a simple script to send multiple requests. + +```shell +for i in `seq 1 10`; do curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee; done +``` + +You should see some successful responses from the coffee Pod, however you should see multiple responses like the following: + +```text +Request ID: 890c17df930ef1ef573feed3c6e81290 + +503 Service Temporarily Unavailable + +

503 Service Temporarily Unavailable

+
nginx
+ + +``` + +This is the default error response given by NGINX when the rate limit burst is exceeded, meaning our `SnippetsFilter` +correctly applied our rate limiting NGINX configuration changes. + +## Configure rate limiting to the tea application + +Now, lets configure a different set of rate limiting rules to our tea application by adding the following `SnippetsFilter`: + +```yaml +kubectl apply -f - < +``` + +Verify that the tea `HTTPRoute` which had an `InvalidFilter` condition earlier, no longer has that condition. + +```shell +kubectl describe httproutes.gateway.networking.k8s.io tea +``` + +You should see the following conditions: + +```text +Conditions: + Last Transition Time: 2024-10-23T00:33:08Z + Message: The route is accepted + Observed Generation: 2 + Reason: Accepted + Status: True + Type: Accepted + Last Transition Time: 2024-10-23T00:33:08Z + Message: All references are resolved + Observed Generation: 2 + Reason: ResolvedRefs + Status: True + Type: ResolvedRefs +``` + +Next, test that the `SnippetsFilter` is configured and has successfully applied the rate limiting NGINX configuration changes. + +Send a request to tea: + +```shell +curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/tea +``` + +This request should receive a response from the tea Pod: + +```text +Server address: 10.244.0.7:8080 +Server name: tea-76c7c85bbd-cf8nz +``` + +When processing a single request, the rate limiting configuration has no noticeable effect. Now, lets try sending +multiple requests. + +```shell +for i in `seq 1 10`; do curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/tea; done +``` + +You should see all successful responses from the tea Pod, but they should be spaced apart roughly one second each as +expected through our rate limiting configuration. + +## Further reading + +- [API reference]({{< relref "reference/api.md" >}}): all configuration fields for the `SnippetsFilter` API. From 3f1673b33b70436af62030a0fe39ad05d82f1509 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Thu, 24 Oct 2024 11:38:14 -0700 Subject: [PATCH 02/20] Add docs suggestions --- examples/snippets-filter/README.md | 2 +- .../traffic-management/snippets-filters.md | 52 +++++++++++-------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/examples/snippets-filter/README.md b/examples/snippets-filter/README.md index c523ec2c34..bd58656161 100644 --- a/examples/snippets-filter/README.md +++ b/examples/snippets-filter/README.md @@ -1,3 +1,3 @@ # SnippetsFilter -This directory contains the YAML files used in the [SnippetsFilter](https://docs.nginx.com/nginx-gateway-fabric/how-to/traffic-management/snippets-filters/) guide. +This directory contains the YAML files used in the [Use the SnippetsFilter API](https://docs.nginx.com/nginx-gateway-fabric/how-to/traffic-management/snippets-filters/) guide. diff --git a/site/content/how-to/traffic-management/snippets-filters.md b/site/content/how-to/traffic-management/snippets-filters.md index e0aa8ec250..b4fd0aa512 100644 --- a/site/content/how-to/traffic-management/snippets-filters.md +++ b/site/content/how-to/traffic-management/snippets-filters.md @@ -1,11 +1,13 @@ --- -title: "Snippets Filters" +title: "Use the SnippetsFilter API" weight: 800 toc: true docs: "DOCS-000" --- -Learn how to use Snippets with the `SnippetsFilter` API. +This topic introduces Snippets and how to implement them using the `SnippetsFilter` API. It provides an example of how to use a Snippet for rate limiting, and how to investigate errors caused by misconfiguration. + +--- ## Overview @@ -15,6 +17,8 @@ NGINX configurations that NGINX Gateway Fabric generates. Snippets are for advanced NGINX users who need more control over the generated NGINX configuration, and can be used in cases where Gateway API resources or NGINX extensions don't apply. +--- + ## Disadvantages of Snippets Snippets are configured using the `SnippetsFilter` API, but are disabled by default due to their complexity and security implications. @@ -23,11 +27,11 @@ To use Snippets, set the `nginxGateway.snippetsFilters.enable` command line argu Snippets have the following disadvantages: -- *Complexity*. Snippets require you to: - - Understand NGINX Configuration primitives and implement a correct NGINX configuration. +- _Complexity_. Snippets require you to: + - Understand NGINX configuration primitives to implement correct NGINX configuration. - Understand how NGINX Gateway Fabric generates NGINX configuration so that a Snippet doesn’t interfere with the other features in the configuration. -- *Decreased robustness*. An incorrect Snippet can invalidate NGINX configuration, causing reload failures. Until the snippet is fixed, it will prevent any new configuration updates, including updates for the other Gateway resources. -- *Security implications*. Snippets give access to NGINX configuration primitives, which are not validated by NGINX Gateway Fabric. For example, a Snippet can configure NGINX to serve the TLS certificates and keys used for TLS termination for Gateway resources. +- _Decreased robustness_. An incorrect Snippet can invalidate NGINX configuration, causing reload failures. Until the snippet is fixed, it will prevent any new configuration updates, including updates for the other Gateway resources. +- _Security implications_. Snippets give access to NGINX configuration primitives, which are not validated by NGINX Gateway Fabric. For example, a Snippet can configure NGINX to serve the TLS certificates and keys used for TLS termination for Gateway resources. {{< note >}} If the NGINX configuration includes an invalid Snippet, NGINX will continue to operate with the last valid configuration. {{< /note >}} @@ -47,7 +51,7 @@ Due to the described disadvantages of Snippets, we recommend exhausting all othe GW_PORT= ``` - {{< note >}}In a production environment, you should have a DNS record for the external IP address that is exposed, and it should refer to the hostname that the gateway will forward for.{{< /note >}} + {{< note >}} In a production environment, you should have a DNS record for the external IP address that is exposed, and it should refer to the hostname that the gateway will forward for. {{< /note >}} - Create the coffee and tea example applications: @@ -77,7 +81,7 @@ Due to the described disadvantages of Snippets, we recommend exhausting all othe curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee ``` - Send a request to tea + Send a request to tea: ```shell curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/tea @@ -95,7 +99,7 @@ Due to the described disadvantages of Snippets, we recommend exhausting all othe ``` - Lets check out our HTTPRoutes to see what's causing this error: + Use `kubectl describe` to investigate HTTPRoutes for the error: ```shell kubectl describe httproutes.gateway.networking.k8s.io @@ -135,13 +139,15 @@ Due to the described disadvantages of Snippets, we recommend exhausting all othe Type: ResolvedRefs ``` - This is because in the HTTPRoutes we created earlier, they both reference `SnippetsFilter` resources that do not currently - exist, and thus a 500 error code response will be returned on requests that are processed by these HTTPRoutes. - We will solve this in the next section when we add SnippetsFilters. + The HTTPRoutes created earlier both reference `SnippetsFilter` resources that do not currently + exist, creating a 500 error code response returned on requests that are processed by these HTTPRoutes. + This issue will be resolved using SnippetsFilters. + +--- ## Configure rate limiting to the coffee application -Lets configure rate limiting to our coffee application by adding the following `SnippetsFilter`: +Configure rate limiting to the coffee application by adding the following `SnippetsFilter`: ```yaml kubectl apply -f - < Date: Thu, 24 Oct 2024 15:00:42 -0700 Subject: [PATCH 03/20] Add review feedback --- .../how-to/traffic-management/snippets-filters.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/site/content/how-to/traffic-management/snippets-filters.md b/site/content/how-to/traffic-management/snippets-filters.md index b4fd0aa512..b38be16454 100644 --- a/site/content/how-to/traffic-management/snippets-filters.md +++ b/site/content/how-to/traffic-management/snippets-filters.md @@ -11,16 +11,19 @@ This topic introduces Snippets and how to implement them using the `SnippetsFilt ## Overview -Snippets allow Cluster Operators to insert NGINX configuration into different contexts of the +Snippets allow users to insert NGINX configuration into different contexts of the NGINX configurations that NGINX Gateway Fabric generates. Snippets are for advanced NGINX users who need more control over the generated NGINX configuration, -and can be used in cases where Gateway API resources or NGINX extensions don't apply. +and can be used in cases where Gateway API resources or NGINX extensions policies don't apply. --- ## Disadvantages of Snippets +{{< warning >}} We recommend managing NGINX configuration through Gateway API resources, [first-class policies]({{< relref "overview/custom-policies.md" >}}), and other existing NGINX extensions +before using Snippets. {{< /warning >}} + Snippets are configured using the `SnippetsFilter` API, but are disabled by default due to their complexity and security implications. To use Snippets, set the `nginxGateway.snippetsFilters.enable` command line argument to true. @@ -35,9 +38,6 @@ Snippets have the following disadvantages: {{< note >}} If the NGINX configuration includes an invalid Snippet, NGINX will continue to operate with the last valid configuration. {{< /note >}} -Due to the described disadvantages of Snippets, we recommend exhausting all other means of NGINX configuration through Gateway API resources, -[first-class policies]({{< relref "overview/custom-policies.md" >}}), and other NGINX extensions before using Snippets. - {{< note >}} If you end up using Snippets and run into situations where an NGINX directive fails to be applied, please create an issue in the [NGINX Gateway Fabric Github repository](https://github.com/nginxinc/nginx-gateway-fabric). {{< /note >}} @@ -272,7 +272,7 @@ spec: EOF ``` -This `SnippetFilter` is the same as the one applied to the coffee HTTPRoute, however it removes the `nodelay` setting +This `SnippetsFilter` is the same as the one applied to the coffee HTTPRoute, however it removes the `nodelay` setting on the `limit_req` directive. This forces a delay on the incoming requests to match the rate set in `limit_req_zone`. Verify that the `SnippetsFilter` is Accepted: From 2be016feddef69ad818db6f336c4bf3810c2895f Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Thu, 24 Oct 2024 15:13:37 -0700 Subject: [PATCH 04/20] Move and elaborate on enable snippets statement --- .../content/how-to/traffic-management/snippets-filters.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/site/content/how-to/traffic-management/snippets-filters.md b/site/content/how-to/traffic-management/snippets-filters.md index b38be16454..49eaff2827 100644 --- a/site/content/how-to/traffic-management/snippets-filters.md +++ b/site/content/how-to/traffic-management/snippets-filters.md @@ -26,8 +26,6 @@ before using Snippets. {{< /warning >}} Snippets are configured using the `SnippetsFilter` API, but are disabled by default due to their complexity and security implications. -To use Snippets, set the `nginxGateway.snippetsFilters.enable` command line argument to true. - Snippets have the following disadvantages: - _Complexity_. Snippets require you to: @@ -43,7 +41,11 @@ Snippets have the following disadvantages: ## Setup -- [Install]({{< relref "/installation/" >}}) NGINX Gateway Fabric. +- To enable Snippets, [install]({{< relref "/installation/" >}}) NGINX Gateway Fabric with these modifications: + - Using Helm: set the `nginxGateway.snippetsFilters.enable` command line argument to true. + - Using Kubernetes manifests: set the `--snippets-filters` flag in the nginx-gateway container argument, add `snippetsfilters` to the RBAC + rules with verbs `list` and `watch`, and add `snippetsfilters/status` to the RBAC rules with verb `update`. See this [example manifest](https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/main/deploy/snippets-filters/deploy.yaml) for clarification. + - Save the public IP address and port of NGINX Gateway Fabric into shell variables: ```text From 21d85f6afd45636356bd1c0790dabbcb35e0fb91 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Thu, 24 Oct 2024 15:33:44 -0700 Subject: [PATCH 05/20] Add link to data plane configuration --- site/content/how-to/traffic-management/snippets-filters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/how-to/traffic-management/snippets-filters.md b/site/content/how-to/traffic-management/snippets-filters.md index 49eaff2827..76804cb1a9 100644 --- a/site/content/how-to/traffic-management/snippets-filters.md +++ b/site/content/how-to/traffic-management/snippets-filters.md @@ -21,7 +21,7 @@ and can be used in cases where Gateway API resources or NGINX extensions policie ## Disadvantages of Snippets -{{< warning >}} We recommend managing NGINX configuration through Gateway API resources, [first-class policies]({{< relref "overview/custom-policies.md" >}}), and other existing NGINX extensions +{{< warning >}} We recommend managing NGINX configuration through Gateway API resources, [first-class policies]({{< relref "overview/custom-policies.md" >}}), and other existing [NGINX extensions]({{< relref "data-plane-configuration.md" >}}) before using Snippets. {{< /warning >}} Snippets are configured using the `SnippetsFilter` API, but are disabled by default due to their complexity and security implications. From 17ff791da3f89cff1ec7b3932de7c5b9fbbd2eae Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Thu, 24 Oct 2024 16:01:10 -0700 Subject: [PATCH 06/20] Add more suggestions --- examples/snippets-filter/README.md | 2 +- .../traffic-management/{snippets-filters.md => snippets.md} | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) rename site/content/how-to/traffic-management/{snippets-filters.md => snippets.md} (97%) diff --git a/examples/snippets-filter/README.md b/examples/snippets-filter/README.md index bd58656161..219f26e618 100644 --- a/examples/snippets-filter/README.md +++ b/examples/snippets-filter/README.md @@ -1,3 +1,3 @@ # SnippetsFilter -This directory contains the YAML files used in the [Use the SnippetsFilter API](https://docs.nginx.com/nginx-gateway-fabric/how-to/traffic-management/snippets-filters/) guide. +This directory contains the YAML files used in the [Use the SnippetsFilter API](https://docs.nginx.com/nginx-gateway-fabric/how-to/traffic-management/snippets/) guide. diff --git a/site/content/how-to/traffic-management/snippets-filters.md b/site/content/how-to/traffic-management/snippets.md similarity index 97% rename from site/content/how-to/traffic-management/snippets-filters.md rename to site/content/how-to/traffic-management/snippets.md index 76804cb1a9..24e3935ed4 100644 --- a/site/content/how-to/traffic-management/snippets-filters.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -17,6 +17,9 @@ NGINX configurations that NGINX Gateway Fabric generates. Snippets are for advanced NGINX users who need more control over the generated NGINX configuration, and can be used in cases where Gateway API resources or NGINX extensions policies don't apply. +Users can configure Snippets through the `SnippetsFilter` API. `SnippetsFilter` is an [HTTPRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter) +that attaches to an HTTP/GRPCRoute rule and is intended to modify NGINX configuration specifically for that Route rule. + --- ## Disadvantages of Snippets From 300778370d0ef6e8a348b4cbc7b237241de4e449 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Thu, 24 Oct 2024 16:54:59 -0700 Subject: [PATCH 07/20] Add a conclusion statement --- site/content/how-to/traffic-management/snippets.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 24e3935ed4..70ba1ea410 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -351,6 +351,8 @@ for i in `seq 1 10`; do curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://c You should see all successful responses from the tea Pod, but they should be spaced apart roughly one second each as expected through the rate limiting configuration. +You've now used the `SnippetFilter` resource to configure two distinct rate limiting rules to different backend applications through the use of Snippets. + --- ## Further reading From 135282f7e4bdd8a721cdbf0e928b067aa83855db Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Thu, 24 Oct 2024 16:59:03 -0700 Subject: [PATCH 08/20] Add more to conclusion statement --- site/content/how-to/traffic-management/snippets.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 70ba1ea410..209e1ba163 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -352,6 +352,8 @@ You should see all successful responses from the tea Pod, but they should be spa expected through the rate limiting configuration. You've now used the `SnippetFilter` resource to configure two distinct rate limiting rules to different backend applications through the use of Snippets. +For an alternative method of modifying the NGINX configuration NGINX Gateway Fabric generates through Gateway API resources, check out +our supported [first-class policies]({{< relref "overview/custom-policies.md" >}}) which don't carry many of the aforementioned disadvantages of Snippets. --- From 387c531d11430a55aa789fea23d9fade08a2cee9 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Mon, 28 Oct 2024 10:18:59 -0700 Subject: [PATCH 09/20] Add more feedback --- examples/snippets-filter/README.md | 2 +- site/content/how-to/traffic-management/snippets.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/snippets-filter/README.md b/examples/snippets-filter/README.md index 219f26e618..dce0157962 100644 --- a/examples/snippets-filter/README.md +++ b/examples/snippets-filter/README.md @@ -1,3 +1,3 @@ # SnippetsFilter -This directory contains the YAML files used in the [Use the SnippetsFilter API](https://docs.nginx.com/nginx-gateway-fabric/how-to/traffic-management/snippets/) guide. +This directory contains the YAML files used in the [SnippetsFilter API](https://docs.nginx.com/nginx-gateway-fabric/how-to/traffic-management/snippets/) guide. diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 209e1ba163..ffd8ac6627 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -15,7 +15,7 @@ Snippets allow users to insert NGINX configuration into different contexts of th NGINX configurations that NGINX Gateway Fabric generates. Snippets are for advanced NGINX users who need more control over the generated NGINX configuration, -and can be used in cases where Gateway API resources or NGINX extensions policies don't apply. +and can be used in cases where Gateway API resources or NGINX extension policies don't apply. Users can configure Snippets through the `SnippetsFilter` API. `SnippetsFilter` is an [HTTPRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter) that attaches to an HTTP/GRPCRoute rule and is intended to modify NGINX configuration specifically for that Route rule. @@ -45,7 +45,7 @@ Snippets have the following disadvantages: ## Setup - To enable Snippets, [install]({{< relref "/installation/" >}}) NGINX Gateway Fabric with these modifications: - - Using Helm: set the `nginxGateway.snippetsFilters.enable` command line argument to true. + - Using Helm: set the `nginxGateway.snippetsFilters.enable=true` Helm value. - Using Kubernetes manifests: set the `--snippets-filters` flag in the nginx-gateway container argument, add `snippetsfilters` to the RBAC rules with verbs `list` and `watch`, and add `snippetsfilters/status` to the RBAC rules with verb `update`. See this [example manifest](https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/main/deploy/snippets-filters/deploy.yaml) for clarification. @@ -351,7 +351,7 @@ for i in `seq 1 10`; do curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://c You should see all successful responses from the tea Pod, but they should be spaced apart roughly one second each as expected through the rate limiting configuration. -You've now used the `SnippetFilter` resource to configure two distinct rate limiting rules to different backend applications through the use of Snippets. +You've now used the `SnippetsFilter` resource to configure two distinct rate limiting rules to different backend applications through the use of Snippets. For an alternative method of modifying the NGINX configuration NGINX Gateway Fabric generates through Gateway API resources, check out our supported [first-class policies]({{< relref "overview/custom-policies.md" >}}) which don't carry many of the aforementioned disadvantages of Snippets. From 4f905137df4811d7183814ee3fa7ce7c407acc72 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Mon, 28 Oct 2024 16:11:57 -0700 Subject: [PATCH 10/20] Refactor document layout to remove troubleshooting in setup --- examples/snippets-filter/httproutes.yaml | 12 -- .../how-to/traffic-management/snippets.md | 150 +++++++++++------- 2 files changed, 89 insertions(+), 73 deletions(-) diff --git a/examples/snippets-filter/httproutes.yaml b/examples/snippets-filter/httproutes.yaml index 29c1f55e42..fe2c435980 100644 --- a/examples/snippets-filter/httproutes.yaml +++ b/examples/snippets-filter/httproutes.yaml @@ -13,12 +13,6 @@ spec: - path: type: PathPrefix value: /coffee - filters: - - type: ExtensionRef - extensionRef: - group: gateway.nginx.org - kind: SnippetsFilter - name: coffee-rate-limiting-sf backendRefs: - name: coffee port: 80 @@ -38,12 +32,6 @@ spec: - path: type: PathPrefix value: /tea - filters: - - type: ExtensionRef - extensionRef: - group: gateway.nginx.org - kind: SnippetsFilter - name: tea-rate-limiting-sf backendRefs: - name: tea port: 80 diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index ffd8ac6627..9524ffde46 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -5,7 +5,7 @@ toc: true docs: "DOCS-000" --- -This topic introduces Snippets and how to implement them using the `SnippetsFilter` API. It provides an example of how to use a Snippet for rate limiting, and how to investigate errors caused by misconfiguration. +This topic introduces Snippets, how to implement them using the `SnippetsFilter` API, and provides an example of how to use `SnippetsFilter` for rate limiting. --- @@ -86,67 +86,33 @@ Snippets have the following disadvantages: curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee ``` + This request should receive a response from the coffee Pod: + + ```text + Server address: 10.244.0.7:8080 + Server name: coffee-76c7c85bbd-cf8nz + ``` + Send a request to tea: ```shell curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/tea - ``` + ``` - Both requests should receive this response from the backend Pod: + This request should receive a response from the tea Pod: ```text - - 500 Internal Server Error - -

500 Internal Server Error

-
nginx
- - + Server address: 10.244.0.6:8080 + Server name: tea-76c7c85bbd-cf8nz ``` - Use `kubectl describe` to investigate HTTPRoutes for the error: + Before we enable rate limiting, try sending multiple requests to coffee: ```shell - kubectl describe httproutes.gateway.networking.k8s.io + for i in `seq 1 10`; do curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee; done ``` - You should see the following conditions: - - ```text - Conditions: - Last Transition Time: 2024-10-22T23:43:11Z - Message: The route is accepted - Observed Generation: 1 - Reason: Accepted - Status: True - Type: Accepted - Last Transition Time: 2024-10-22T23:43:11Z - Message: spec.rules[0].filters[0].extensionRef: Not found: v1.LocalObjectReference{Group:"gateway.nginx.org", Kind:"SnippetsFilter", Name:"coffee-rate-limiting-sf"} - Observed Generation: 1 - Reason: InvalidFilter - Status: False - Type: ResolvedRefs - . - . - . - Conditions: - Last Transition Time: 2024-10-22T23:43:14Z - Message: The route is accepted - Observed Generation: 1 - Reason: Accepted - Status: True - Type: Accepted - Last Transition Time: 2024-10-22T23:43:14Z - Message: spec.rules[0].filters[0].extensionRef: Not found: v1.LocalObjectReference{Group:"gateway.nginx.org", Kind:"SnippetsFilter", Name:"tea-rate-limiting-sf"} - Observed Generation: 1 - Reason: InvalidFilter - Status: False - Type: ResolvedRefs - ``` - - The HTTPRoutes created earlier both reference `SnippetsFilter` resources that do not currently - exist, creating a 500 error code response returned on requests that are processed by these HTTPRoutes. - This issue will be resolved using SnippetsFilters. + You should see all successful responses in quick succession as we configured any rate limiting rules yet. --- @@ -163,14 +129,13 @@ metadata: spec: snippets: - context: http - value: limit_req_zone $binary_remote_addr zone=coffeezone:10m rate=1r/s; + value: limit_req_zone \$binary_remote_addr zone=coffeezone:10m rate=1r/s; - context: http.server.location value: limit_req zone=coffeezone burst=3 nodelay; EOF ``` -This `SnippetsFilter` is already referenced by the HTTPRoute created during setup, so it will immediately apply -to the HTTPRoute. The Snippet uses the NGINX `limit_req_module` to configure rate limiting for this HTTPRoute and the +The Snippet uses the NGINX `limit_req_module` to configure rate limiting for this HTTPRoute and the backend coffee application. This snippet will limit the request processing rate to 1 request per second, and if there are more than 3 requests in queue, it will throw a 503 error. @@ -196,7 +161,38 @@ Status: Events: ``` -Verify that the coffee `HTTPRoute` which had an `InvalidFilter` condition earlier, no longer has that condition. +To use the `SnippetsFilter`, update the coffee HTTPRoute to reference it: + +```yaml +kubectl apply -f - < ``` -Verify that the tea `HTTPRoute` which had an `InvalidFilter` condition earlier, no longer has that condition. + +Update the tea HTTPRoute to reference the `SnippetsFilter`: + +```yaml +kubectl apply -f - < Date: Tue, 29 Oct 2024 09:16:40 -0700 Subject: [PATCH 11/20] Add docs feedback --- site/content/how-to/traffic-management/snippets.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 9524ffde46..4c15cca8f5 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -42,6 +42,8 @@ Snippets have the following disadvantages: {{< note >}} If you end up using Snippets and run into situations where an NGINX directive fails to be applied, please create an issue in the [NGINX Gateway Fabric Github repository](https://github.com/nginxinc/nginx-gateway-fabric). {{< /note >}} +--- + ## Setup - To enable Snippets, [install]({{< relref "/installation/" >}}) NGINX Gateway Fabric with these modifications: @@ -52,7 +54,7 @@ Snippets have the following disadvantages: - Save the public IP address and port of NGINX Gateway Fabric into shell variables: ```text - GW_IP=XXX.YYY.ZZZ.III + GW_IP= GW_PORT= ``` @@ -192,7 +194,7 @@ spec: EOF ``` -Verify that the coffee HTTPRoute's has been configured correctly: +Verify that the coffee HTTPRoute has been configured correctly: ```shell kubectl describe httproutes.gateway.networking.k8s.io coffee @@ -298,7 +300,6 @@ Status: Events: ``` - Update the tea HTTPRoute to reference the `SnippetsFilter`: ```yaml @@ -330,7 +331,7 @@ spec: EOF ``` -Verify that the tea HTTPRoute's has been configured correctly: +Verify that the tea HTTPRoute has been configured correctly: ```shell kubectl describe httproutes.gateway.networking.k8s.io tea @@ -379,12 +380,12 @@ for i in `seq 1 10`; do curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://c You should see all successful responses from the tea Pod, but they should be spaced apart roughly one second each as expected through the rate limiting configuration. -You've now used the `SnippetsFilter` resource to configure two distinct rate limiting rules to different backend applications through the use of Snippets. +This indicates that you've successfully used Snippets with the `SnippetsFilter` resource to configure two distinct rate limiting rules to different backend applications. For an alternative method of modifying the NGINX configuration NGINX Gateway Fabric generates through Gateway API resources, check out our supported [first-class policies]({{< relref "overview/custom-policies.md" >}}) which don't carry many of the aforementioned disadvantages of Snippets. --- -## Further reading +## See also - [API reference]({{< relref "reference/api.md" >}}): all configuration fields for the `SnippetsFilter` API. From eb7313dc92fb3cda2daf354f1683decf4e38e258 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Tue, 29 Oct 2024 15:08:31 -0700 Subject: [PATCH 12/20] Add feedback --- .../coffee-snippets-filter.yaml | 10 ------ .../no-delay-rate-limiting-sf.yaml | 10 ++++++ .../snippets-filter/rate-limiting-sf.yaml | 10 ++++++ .../snippets-filter/tea-snippets-filter.yaml | 10 ------ .../how-to/traffic-management/snippets.md | 32 ++++++++++--------- 5 files changed, 37 insertions(+), 35 deletions(-) delete mode 100644 examples/snippets-filter/coffee-snippets-filter.yaml create mode 100644 examples/snippets-filter/no-delay-rate-limiting-sf.yaml create mode 100644 examples/snippets-filter/rate-limiting-sf.yaml delete mode 100644 examples/snippets-filter/tea-snippets-filter.yaml diff --git a/examples/snippets-filter/coffee-snippets-filter.yaml b/examples/snippets-filter/coffee-snippets-filter.yaml deleted file mode 100644 index 5202f302ea..0000000000 --- a/examples/snippets-filter/coffee-snippets-filter.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: gateway.nginx.org/v1alpha1 -kind: SnippetsFilter -metadata: - name: coffee-rate-limiting-sf -spec: - snippets: - - context: http - value: limit_req_zone $binary_remote_addr zone=coffeezone:10m rate=1r/s; - - context: http.server.location - value: limit_req zone=coffeezone burst=3 nodelay; diff --git a/examples/snippets-filter/no-delay-rate-limiting-sf.yaml b/examples/snippets-filter/no-delay-rate-limiting-sf.yaml new file mode 100644 index 0000000000..d6dd9334e3 --- /dev/null +++ b/examples/snippets-filter/no-delay-rate-limiting-sf.yaml @@ -0,0 +1,10 @@ +apiVersion: gateway.nginx.org/v1alpha1 +kind: SnippetsFilter +metadata: + name: no-delay-rate-limiting-sf +spec: + snippets: + - context: http + value: limit_req_zone $binary_remote_addr zone=no-delay-rate-limiting-sf:10m rate=1r/s; + - context: http.server.location + value: limit_req zone=no-delay-rate-limiting-sf burst=3 nodelay; diff --git a/examples/snippets-filter/rate-limiting-sf.yaml b/examples/snippets-filter/rate-limiting-sf.yaml new file mode 100644 index 0000000000..547a298d84 --- /dev/null +++ b/examples/snippets-filter/rate-limiting-sf.yaml @@ -0,0 +1,10 @@ +apiVersion: gateway.nginx.org/v1alpha1 +kind: SnippetsFilter +metadata: + name: rate-limiting-sf +spec: + snippets: + - context: http + value: limit_req_zone $binary_remote_addr zone=rate-limiting-sf:10m rate=1r/s; + - context: http.server.location + value: limit_req zone=rate-limiting-sf burst=3; diff --git a/examples/snippets-filter/tea-snippets-filter.yaml b/examples/snippets-filter/tea-snippets-filter.yaml deleted file mode 100644 index abcd2daec8..0000000000 --- a/examples/snippets-filter/tea-snippets-filter.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: gateway.nginx.org/v1alpha1 -kind: SnippetsFilter -metadata: - name: tea-rate-limiting-sf -spec: - snippets: - - context: http - value: limit_req_zone $binary_remote_addr zone=teazone:10m rate=1r/s; - - context: http.server.location - value: limit_req zone=teazone burst=3; diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 4c15cca8f5..fcacf669f2 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -17,8 +17,8 @@ NGINX configurations that NGINX Gateway Fabric generates. Snippets are for advanced NGINX users who need more control over the generated NGINX configuration, and can be used in cases where Gateway API resources or NGINX extension policies don't apply. -Users can configure Snippets through the `SnippetsFilter` API. `SnippetsFilter` is an [HTTPRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter) -that attaches to an HTTP/GRPCRoute rule and is intended to modify NGINX configuration specifically for that Route rule. +Users can configure Snippets through the `SnippetsFilter` API. `SnippetsFilter` can be an [HTTPRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter) or [GRPCRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GRPCRouteFilter), +that can be defined in an HTTP/GRPCRoute rule and is intended to modify NGINX configuration specifically for that Route rule. `SnippetsFilter` is an `extensionRef` type filter. --- @@ -37,7 +37,7 @@ Snippets have the following disadvantages: - _Decreased robustness_. An incorrect Snippet can invalidate NGINX configuration, causing reload failures. Until the snippet is fixed, it will prevent any new configuration updates, including updates for the other Gateway resources. - _Security implications_. Snippets give access to NGINX configuration primitives, which are not validated by NGINX Gateway Fabric. For example, a Snippet can configure NGINX to serve the TLS certificates and keys used for TLS termination for Gateway resources. -{{< note >}} If the NGINX configuration includes an invalid Snippet, NGINX will continue to operate with the last valid configuration. {{< /note >}} +{{< note >}} If the NGINX configuration includes an invalid Snippet, NGINX will continue to operate with the last valid configuration. No new configuration will be applied until the invalid Snippet is fixed. {{< /note >}} {{< note >}} If you end up using Snippets and run into situations where an NGINX directive fails to be applied, please create an issue in the [NGINX Gateway Fabric Github repository](https://github.com/nginxinc/nginx-gateway-fabric). {{< /note >}} @@ -127,24 +127,26 @@ kubectl apply -f - < Date: Tue, 29 Oct 2024 15:32:09 -0700 Subject: [PATCH 13/20] Add troubleshooting section --- .../how-to/traffic-management/snippets.md | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index fcacf669f2..23562fa125 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -388,6 +388,62 @@ our supported [first-class policies]({{< relref "overview/custom-policies.md" >} --- +## Troubleshooting + +If a `SnippetsFilter` is defined in a Route resource and contains a Snippet which includes an invalid NGINX configuration, NGINX will continue to operate +with the last valid configuration and an event with the error will be outputted. No new configuration will be applied until the invalid Snippet is fixed. + +An example of an error from the NGINX Gateway Fabric `nginx-gateway` container logs: + +```text +{"level":"error","ts":"2024-10-29T22:19:41Z","logger":"eventLoop.eventHandler","msg":"Failed to update NGINX configuration","batchID":156,"error":"failed to reload NGINX: reload unsuccessful: no new NGINX worker processes started for config version 141. Please check the NGINX container logs for possible configuration issues: context deadline exceeded","stacktrace":"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static.(*eventHandlerImpl).HandleEventBatch\n\tgithub.com/nginxinc/nginx-gateway-fabric/internal/mode/static/handler.go:219\ngithub.com/nginxinc/nginx-gateway-fabric/internal/framework/events.(*EventLoop).Start.func1.1\n\tgithub.com/nginxinc/nginx-gateway-fabric/internal/framework/events/loop.go:74"} +``` + +An example of an error from the NGINX Gateway Fabric `nginx` container logs: + +```text +2024/10/29 22:18:41 [emerg] 40#40: invalid number of arguments in "limit_req_zone" directive in /etc/nginx/includes/SnippetsFilter_http_default_rate-limiting-sf.conf:1 +``` + +The Route resource which references the `SnippetsFilter` may also contain information in its conditions describing the error: + +```text + Conditions: + Last Transition Time: 2024-10-29T22:19:41Z + Message: All references are resolved + Observed Generation: 2 + Reason: ResolvedRefs + Status: True + Type: ResolvedRefs + Last Transition Time: 2024-10-29T22:19:41Z + Message: The Gateway is not programmed due to a failure to reload nginx with the configuration. Please see the nginx container logs for any possible configuration issues. NGINX may still be configured for this Route. However, future updates to this resource will not be configured until the Gateway is programmed again + Observed Generation: 2 + Reason: GatewayNotProgrammed + Status: False + Type: Accepted +``` + +If a Route resource references a `SnippetsFilter` which cannot be resolved, the route will return a 500 HTTP error response on all requests. +The Route conditions will contain information describing the error: + +```text +Conditions: + Last Transition Time: 2024-10-29T22:26:01Z + Message: The route is accepted + Observed Generation: 2 + Reason: Accepted + Status: True + Type: Accepted + Last Transition Time: 2024-10-29T22:26:01Z + Message: spec.rules[0].filters[0].extensionRef: Not found: v1.LocalObjectReference{Group:"gateway.nginx.org", Kind:"SnippetsFilter", Name:"rate-limiting-sf"} + Observed Generation: 2 + Reason: InvalidFilter + Status: False + Type: ResolvedRefs +``` + +--- + ## See also - [API reference]({{< relref "reference/api.md" >}}): all configuration fields for the `SnippetsFilter` API. From 6c9626190d457e4744bd892e97155fe3897448c0 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Tue, 29 Oct 2024 15:33:03 -0700 Subject: [PATCH 14/20] Adjust small wording --- site/content/how-to/traffic-management/snippets.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 23562fa125..d95d2c4ce6 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -390,7 +390,7 @@ our supported [first-class policies]({{< relref "overview/custom-policies.md" >} ## Troubleshooting -If a `SnippetsFilter` is defined in a Route resource and contains a Snippet which includes an invalid NGINX configuration, NGINX will continue to operate +If a `SnippetsFilter` is defined in a Route and contains a Snippet which includes an invalid NGINX configuration, NGINX will continue to operate with the last valid configuration and an event with the error will be outputted. No new configuration will be applied until the invalid Snippet is fixed. An example of an error from the NGINX Gateway Fabric `nginx-gateway` container logs: @@ -405,7 +405,7 @@ An example of an error from the NGINX Gateway Fabric `nginx` container logs: 2024/10/29 22:18:41 [emerg] 40#40: invalid number of arguments in "limit_req_zone" directive in /etc/nginx/includes/SnippetsFilter_http_default_rate-limiting-sf.conf:1 ``` -The Route resource which references the `SnippetsFilter` may also contain information in its conditions describing the error: +The Route which references the `SnippetsFilter` may also contain information in its conditions describing the error: ```text Conditions: @@ -423,7 +423,7 @@ The Route resource which references the `SnippetsFilter` may also contain inform Type: Accepted ``` -If a Route resource references a `SnippetsFilter` which cannot be resolved, the route will return a 500 HTTP error response on all requests. +If a Route references a `SnippetsFilter` which cannot be resolved, the route will return a 500 HTTP error response on all requests. The Route conditions will contain information describing the error: ```text From ce1557c54f13ebe059ba288d399a8809b9413c7c Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Tue, 29 Oct 2024 15:37:24 -0700 Subject: [PATCH 15/20] Move recommendation to open issue in github down to troubleshooting --- site/content/how-to/traffic-management/snippets.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index d95d2c4ce6..7d1b265a1a 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -39,9 +39,6 @@ Snippets have the following disadvantages: {{< note >}} If the NGINX configuration includes an invalid Snippet, NGINX will continue to operate with the last valid configuration. No new configuration will be applied until the invalid Snippet is fixed. {{< /note >}} -{{< note >}} If you end up using Snippets and run into situations where an NGINX directive fails to be applied, please create an issue in the -[NGINX Gateway Fabric Github repository](https://github.com/nginxinc/nginx-gateway-fabric). {{< /note >}} - --- ## Setup @@ -442,6 +439,9 @@ Conditions: Type: ResolvedRefs ``` +{{< note >}} If you run into situations where an NGINX directive fails to be applied and the troubleshooting information here isn't sufficient, please create an issue in the +[NGINX Gateway Fabric Github repository](https://github.com/nginxinc/nginx-gateway-fabric). {{< /note >}} + --- ## See also From 3ae7bdf45e61216a78aa0f51f54f4534b90c9ee9 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Wed, 30 Oct 2024 11:03:42 -0700 Subject: [PATCH 16/20] Add best practices section --- .../content/how-to/traffic-management/snippets.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 7d1b265a1a..9f3861108f 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -18,7 +18,7 @@ Snippets are for advanced NGINX users who need more control over the generated N and can be used in cases where Gateway API resources or NGINX extension policies don't apply. Users can configure Snippets through the `SnippetsFilter` API. `SnippetsFilter` can be an [HTTPRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter) or [GRPCRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GRPCRouteFilter), -that can be defined in an HTTP/GRPCRoute rule and is intended to modify NGINX configuration specifically for that Route rule. `SnippetsFilter` is an `extensionRef` type filter. +that can be defined in an HTTPRoute/GRPCRoute rule and is intended to modify NGINX configuration specifically for that Route rule. `SnippetsFilter` is an `extensionRef` type filter. --- @@ -41,6 +41,19 @@ Snippets have the following disadvantages: --- +## Best Practices when using SnippetsFilters + +There are endless ways to use `SnippetsFilters` to modify NGINX configuration, and thus there are many ways to generate invalid or undesired NGINX configuration. +We have outlined a few best practices to keep in mind when using `SnippetsFilters` to keep NGINX Gateway Fabric functioning correctly: + +1. Using the [Roles and Personas](https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/) defined in the Gateway API, `SnippetsFilter` access + should be limited to Cluster operators. Application developers should not be able to create, modify, or delete `SnippetsFilters` as they affect other applications. + `SnippetsFilter` creates a natural split of responsibilities between the Cluster operator and the Application developer: the Cluster operator creates a `SnippetsFilter`; the Application developer references the `SnippetsFilter` in an HTTPRoute/GRPCRoute to enable it. +2. In a `SnippetsFilter`, only one Snippet per NGINX context is allowed, however multiple `SnippetsFilters` can be referenced in the same routing rule. As such, `SnippetsFilters` should not conflict with each other. If `SnippetsFilters` do conflict, they should not be referenced on the same routing rule. +3. `SnippetsFilters` that define Snippets targeting NGINX contexts `main`, `http`, or `http.server`, can potentially affect more than the routing rule they are referenced by. Proceed with caution and verify the behavior of the NGINX configuration before creating those `SnippetsFilters` in a production scenario. + +--- + ## Setup - To enable Snippets, [install]({{< relref "/installation/" >}}) NGINX Gateway Fabric with these modifications: From 402ba9d051bc5a13b89753604c0217695c8de356 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Thu, 31 Oct 2024 10:35:53 -0700 Subject: [PATCH 17/20] Add small wording change --- site/content/how-to/traffic-management/snippets.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 9f3861108f..733bd9c0de 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -147,9 +147,8 @@ spec: EOF ``` -This `SnippetsFilter` defines two Snippets to configure rate limiting for this HTTPRoute and the -backend coffee application. The first one injects the value: `limit_req_zone \$binary_remote_addr zone=no-delay-rate-limiting-sf:10m rate=1r/s;` -into the `http` context. The second one injects the value: `limit_req zone=no-delay-rate-limiting-sf burst=3 nodelay;` into the location(s) for `/coffee`. +This `SnippetsFilter` defines two Snippets to configure rate limiting. The first Snippet injects the value: `limit_req_zone \$binary_remote_addr zone=no-delay-rate-limiting-sf:10m rate=1r/s;` +into the `http` context. The second Snippet injects the value: `limit_req zone=no-delay-rate-limiting-sf burst=3 nodelay;` into the location(s) generated for the routing rule. This `SnippetsFilter` will limit the request processing rate to 1 request per second, and if there are more than 3 requests in queue, it will throw a 503 error. From 4e74a2c017713169f7c80d9322640b6b7ff4016b Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Thu, 31 Oct 2024 11:07:17 -0700 Subject: [PATCH 18/20] Add reorganization of document --- .../how-to/traffic-management/snippets.md | 156 ++++++++++-------- 1 file changed, 84 insertions(+), 72 deletions(-) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 733bd9c0de..38a120be4c 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -128,9 +128,52 @@ We have outlined a few best practices to keep in mind when using `SnippetsFilter --- -## Configure rate limiting to the coffee application +## Create Rate Limiting SnippetsFilters -Configure rate limiting to the coffee application by adding the following `SnippetsFilter`: +Configure a rate limiting `SnippetsFilter` named `rate-limiting-sf` by adding the following `SnippetsFilter`: + +```yaml +kubectl apply -f - < +``` + +Configure another rate limiting `SnippetsFilter` named `no-delay-rate-limiting-sf` by adding the following `SnippetsFilter`: ```yaml kubectl apply -f - < ``` -To use the `SnippetsFilter`, update the coffee HTTPRoute to reference it: +## Configure coffee to reference rate-limiting-sf SnippetsFilter + +To use the `rate-limiting-sf` `SnippetsFilter`, update the coffee HTTPRoute to reference it: ```yaml kubectl apply -f - < -503 Service Temporarily Unavailable - -

503 Service Temporarily Unavailable

-
nginx
- - -``` - -This is the default error response given by NGINX when the rate limit burst is exceeded, meaning our `SnippetsFilter` -correctly applied our rate limiting NGINX configuration changes. - -## Configure rate limiting to the tea application - -Configure a different set of rate limiting rules to the tea application by adding the following `SnippetsFilter`: - -```yaml -kubectl apply -f - < -``` - -Update the tea HTTPRoute to reference the `SnippetsFilter`: +Update the tea HTTPRoute to reference the `no-delay-rate-limting-sf` `SnippetsFilter`: ```yaml kubectl apply -f - < +503 Service Temporarily Unavailable + +

503 Service Temporarily Unavailable

+
nginx
+ + +``` + +This is the default error response given by NGINX when the rate limit burst is exceeded, meaning our `SnippetsFilter` +correctly applied our rate limiting NGINX configuration changes. + +--- + +## Conclusion + +You've successfully used Snippets with the `SnippetsFilter` resource to configure two distinct rate limiting rules to different backend applications. + +In this example guide, the Cluster Operator would have played the role in creating and applying the `SnippetsFilter` resources shown in [Create Rate Limiting SnippetsFilters](#create-rate-limiting-snippetsfilters) +while the Application Developers for coffee and tea would have played the role in modifying their application to reference whichever `SnippetsFilter` they want shown in +[Configure coffee to reference rate-limiting-sf SnippetsFilter](#configure-coffee-to-reference-rate-limiting-sf-snippetsfilter) and [Configure tea to reference no-delay-rate-limiting-sf SnippetsFilter](#configure-tea-to-reference-no-delay-rate-limiting-sf-snippetsfilter). +This follows our recommended Role and Persona separation described in the [Best Practices when using SnippetsFilters](#best-practices-when-using-snippetsfilters). -This indicates that you've successfully used Snippets with the `SnippetsFilter` resource to configure two distinct rate limiting rules to different backend applications. For an alternative method of modifying the NGINX configuration NGINX Gateway Fabric generates through Gateway API resources, check out our supported [first-class policies]({{< relref "overview/custom-policies.md" >}}) which don't carry many of the aforementioned disadvantages of Snippets. From 1933a97e574de33c86d27c105dfb9adb8907c72d Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Mon, 11 Nov 2024 21:32:05 -0800 Subject: [PATCH 19/20] Add small typo --- site/content/how-to/traffic-management/snippets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index 38a120be4c..d79a9c7694 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -124,7 +124,7 @@ We have outlined a few best practices to keep in mind when using `SnippetsFilter for i in `seq 1 10`; do curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee; done ``` - You should see all successful responses in quick succession as we configured any rate limiting rules yet. + You should see all successful responses in quick succession as we have not configured any rate limiting rules yet. --- From ffd09a44bf7fee971c4c344f5f52fb6629f5cd49 Mon Sep 17 00:00:00 2001 From: Benjamin Jee Date: Mon, 11 Nov 2024 21:34:18 -0800 Subject: [PATCH 20/20] Add stronger language edits --- site/content/how-to/traffic-management/snippets.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index d79a9c7694..6064ee5dbf 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -14,8 +14,8 @@ This topic introduces Snippets, how to implement them using the `SnippetsFilter` Snippets allow users to insert NGINX configuration into different contexts of the NGINX configurations that NGINX Gateway Fabric generates. -Snippets are for advanced NGINX users who need more control over the generated NGINX configuration, -and can be used in cases where Gateway API resources or NGINX extension policies don't apply. +Snippets should only be used by advanced NGINX users who need more control over the generated NGINX configuration, +and only in cases where Gateway API resources or NGINX extension policies don't apply. Users can configure Snippets through the `SnippetsFilter` API. `SnippetsFilter` can be an [HTTPRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter) or [GRPCRouteFilter](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.GRPCRouteFilter), that can be defined in an HTTPRoute/GRPCRoute rule and is intended to modify NGINX configuration specifically for that Route rule. `SnippetsFilter` is an `extensionRef` type filter.