End of Sale Notice:
Commercial support for NGINX Service Mesh is available to customers who currently have active NGINX Microservices Bundle subscriptions. F5 NGINX announced the End of Sale (EoS) for the NGINX Microservices Bundles as of July 1, 2023.
See our End of Sale announcement for more details.
Deploy with NGINX Ingress Controller
This topic describes how to install and use F5 NGINX Ingress Controller with NGINX Service Mesh
Overview
You can deploy NGINX Ingress Controller for Kubernetes with NGINX Service Mesh to control both ingress and egress traffic.
Important:
NGINX Ingress Controller can be used for free with NGINX Open Source. Paying customers have access to NGINX Ingress Controller with NGINX Plus. To deploy NGINX Ingress Controller with NGINX Service Mesh, you must use either:
- Open Source NGINX Ingress Controller version 3.0+
- NGINX Plus version of NGINX Ingress Controller
Visit the NGINX Ingress Controller product page for more information.
Supported Versions
The supported NGINX Plus Ingress Controller versions for each release are listed in the technical specifications doc.
The documentation for the latest stable release of NGINX Ingress Controller is available at docs.nginx.com/nginx-ingress-controller. For version specific documentation, deployment configs, and configuration examples, select the tag corresponding to your desired version in GitHub.
Secure Communication Between NGINX Ingress Controller and NGINX Service Mesh
The NGINX Ingress Controller can participate in the mTLS cert exchange with services in the mesh without being injected with the sidecar proxy. The SPIRE server - the certificate authority of the mesh - issues certs and keys for NGINX Ingress Controller and pushes them to the SPIRE agents running on each node in the cluster. NGINX Ingress Controller fetches these certs and keys from the SPIRE agent via a unix socket and uses them to communicate with services in the mesh.
Cert Rotation with NGINX Ingress Controller
The ttl
of the SVID certificates issued by SPIRE is set to 1hr
by default. You can change this when deploying the mesh; refer to the nginx-meshctl documentation for more information.
When using NGINX Ingress Controller with mTLS enabled, it is best practice to keep the ttl
at 1 hour or greater.
Install NGINX Ingress Controller with mTLS enabled
To configure NGINX Ingress Controller to communicate with mesh workloads over mTLS you need to make a modification to the Ingress Controller’s Pod spec. This section describes each modification that is required, but if you’d like to jump to installation, go to the Install with Manifests or Install with Helm sections.
-
Add NGINX Service Mesh label
One or both of the following labels must be added to the Ingress Controller’s Pod spec, depending on your use case:
labels: nsm.nginx.com/enable-ingress: "true" ...
labels: nsm.nginx.com/enable-egress: "true" ...
These labels tell NGINX Service Mesh to mutate the Ingress Controller Pod with the proper configuration in order to properly integrate with the mesh.
See Also:
For more information, see How NGINX Ingress Controller Integrates with NGINX Service Mesh.
Note:
All communication between NGINX Ingress Controller and the upstream Services occurs over mTLS, using the certificates and keys generated by the SPIRE server. Therefore, NGINX Ingress Controller can only route traffic to Services in the mesh that have an
mtls-mode
ofpermissive
orstrict
. In cases where you need to route traffic to both mTLS and non-mTLS Services, you may need another Ingress Controller that does not participate in the mTLS fabric.Refer to the NGINX Ingress Controller’s Running Multiple Ingress Controllers guide for instructions on how to configure multiple Ingress Controllers.
If you would like to enable egress traffic, refer to the Enable Egress section of this guide.
Install with Manifests
Before installing NGINX Ingress Controller, you must install NGINX Service Mesh with an mTLS mode of permissive
, or strict
.
NGINX Ingress Controller will try to fetch certs from the SPIRE agent on startup. If it cannot reach the SPIRE agent, startup will fail, and NGINX Ingress Controller will go into CrashLoopBackoff state. The state will resolve once NGINX Ingress Controller connects to the SPIRE agent.
For instructions on how to install NGINX Service Mesh, see the Installation guide.
Note:
Before continuing, check the NGINX Ingress Controller supported versions section and make sure you are working off the correct release tag for all NGINX Ingress Controller instructions.
NGINX OSS Ingress Controller
- Build or Pull the NGINX OSS Ingress Controller image:
- Create and push your NGINX Docker image.
- For NGINX OSS Ingress you can also pull the NGINX Docker image.
- Set up Kubernetes Resources for NGINX Ingress Controller using Kubernetes manifests:
- Create the NGINX Ingress Controller as a Deployment or DaemonSet in Kubernetes using one of the following example manifests:
-
Kubernetes Deployment:
nginx-ingress-controller/oss/nginx-ingress.yaml
-
Kubernetes DaemonSet:
nginx-ingress-controller/oss/nginx-ingress-daemonset.yaml
-
OpenShift Deployment:
nginx-ingress-controller/oss/openshift/nginx-ingress.yaml
-
Openshift DaemonSet:
nginx-ingress-controller/oss/openshift/nginx-ingress-daemonset.yaml
Note:
The provided manifests configure NGINX Ingress Controller for ingress traffic only. If you would like to enable egress traffic, refer to the Enable Egress section of this guide.Important:
Be sure to replace thenginx-ingress:version
image used in the manifest with the chosen image from a supported Container registry; or the container image that you have built. -
OpenShift only:
Download the SecurityContextConstraint necessary to run NGINX Ingress Controller in an OpenShift environment.
-
Apply the
nginx-ingress-permissions
SecurityContextConstraint:kubectl apply -f nic-scc.yaml
-
Install the OpenShift CLI by following the steps in their documentation.
-
Add the
nginx-ingress-permissions
to the ServiceAccount of the NGINX Ingress Controller.oc adm policy add-scc-to-user nginx-ingress-permissions -z nginx-ingress -n nginx-ingress
-
NGINX Plus Ingress Controller
- Build or Pull the NGINX Plus Ingress Controller image:
- Create and push your NGINX Plus Docker image.
- For NGINX Plus Ingress releases >=
1.12.0
you can also pull the NGINX Plus Docker image.
- Set up Kubernetes Resources for NGINX Plus Ingress Controller using Kubernetes manifests:
- Create the NGINX Plus Ingress Controller as a Deployment or DaemonSet in Kubernetes using one of the following example manifests:
-
Kubernetes Deployment:
nginx-ingress-controller/plus/nginx-plus-ingress.yaml
-
Kubernetes DaemonSet:
nginx-ingress-controller/plus/nginx-plus-ingress-daemonset.yaml
-
OpenShift Deployment:
nginx-ingress-controller/openshift/nginx-plus-ingress.yaml
-
Openshift DaemonSet:
nginx-ingress-controller/openshift/nginx-plus-ingress-daemonset.yaml
Note:
The provided manifests configure NGINX Plus Ingress Controller for ingress traffic only. If you would like to enable egress traffic, refer to the Enable Egress section of this guide.Important:
Be sure to replace thenginx-plus-ingress:version
image used in the manifest with the chosen image from the F5 Container registry; or the container image that you have built. -
OpenShift only:
Download the SecurityContextConstraint necessary to run NGINX Ingress Controller in an OpenShift environment.
-
Apply the
nginx-ingress-permissions
SecurityContextConstraint:kubectl apply -f nic-scc.yaml
-
Install the OpenShift CLI by following the steps in their documentation.
-
Add the
nginx-ingress-permissions
to the ServiceAccount of the NGINX Plus Ingress Controller.oc adm policy add-scc-to-user nginx-ingress-permissions -z nginx-ingress -n nginx-ingress
-
Install with Helm
Before installing NGINX Ingress Controller, you must install NGINX Service Mesh with an mTLS mode of permissive
, or strict
.
NGINX Ingress Controller will try to fetch certs from the SPIRE agent on startup. If it cannot reach the SPIRE agent, startup will fail, and NGINX Ingress Controller will go into CrashLoopBackoff state. The state will resolve once NGINX Ingress Controller connects to the SPIRE agent.
For instructions on how to install NGINX Service Mesh, see the Installation guide.
Note:
NGINX Plus Ingress Controller v2.2+ or NGINX OSS Ingress Controller v3.0+ is required to deploy via Helm and integrate with NGINX Service Mesh.
Follow the instructions to install the NGINX Ingress Controller with Helm.
Set the nginxServiceMesh.enable
parameter to true
.
Note:
This will configure NGINX Ingress Controller to route ingress traffic to NGINX Service Mesh workloads. If you would like to enable egress traffic, refer to the Enable Egress section of this guide.
The values-nsm.yaml
file contains all the configuration parameters that are relevant for integration with NGINX Service Mesh. You can use this file if you are installing NGINX Ingress Controller via chart sources.
Expose your applications
With mTLS enabled, you can use Kubernetes Ingress, VirtualServer, and VirtualServerRoutes resources to configure load balancing for HTTP and gRPC applications. TCP load balancing via TransportServer resources is not supported.
Note:
The NGINX Ingress Controller’s custom resource TransportServer and the SMI Spec’s custom resource TrafficSplit share the same Kubernetes short namets
. To avoid conflicts, use the full namestransportserver(s)
andtrafficsplit(s)
when managing these resources withkubectl
.
To learn how to expose your applications using NGINX Ingress Controller, refer to the Expose an Application with NGINX Ingress Controller tutorial.
Enable Egress
You can configure NGINX Ingress Controller to act as the egress endpoint of the mesh, enabling your meshed services to communicate securely with external, non-meshed services.
Note:
Multiple endpoints for a single egress deployment are supported, but multiple egress deployments are not supported.
Enable with Manifests
If you are installing NGINX Ingress Controller with manifests follow the Install with Manifests instructions and make the following change to the NGINX Ingress Controller Pod spec:
-
Add the following label to the NGINX Ingress Controller Pod spec:
labels: nsm.nginx.com/enable-egress: "true" ...
This label prevents automatic injection of the sidecar proxy and configures the NGINX Ingress Controller as the egress endpoint of the mesh.
This will create a virtual server block in NGINX Ingress Controller that terminates TLS connections using the SPIFFE certs fetched from the SPIRE agent.
Enable with Helm
Note:
NGINX Plus Ingress Controller v2.2+ or NGINX OSS Ingress Controller v3.0+ is required to deploy via Helm and integrate with NGINX Service Mesh.
If you are installing NGINX Ingress Controller with Helm, follow the Install with Helm instructions and set nginxServiceMesh.enableEgress
to true
.
Allow Pods to route egress traffic through NGINX Ingress Controller
If egress is enabled you can configure Pods to route all egress traffic - requests to non-meshed services - through NGINX Ingress Controller. This feature can be enabled by adding the following annotation to the Pod spec of an application Pod:
config.nsm.nginx.com/default-egress-allowed: "true"
This annotation can be removed or changed after deployment and the egress behavior of the Pod will be updated accordingly.
Create internal routes for non-meshed services
Internal routes represent a route from NGINX Ingress Controller to a non-meshed service. This route is called “internal” because it is only accessible from a Pod in the mesh and is not accessible from the public internet.
Caution:
If you deploy NGINX Ingress Controller without mTLS enabled, the internal routes could be accessible from the public internet. We do not recommend using the egress feature with a plaintext deployment of NGINX Ingress Controller.
To generate an internal route, create an Ingress resource or VirtualServer resource using the information for your non-meshed service.
Add the following configuration, depending on the type of resource you created:
- For an Ingress resource, add the following annotation to the resource definition:
nsm.nginx.com/internal-route: "true"
- For a VirtualServer resource, add the following field to the custom resource definition:
spec:
internalRoute: true
If your non-meshed service is external to Kubernetes, follow the ExternalName services example.
Note:
Thensm.nginx.com/internal-route: "true"
Ingress annotation orinternalRoute: true
VirtualServer field is still required for routing to external endpoints.
The NGINX Ingress Controller egress tutorial provides instructions for creating internal routes for non-meshed services.
Enable Ingress and Egress Traffic
There are a couple ways to enable both ingress and egress traffic using the NGINX Ingress Controller. You can either allow both ingress and egress traffic through the same NGINX Ingress Controller, or deploy two NGINX Ingress Controllers: one for handling ingress traffic only and the other for handling egress traffic.
For the single deployment option, follow the installation instructions and the instructions to Enable Egress. If you would like to configure two Ingress Controllers to keep ingress and egress traffic separate you can leverage Ingress Classes.
Enable UDP Traffic
By default, NGINX Ingress Controller only routes TCP traffic. You can configure it to route UDP traffic by making the following changes to the NGINX Ingress Controller before deploying:
-
Enable GlobalConfiguration resources for NGINX Ingress Controller by following the setup defined in the GlobalConfiguration Resource documentation.
This allows you to define global configuration parameters for the NGINX Ingress Controller, and create a UDP listener to route ingress UDP traffic to your backend applications.
Important:
mTLS does not affect UDP communication, as mTLS in NGINX Service Mesh applies only to TCP traffic at this time.
Create a GlobalConfiguration Resource
To allow UDP traffic to be routed to your Kubernetes applications, create a UDP listener in NGINX Ingress Controller. This can be done via a GlobalConfiguration Resource.
To create a GlobalConfiguration resource, see the NGINX Ingress Controller documentation to create a listener with protocol UDP.
Ingress UDP Traffic
You can pass and load balance UDP traffic by using a TransportServer resource. This will link the UDP listener defined in the Create a GlobalConfiguration Resource step with an upstream associated with your designated backend UDP application.
To create a TransportServer resource, follow the steps outlined in the TransportServer NGINX Ingress Controller guide and link the UDP listener with the name and port of your backend service.
To learn how to expose a UDP application using NGINX Ingress Controller, see the Expose a UDP Application with NGINX Ingress Controller tutorial.
Plaintext configuration
Deploy NGINX Service Mesh with mtls-mode
set to off
and follow the instructions to deploy NGINX Ingress Controller.
Add the enable-ingress and/or the enable-egress label shown below to the NGINX Ingress Controller Pod spec:
nsm.nginx.com/enable-ingress: "true"
nsm.nginx.com/enable-egress: "true"
Caution:
All communication between NGINX Ingress Controller and the services in the mesh will be over plaintext! We do not recommend using the egress feature with a plaintext deployment of NGINX Ingress Controller, it is possible that internal routes could be accessible from the public internet. We highly recommend installing NGINX Ingress Controller with mTLS enabled.
NGINX Ingress Controller Metrics
To enable metrics collection for the NGINX Ingress Controller, take the following steps:
- Run the NGINX Ingress Controller with the
-enable-prometheus-metrics
command line argument. The NGINX Ingress Controller exposes NGINX metrics in Prometheus format via the/metrics
path on port 9113. This port is customizable via the-prometheus-metrics-listen-port
command-line argument; consult the Command Line Arguments section of the NGINX Ingress Controller docs for more information on available command line arguments.
Note:
If using the NGINX Plus Ingress Controller, add this additional flag to enable latency metrics:-enable-latency-metrics
-
Add the following Prometheus annotations NGINX Ingress Controller Pod spec:
prometheus.io/scrape: "true" prometheus.io/port: "<prometheus-metrics-listen-port>"
-
Add the resource name as a label to the NGINX Ingress Controller Pod spec:
-
For Deployment:
nsm.nginx.com/deployment: <name of NGINX Ingress Controller Deployment>
-
For DaemonSet:
nsm.nginx.com/daemonset: <name of NGINX Ingress Controller DaemonSet>
This allows metrics scraped from NGINX Ingress Controller Pods to be associated with the resource that created the Pods.
-
View the metrics in Prometheus
The NGINX Service Mesh uses the Pod’s container name setting to identify the NGINX Ingress Controller metrics that should be consumed by the Prometheus server.
Add the applicable nginx-ingress
scrape config to your Prometheus configuration and consult
Monitoring and Tracing for installation instructions.
Available metrics
For a list of the NGINX Ingress Controller metrics, consult the Available Metrics section of the NGINX Ingress Controller docs.
Note:
The NGINX Plus metrics exported by the NGINX Plus Ingress Controller are renamed fromnginx_ingress_controller_<metric-name>
tonginxplus_<metric-name>
to be consistent with the metrics exported by NGINX Service Mesh sidecars. For example,nginx_ingress_controller_upstream_server_response_latency_ms_count
is renamed tonginxplus_upstream_server_response_latency_ms_count
. The Ingress Controller specific metrics, such asnginx_ingress_controller_nginx_reloads_total
, are not renamed.
For more information on metrics, a list of Prometheus labels, and examples of querying and filtering, see the Prometheus Metrics doc.
To view the metrics, use port-forwarding:
kubectl port-forward -n nginx-mesh svc/prometheus 9090
Monitor your application in Grafana
NGINX Service Mesh provides a custom dashboard that you can import into your Grafana deployment to monitor your application. To import and view the dashboard, port-forward your Grafana service:
kubectl port-forward -n <grafana-namespace> svc/grafana 3000
Then you can navigate your browser to localhost:3000
to view Grafana.
Here is a view of the provided “NGINX Mesh Top” dashboard:
How NGINX Ingress Controller Integrates with NGINX Service Mesh
Mutating Webhook
NGINX Service Mesh version v1.7+ provides a mutating webhook that detects and configures instances of NGINX Ingress Controller.
Pod Spec Changes
-
NGINX Service Mesh mounts and configures the SPIRE agent socket based on environment
The SPIRE agent socket needs to be mounted to the Ingress Controller Pod so the Ingress Controller can fetch its certificates and keys from the SPIRE agent. This allows the Ingress Controller to authenticate with workloads in the mesh. For more information on how SPIRE distributes certificates see the SPIRE section in the architecture doc.
-
Kubernetes
The following `hostPath` is added as a volume to the Ingress Controller's Pod spec: ```yaml volumes: - hostPath: path: /run/spire/sockets type: DirectoryOrCreate name: spire-agent-socket ``` NGINX Service Mesh also mounts the socket to the Ingress Controller's container spec: ```yaml volumeMounts: - mountPath: /run/spire/sockets name: spire-agent-socket ```
-
OpenShift
To mount the SPIRE agent socket in OpenShift, NGINX Service Mesh adds the following
csi
driver to the Ingress Controller’s Pod spec:volumes: - csi: driver: csi.spiffe.io readOnly: true name: spire-agent-socket
and mount the socket to the Ingress Controller’s container spec:
volumeMounts: - mountPath: /run/spire/sockets name: spire-agent-socket
For more information as to why a CSI Driver is needed for loading the agent socket in OpenShift, see Introduction in the OpenShift Considerations doc.
-
NGINX Service Mesh adds a command line argument
The following argument is added to the Ingress Controller’s container args:
args: - -spire-agent-address=/run/spire/sockets/agent.sock ... -
- The
spire-agent-address
passes the address of the SPIRE agent/run/spire/sockets/agent.sock
to the Ingress Controller.
If egress is enabled NGINX Service Mesh also adds the following argument to the Ingress Controller’s container args:
args: - -enable-internal-routes ... -
- The
-
NGINX Service Mesh adds a SPIFFE label
labels: spiffe.io/spiffeid: "true" ...
These labels tell NGINX Service Mesh to mutate the Ingress Controller Pod with the proper configuration in order to properly integrate with the mesh.