diff --git a/.yamllint.yaml b/.yamllint.yaml index 18093520d6..b0e6d6d7dd 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -7,6 +7,7 @@ ignore: - charts/nginx-gateway-fabric/ - config/crd/bases/ - deploy/crds.yaml + - site/static rules: braces: enable diff --git a/site/content/how-to/maintenance/_index.md b/site/content/how-to/maintenance/_index.md index 5c33e95bbc..dd64b81b48 100644 --- a/site/content/how-to/maintenance/_index.md +++ b/site/content/how-to/maintenance/_index.md @@ -1,7 +1,7 @@ --- title: "Maintenance and Upgrades" description: -weight: 400 +weight: 500 linkTitle: "Maintenance and Upgrades" menu: docs: diff --git a/site/content/how-to/monitoring/_index.md b/site/content/how-to/monitoring/_index.md index 0213ee98e3..c649a3153b 100644 --- a/site/content/how-to/monitoring/_index.md +++ b/site/content/how-to/monitoring/_index.md @@ -1,7 +1,7 @@ --- title: "Monitoring and Troubleshooting" description: -weight: 500 +weight: 400 linkTitle: "Monitoring and Troubleshooting" menu: docs: diff --git a/site/content/how-to/monitoring/dashboard.md b/site/content/how-to/monitoring/dashboard.md index 97cf0fbdf5..8ff5dc79c4 100644 --- a/site/content/how-to/monitoring/dashboard.md +++ b/site/content/how-to/monitoring/dashboard.md @@ -1,7 +1,7 @@ --- title: "NGINX Plus Dashboard" description: "Learn how to view the NGINX Plus dashboard to see real-time metrics." -weight: 200 +weight: 300 toc: true docs: "DOCS-1417" --- diff --git a/site/content/how-to/monitoring/prometheus.md b/site/content/how-to/monitoring/prometheus.md index ea891feb81..d0238051e2 100644 --- a/site/content/how-to/monitoring/prometheus.md +++ b/site/content/how-to/monitoring/prometheus.md @@ -66,7 +66,7 @@ In the Grafana UI menu, go to `Connections` then `Data sources`. Add your Promet Download the following sample dashboard and Import as a new Dashboard in the Grafana UI. -{{< download "grafana-dashboard.json" "ngf-grafana-dashboard.json" >}} +- {{< download "grafana-dashboard.json" "ngf-grafana-dashboard.json" >}} ## Available metrics in NGINX Gateway Fabric diff --git a/site/content/how-to/monitoring/tracing.md b/site/content/how-to/monitoring/tracing.md new file mode 100644 index 0000000000..679aa0d7f5 --- /dev/null +++ b/site/content/how-to/monitoring/tracing.md @@ -0,0 +1,328 @@ +--- +title: "Tracing" +weight: 200 +toc: true +docs: "DOCS-000" +--- + +Learn how to configure tracing in NGINX Gateway Fabric. + +## Overview + +NGINX Gateway Fabric supports tracing using [OpenTelemetry](https://opentelemetry.io/). The official [NGINX OpenTelemetry Module](https://github.com/nginxinc/nginx-otel) instruments the NGINX data plane to export traces to a configured collector. Tracing data can be used with an OpenTelemetry Protocol (OTLP) exporter, such as the [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector). This collector can then export data to one or more upstream collectors like [Jaeger](https://www.jaegertracing.io/), [DataDog](https://docs.datadoghq.com/tracing/), and many others. This is called the [Agent model](https://opentelemetry.io/docs/collector/deployment/agent/). + +This guide explains how to enable tracing on HTTPRoutes using NGINX Gateway Fabric. It uses the OpenTelemetry Collector and Jaeger to process and collect the traces. + +## Install the Collectors + +The first step is to install the collectors. NGINX Gateway Fabric will be configured to export to the OpenTelemetry Collector, which is configured to export to Jaeger. This model allows the visualization collector (Jaeger) to be swapped with something else, or to add more collectors without needing to reconfigure NGINX Gateway Fabric. It is also possible to configure NGINX Gateway Fabric to export directly to Jaeger. + +Create the namespace: + +```shell +kubectl create namespace monitoring +``` + +Download the following files containing the configurations for the collectors: + +- {{< download "otel-collector.yaml" "otel-collector.yaml" >}} +- {{< download "jaeger.yaml" "jaeger.yaml" >}} + +{{< note >}}These collectors are for demonstration purposes and are not tuned for production use.{{< /note >}} + +Then install them: + +```shell +kubectl apply -f otel-collector.yaml -f jaeger.yaml -n monitoring +``` + +Ensure the Pods are running: + +```shell +kubectl -n monitoring get pods +``` + +```text +NAME READY STATUS RESTARTS AGE +jaeger-8469f69b86-bfpk9 1/1 Running 0 9s +otel-collector-f786b7dfd-h2x9l 1/1 Running 0 9s +``` + +Once running, you can access the Jaeger dashboard by using port-forwarding in the background: + +```shell +kubectl port-forward -n monitoring svc/jaeger 16686:16686 & +``` + +Visit [http://127.0.0.1:16686](http://127.0.0.1:16686) to view the dashboard. + +## Enable tracing + +To enable tracing, you must configure two resources: + +- `NginxProxy`: This resource contains global settings relating to the NGINX data plane. It is created and managed by the [cluster operator](https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/), and is referenced in the `parametersRef` field of the GatewayClass. This resource can be created and linked when we install NGINX Gateway Fabric using its helm chart, or it can be added later. This guide installs the resource using the helm chart, but the resource can also be created for an existing deployment. + + The `NginxProxy` resource contains configuration for the collector, and applies to all Gateways and routes under the GatewayClass. It does not enable tracing, but is a prerequisite to the next piece of configuration. + +- `ObservabilityPolicy`: This resource is a [Direct PolicyAttachment](https://gateway-api.sigs.k8s.io/reference/policy-attachment/) that targets HTTPRoutes or GRPCRoutes. It is created by the [application developer](https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/) and enables tracing for a specific route or routes. It requires the `NginxProxy` resource to exist in order to complete the tracing configuration. + +### Install NGINX Gateway Fabric with global tracing configuration + +{{< note >}}Ensure that you [install the Gateway API resources]({{< relref "installation/installing-ngf/helm.md#installing-the-gateway-api-resources" >}}).{{< /note >}} + +Referencing the previously deployed collector, create the following `values.yaml` file for installing NGINX Gateway Fabric: + +```yaml +cat < values.yaml +nginx: + config: + telemetry: + exporter: + endpoint: otel-collector.tracing.svc:4317 + spanAttributes: + - key: cluster-attribute-key + value: cluster-attribute-value +EOT +``` + +The span attribute will be added to all tracing spans. + +To install: + +```shell +helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --create-namespace -n nginx-gateway -f values.yaml +``` + +You should see the following configuration: + +```shell +kubectl get nginxproxies.gateway.nginx.org ngf-proxy-config -o yaml +``` + +```yaml +apiVersion: gateway.nginx.org/v1alpha1 +kind: NginxProxy +metadata: + name: ngf-proxy-config +spec: + telemetry: + exporter: + endpoint: otel-collector.tracing.svc:4317 + spanAttributes: + - key: cluster-attribute-key + value: cluster-attribute-value +``` + +```shell +kubectl get gatewayclasses.gateway.networking.k8s.io nginx -o yaml +``` + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: GatewayClass +metadata: + name: nginx +spec: + controllerName: gateway.nginx.org/nginx-gateway-controller + parametersRef: + group: gateway.nginx.org + kind: NginxProxy + name: ngf-proxy-config +status: + conditions: + - lastTransitionTime: "2024-05-22T15:18:35Z" + message: GatewayClass is accepted + observedGeneration: 1 + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: "2024-05-22T15:18:35Z" + message: Gateway API CRD versions are supported + observedGeneration: 1 + reason: SupportedVersion + status: "True" + type: SupportedVersion + - lastTransitionTime: "2024-05-22T15:18:35Z" + message: parametersRef resource is resolved + observedGeneration: 1 + reason: ResolvedRefs + status: "True" + type: ResolvedRefs +``` + +If you already have NGINX Gateway Fabric installed, then you can create the `NginxProxy` resource and link it to the GatewayClass `parametersRef`: + +```shell +kubectl edit gatewayclasses.gateway.networking.k8s.io nginx +``` + +Next, [Expose NGINX Gateway Fabric]({{< relref "installation/expose-nginx-gateway-fabric.md" >}}) and save the public IP address and port of NGINX Gateway Fabric into shell variables: + + ```text + GW_IP=XXX.YYY.ZZZ.III + GW_PORT= + ``` + +You can now create the application, route, and tracing policy. + +### Create the application and route + +Create the basic **coffee** application: + +```yaml +kubectl apply -f - <}}If you have a DNS record allocated for `cafe.example.com`, you can send the request directly to that hostname, without needing to resolve.{{< /note >}} + +```shell +curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee +``` + +You should receive a response from the coffee Pod. + +```text +Server address: 10.244.0.69:8080 +Server name: coffee-6b8b6d6486-k5w5w +URI: /coffee +``` + +You shouldn't see any information from the [Jaeger dashboard](http://127.0.0.1:16686) yet: you need to create the `ObservabilityPolicy`. + +### Create the ObservabilityPolicy + +To enable tracing for the coffee HTTPRoute, create the following policy: + +```yaml +kubectl apply -f - <:`. + +{{}} + +

+ +Select a trace to view the attributes. + +{{}} + +The trace includes the attribute from the global NginxProxy resource as well as the attribute from the ObservabilityPolicy. diff --git a/site/content/how-to/monitoring/troubleshooting.md b/site/content/how-to/monitoring/troubleshooting.md index 96ddae0461..8b8f4c631e 100644 --- a/site/content/how-to/monitoring/troubleshooting.md +++ b/site/content/how-to/monitoring/troubleshooting.md @@ -1,7 +1,6 @@ --- title: "Troubleshooting" - -weight: 300 +weight: 400 toc: true docs: "DOCS-1419" --- diff --git a/site/content/includes/installation/install-gateway-api-resources.md b/site/content/includes/installation/install-gateway-api-resources.md index a0ba68a58f..d97d7d4f91 100644 --- a/site/content/includes/installation/install-gateway-api-resources.md +++ b/site/content/includes/installation/install-gateway-api-resources.md @@ -10,7 +10,7 @@ To install the Gateway API resources, run the following: kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.2.0" | kubectl apply -f - ``` -{{}}If you plan to use the `edge` version of NGINX Gateway Fabric, you can replace the vesion in `ref` with `main`, for example `ref=main`.{{}} +{{}}If you plan to use the `edge` version of NGINX Gateway Fabric, you can replace the version in `ref` with `main`, for example `ref=main`.{{}} Alternatively, you can install the Gateway API resources from the experimental channel. We support a subset of the additional features provided by the experimental channel. To install from the experimental channel, run the following: diff --git a/site/static/img/jaeger-trace-attributes.png b/site/static/img/jaeger-trace-attributes.png new file mode 100644 index 0000000000..ea8d383b11 Binary files /dev/null and b/site/static/img/jaeger-trace-attributes.png differ diff --git a/site/static/img/jaeger-trace-overview.png b/site/static/img/jaeger-trace-overview.png new file mode 100644 index 0000000000..309c826917 Binary files /dev/null and b/site/static/img/jaeger-trace-overview.png differ diff --git a/site/static/jaeger.yaml b/site/static/jaeger.yaml new file mode 100644 index 0000000000..9f1a11c275 --- /dev/null +++ b/site/static/jaeger.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: jaeger + labels: + app.kubernetes.io/name: jaeger +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: jaeger + template: + metadata: + labels: + app.kubernetes.io/name: jaeger + spec: + containers: + - name: jaeger + image: jaegertracing/all-in-one:latest + ports: + - containerPort: 16686 + - containerPort: 4317 +--- +apiVersion: v1 +kind: Service +metadata: + name: jaeger + labels: + app.kubernetes.io/name: jaeger +spec: + selector: + app.kubernetes.io/name: jaeger + ports: + - name: frontend + port: 16686 + - name: collector + port: 4317 diff --git a/site/static/otel-collector.yaml b/site/static/otel-collector.yaml new file mode 100644 index 0000000000..ff2fe807fb --- /dev/null +++ b/site/static/otel-collector.yaml @@ -0,0 +1,72 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: otel-collector-config +data: + otel-collector-config: | + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + processors: + extensions: + exporters: + otlp/jaeger: + endpoint: "jaeger.tracing.svc:4317" + tls: + insecure: true + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [otlp/jaeger] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: otel-collector + labels: + app.kubernetes.io/name: otel-collector +spec: + selector: + matchLabels: + app.kubernetes.io/name: otel-collector + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: otel-collector + spec: + containers: + - name: otel-collector + image: otel/opentelemetry-collector:latest + command: + - /otelcol + - --config=/conf/otel-collector-config.yaml + ports: + - containerPort: 4317 + volumeMounts: + - name: otel-collector-config + mountPath: /conf + volumes: + - name: otel-collector-config + configMap: + name: otel-collector-config + items: + - key: otel-collector-config + path: otel-collector-config.yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: otel-collector + labels: + app.kubernetes.io/name: otel-collector +spec: + selector: + app.kubernetes.io/name: otel-collector + ports: + - name: otlp-grpc + port: 4317