# Get started Type of document: How-to guide Product: NGINX Gateway Fabric --- **Note:** This document is for trying out NGINX Gateway Fabric, and not intended for a production environment. For standard deployments, you should read the [Install NGINX Gateway Fabric](/ngf/install/) section. This is a guide for getting started with NGINX Gateway Fabric. It explains how to: - Set up a [kind (Kubernetes in Docker)](https://kind.sigs.k8s.io/) cluster - Install [NGINX Gateway Fabric](https://github.com/nginx/nginx-gateway-fabric) with [NGINX](https://nginx.org/) - Test NGINX Gateway Fabric with an example application By following the steps in order, you will finish with a functional NGINX Gateway Fabric cluster. ## Before you begin To complete this guide, you need the following prerequisites installed: - [Go 1.16](https://go.dev/dl/) or newer, which is used by kind - [Docker](https://docs.docker.com/get-started/get-docker/), for creating and managing containers - [kind](https://kind.sigs.k8s.io/#installation-and-usage), which allows for running a local Kubernetes cluster using Docker - [kubectl](https://kubernetes.io/docs/tasks/tools/), which provides a command line interface (CLI) for interacting with Kubernetes clusters - [Helm 3.0](https://helm.sh/docs/intro/install/) or newer to install NGINX Gateway Fabric - [curl](https://curl.se/), to test the example application ## Set up a kind cluster Create the file _cluster-config.yaml_ with the following contents, noting the highlighted lines: ```yaml {linenos=true, hl_lines=[6, 9]} apiVersion: kind.x-k8s.io/v1alpha4 kind: Cluster nodes: - role: control-plane extraPortMappings: - containerPort: 31437 hostPort: 8080 protocol: TCP - containerPort: 30478 hostPort: 8443 protocol: TCP ``` **Note:** The _containerPort_ value is used to later configure a _NodePort_. Run the following command: ```shell kind create cluster --config cluster-config.yaml ``` #### Example output ```text Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.31.0) đŸ–ŧ ✓ Preparing nodes đŸ“Ļ ✓ Writing configuration 📜 ✓ Starting control-plane đŸ•šī¸ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-kind" You can now use your cluster with: kubectl cluster-info --context kind-kind Thanks for using kind! 😊 ``` **Note:** If you have cloned [the NGINX Gateway Fabric repository](https://github.com/nginx/nginx-gateway-fabric/tree/main), you can also create a kind cluster from the root folder with the following _make_ command: ```shell make create-kind-cluster ``` ## Install NGINX Gateway Fabric ### Add Gateway API resources Use `kubectl` to add the API resources for NGINX Gateway Fabric with the following command: ```shell kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v" | kubectl apply -f - ``` #### Example output ```text 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 ``` ### Install the Helm chart Use `helm` to install NGINX Gateway Fabric, specifying the NodePort configuration that will be set on the NGINX Service when it is provisioned: ```shell helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric --create-namespace -n nginx-gateway --set nginx.service.type=NodePort --set-json 'nginx.service.nodePorts=[{"port":31437,"listenerPort":80}, {"port":30478,"listenerPort":8443}]' ``` **Note:** The port value should equal the _containerPort_ value from _cluster-config.yaml_ [when you created the kind cluster](#set-up-a-kind-cluster). The _listenerPort_ value will match the port that we expose in the Gateway listener. #### Example output ```text NAME: ngf LAST DEPLOYED: Tue Apr 29 14:45:14 2025 NAMESPACE: nginx-gateway STATUS: deployed REVISION: 1 TEST SUITE: None ``` ## Create an example application In the previous section, you deployed NGINX Gateway Fabric to a local cluster. This section shows you how to deploy a simple web application to test that NGINX Gateway Fabric works. **Note:** The YAML code in the following sections can be found in the [cafe-example folder](https://github.com/nginx/nginx-gateway-fabric/tree/main/examples/cafe-example) of the GitHub repository. ### Create the application resources Run the following command to create the file _cafe.yaml_, which is then used to deploy the *coffee* application to your cluster: ```yaml cat < cafe.yaml 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 EOF kubectl apply -f cafe.yaml ``` #### Example output ```text deployment.apps/coffee created service/coffee created deployment.apps/tea created service/tea created ``` Verify that the new pods are in the `default` namespace: ```shell kubectl get pods ``` #### Example output ```text NAME READY STATUS RESTARTS AGE coffee-676c9f8944-k2bmd 1/1 Running 0 9s tea-6fbfdcb95d-9lhbj 1/1 Running 0 9s ``` ### Create Gateway and HTTPRoute resources Run the following command to create the file _gateway.yaml_, which is then used to deploy a Gateway to your cluster: ```yaml cat < gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: gateway spec: gatewayClassName: nginx listeners: - name: http port: 80 protocol: HTTP hostname: "*.example.com" EOF kubectl apply -f gateway.yaml ``` Verify that the NGINX deployment has been provisioned: ```shell kubectl get pods ``` #### Example output ```text NAME READY STATUS RESTARTS AGE coffee-676c9f8944-k2bmd 1/1 Running 0 31s gateway-nginx-66b5d78f8f-4fmtb 1/1 Running 0 13s tea-6fbfdcb95d-9lhbj 1/1 Running 0 31s ``` Run the following command to create the file _cafe-routes.yaml_. It is then used to deploy two *HTTPRoute* resources in your cluster: one each for _/coffee_ and _/tea_. ```yaml cat < cafe-routes.yaml 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 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: Exact value: /tea backendRefs: - name: tea port: 80 EOF kubectl apply -f cafe-routes.yaml ``` ### Verify the configuration You can check that all of the expected services are available using `kubectl get`: ```shell kubectl get services ``` #### Example output ```text NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coffee ClusterIP 10.96.206.93 80/TCP 2m2s gateway-nginx NodePort 10.96.157.168 80:31437/TCP 104s kubernetes ClusterIP 10.96.0.1 443/TCP 142m tea ClusterIP 10.96.43.183 80/TCP 2m2s ``` You can also use `kubectl describe` on the new resources to check their status: ```shell kubectl describe httproutes ``` #### Example output ```text Name: coffee Namespace: default Labels: Annotations: API Version: gateway.networking.k8s.io/v1 Kind: HTTPRoute Metadata: Creation Timestamp: 2025-04-29T19:06:31Z Generation: 1 Resource Version: 12285 UID: c8055a74-b4c6-442f-b3fb-350fb88b2a7c Spec: Hostnames: cafe.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: gateway Section Name: http Rules: Backend Refs: Group: Kind: Service Name: coffee Port: 80 Weight: 1 Matches: Path: Type: PathPrefix Value: /coffee Status: Parents: Conditions: Last Transition Time: 2025-04-29T19:06:31Z Message: The route is accepted Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-04-29T19:06:31Z Message: All references are resolved Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Controller Name: gateway.nginx.org/nginx-gateway-controller Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: gateway Namespace: default Section Name: http Events: Name: tea Namespace: default Labels: Annotations: API Version: gateway.networking.k8s.io/v1 Kind: HTTPRoute Metadata: Creation Timestamp: 2025-04-29T19:06:31Z Generation: 1 Resource Version: 12284 UID: 55aa0ab5-9b1c-4028-9bb5-4903f05bb998 Spec: Hostnames: cafe.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: gateway Section Name: http Rules: Backend Refs: Group: Kind: Service Name: tea Port: 80 Weight: 1 Matches: Path: Type: Exact Value: /tea Status: Parents: Conditions: Last Transition Time: 2025-04-29T19:06:31Z Message: The route is accepted Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-04-29T19:06:31Z Message: All references are resolved Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Controller Name: gateway.nginx.org/nginx-gateway-controller Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: gateway Namespace: default Section Name: http Events: ``` ```shell kubectl describe gateways ``` #### Example output ```text Name: gateway Namespace: default Labels: Annotations: API Version: gateway.networking.k8s.io/v1 Kind: Gateway Metadata: Creation Timestamp: 2025-04-29T19:05:01Z Generation: 1 Resource Version: 12286 UID: 0baa6e15-55e0-405a-9e7c-de22472fc3ad Spec: Gateway Class Name: nginx Listeners: Allowed Routes: Namespaces: From: Same Hostname: *.example.com Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 10.96.157.168 Conditions: Last Transition Time: 2025-04-29T19:06:31Z Message: Gateway is accepted Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-04-29T19:06:31Z Message: Gateway is programmed Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Listeners: Attached Routes: 2 Conditions: Last Transition Time: 2025-04-29T19:06:31Z Message: Listener is accepted Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-04-29T19:06:31Z Message: Listener is programmed Observed Generation: 1 Reason: Programmed Status: True Type: Programmed Last Transition Time: 2025-04-29T19:06:31Z Message: All references are resolved Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Last Transition Time: 2025-04-29T19:06:31Z Message: No conflicts Observed Generation: 1 Reason: NoConflicts Status: False Type: Conflicted Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Group: gateway.networking.k8s.io Kind: GRPCRoute Events: ``` ## Test NGINX Gateway Fabric By configuring the cluster with the port `31437`, there is implicit port forwarding from your local machine to NodePort, allowing for direct communication to the NGINX Gateway Fabric service. You can use `curl` to test the new services by targeting the hostname (_cafe.example.com_) with the _/coffee_ and _/tea_ paths: ```shell curl --resolve cafe.example.com:8080:127.0.0.1 http://cafe.example.com:8080/coffee ``` #### Example output ```text Server address: 10.244.0.16:8080 Server name: coffee-676c9f8944-k2bmd Date: 29/Apr/2025:19:08:21 +0000 URI: /coffee Request ID: f34e138922171977a79b1b0d0395b97e ``` ```shell curl --resolve cafe.example.com:8080:127.0.0.1 http://cafe.example.com:8080/tea ``` #### Example output ```text Server address: 10.244.0.17:8080 Server name: tea-6fbfdcb95d-9lhbj Date: 29/Apr/2025:19:08:31 +0000 URI: /tea Request ID: 1b5c8f3a4532ea7d7510cf14ffeb27af ``` ## Next steps - [Install NGINX Gateway Fabric](/ngf/install/), for additional ways to install NGINX Gateway Fabric - [Traffic management](/ngf/traffic-management/), for more in-depth traffic management configuration - [How-to guides](/ngf/how-to/), for configuring your cluster