NMC Gateway#

Overview#

NMC Gateway is the shared ingress edge for the NVIDIA Mission Control components. It renders a single Kubernetes Gateway API Gateway that terminates external HTTPS on one load-balancer IP. It is delivered as an Argo CD Application. Refer to Installing GitOps-Managed Components for the shared deploy flow.

How it works#

NMC Gateway runs NVIDIA Mission Control’s nmc-gateway chart on the kgateway controller. The Application renders the shared Gateway resource, its TLS Certificate, and the MetalLB address pool (an IPAddressPool and an L2Advertisement).

%%{init: {'theme': 'base', 'themeVariables': {'lineColor': '#888888', 'edgeLabelBackground': '#e8e8e8'}}}%% flowchart TB CM["cert-manager"] subgraph gw["nmc-gateway namespace"] Gateway["Gateway<br/>one listener, one IP"] Cert["TLS Certificate<br/>covers all host names"] Pool["MetalLB pool<br/>reserved IP"] end subgraph routes["Component HTTPRoutes (parentRefs)"] R1["Argo CD"] R2["Keycloak"] R3["Launchpad"] end CM -.->|"issues"| Cert Cert --> Gateway Pool --> Gateway R1 --> Gateway R2 --> Gateway R3 --> Gateway style gw fill:#eef5ff,stroke:#1565c0,stroke-width:2px style routes fill:#f1f8e9,stroke:#2e7d32,stroke-width:1px style CM fill:#e3f2fd,stroke:#1565c0,color:#000 style Gateway fill:#ef7b4d,stroke:#c5410a,color:#fff style Cert fill:#e8f5e9,stroke:#2e7d32,color:#000 style Pool fill:#fff3e0,stroke:#e65100,color:#000 style R1 fill:#ede7f6,stroke:#5e35b1,color:#000 style R2 fill:#ede7f6,stroke:#5e35b1,color:#000 style R3 fill:#ede7f6,stroke:#5e35b1,color:#000 linkStyle default stroke-width:1.5px

TLS terminates at the gateway. By default, cert-manager issues the certificate from the OpenBao-backed ClusterIssuer (refer to Certificates). The certificate covers the host names of every component the gateway fronts, so one listener serves them all over one IP.

The gateway owns the attachment point, not the routes. Each component that needs external traffic ships its own HTTPRoute in its own Helm chart and attaches through parentRefs. Routing changes then stay in each component’s own repository and review process.

The MetalLB pool is reserved for the shared gateway. It is created with autoAssign: false and a serviceAllocation scoped to the nmc-gateway namespace, so no other Service can claim the load-balancer IP.

Configuration#

Add these settings under the nmcGateway key in values.yaml. The key already carries the pinned version and syncWave from Installing GitOps-Managed Components. The following fields are the ones you set. A field shown with a value uses that value as its default when you omit it.

nmcGateway:
  hostname: <wildcard-sni-host>               # required, e.g. *.dgx-<cluster-name>.nvidia.com
  loadBalancerIP: 10.141.255.248              # replace with an address you reserved
  gatewayClassName: kgateway-ha2              # optional, GatewayClass the gateway binds to
  tlsMode: cert-manager                       # optional, TLS source: cert-manager or existing
  tlsCertManagerIssuerName: nmc-openbao-ca    # optional, cert-manager issuer name
  tlsCertManagerIssuerKind: ClusterIssuer     # optional, issuer kind
  tlsCertManagerIssuerGroup: cert-manager.io  # optional, issuer API group
  # tlsCertManagerDnsNames: [nmc.example.com] # optional, cert SANs; defaults to [hostname]
  httpEnabled: true                           # optional, port 80 listener
  httpsEnabled: true                          # optional, port 443 listener
  allowedRoutesNamespacesFrom: All            # optional, namespaces that may attach HTTPRoutes
  metallbEnabled: true                        # optional, render the MetalLB address pool
  # metallbAddresses: [10.141.255.240/28]     # optional, pool CIDRs; defaults to <loadBalancerIP>/32
  • hostname – wildcard SNI listener host name for the HTTP and HTTPS listeners. No default. Set it.

  • loadBalancerIP – the load-balancer address the gateway is published on. Default 10.141.255.248. Treat the default as a placeholder and set an address that you have reserved. On BCM’s default 10.141.0.0/16 internal network, the head nodes, the head-node high-availability address, and the BCM gateway already occupy the top of the range. Before you choose an address, check your site address records, the node interfaces, and the MetalLB pools of every cluster on the network. Clients reach the served host names through the BCM head-node proxy or directly at this address (refer to Reach the UIs).

  • gatewayClassName – the GatewayClass the gateway binds to. The current release uses kgateway-ha2.

  • tlsMode – the TLS certificate source, cert-manager or existing. Default cert-manager. In existing mode the gateway serves a certificate you bring. Refer to Bring your own certificate.

  • tlsCertManagerIssuerName – the cert-manager issuer the certificate requests from. Default nmc-openbao-ca. Set it to your own issuer to use a customer-managed issuer (refer to Use a customer-managed issuer).

  • tlsCertManagerIssuerKind – the kind of the referenced issuer. Default ClusterIssuer.

  • tlsCertManagerIssuerGroup – the API group of the referenced issuer. Default cert-manager.io. An external issuer uses its own group.

  • tlsCertManagerDnsNames – the DNS names placed on the gateway certificate. Defaults to [hostname].

  • httpEnabled / httpsEnabled – enable the port 80 and port 443 listeners. Default true.

  • allowedRoutesNamespacesFrom – namespaces that may attach HTTPRoute resources. Default All.

  • metallbEnabled – render the MetalLB address pool. Default true.

  • metallbAddresses – addresses in the reserved pool. Defaults to <loadBalancerIP>/32.

Note

tlsCertManagerDnsNames must include the host names of every component the gateway serves. A component whose host name is absent will not have a valid certificate served for it.

Cross-field consistency rules:

  • gatewayClassName must match the class provided by the deployed kgateway controller.

Bring your own certificate#

To serve a certificate from your own certificate authority (CA) instead of one issued by NVIDIA Mission Control, set tlsMode: existing. Place the certificate in OpenBao. External Secrets projects it into the nmc-gateway-tls Secret the gateway serves.

The certificate must meet these requirements:

  • Format. A PEM certificate chain, the leaf plus any intermediates, and its matching private key in unencrypted PEM. NVIDIA Mission Control serves them as a kubernetes.io/tls Secret.

  • Host coverage. The Subject Alternative Names cover every host name the gateway serves. Those host names are the gateway hostname and each fronted component’s host name. For your own domain, the certificate’s SANs must match each of those host names. One wildcard such as *.dgx-<cluster-name>.nvidia.com covers them all.

  • Validity. The certificate is within its validity period.

  • Trust. A certificate from a publicly trusted CA needs nothing more. A certificate from a private CA must be trusted wherever it is validated. Add it to the nmc-ca-bundle for in-cluster clients (refer to Add a private CA to the trust bundle), and distribute it to external clients through your own trust distribution, as you would any private CA.

Provide the certificate in the flow that matches your cluster. Always populate OpenBao before you publish tlsMode: existing. The configure Job fails if the mode is live before the key exists.

At install (Day 1)#

  1. Set tlsMode: existing. When the certificate chains to a private CA, also set trustManager.extraCaEnabled: true (refer to Add a private CA to the trust bundle).

  2. Add k8s_bootstrap_secrets_gateway_tls_crt and k8s_bootstrap_secrets_gateway_tls_key to secrets.yaml (refer to the Secrets section).

  3. Seed and publish (refer to Seed and Publish the Components). The seed step loads the material into OpenBao before the gateway starts, so the certificate is in place the first time the gateway serves traffic.

On a running cluster (Day 2)#

Write the certificate to OpenBao first, then switch the mode. Run the bao commands as the nmc-admin operator (refer to Log in as the nmc-admin operator).

  1. When the certificate chains to a private CA, add that CA to the trust bundle first (refer to Add a private CA to the trust bundle).

  2. Write the certificate to OpenBao:

    bao kv put nmc/gateway/tls tls.crt=@/tmp/fullchain.pem tls.key=@/tmp/key.pem
    
  3. Set tlsMode: existing in values.yaml.

  4. Publish (refer to Seed and Publish the Components), then confirm the gateway serves your certificate (refer to Verify).

When only the leaf changes, write the new material to nmc/gateway/tls. The gateway serves it within one External Secrets refresh, with no restart.

When the CA also changes, add the new CA to the trust bundle before you serve the new leaf, and keep the old CA until the new leaf is live, so no client loses trust:

  1. Publish both CAs. Write the old and new CA together to nmc/cert-manager/extra-ca as one concatenated PEM file, then confirm the nmc-ca-bundle Bundle carries both.

  2. Replace the leaf. Write the new certificate and key to nmc/gateway/tls.

  3. Remove the old CA. Write only the new CA to nmc/cert-manager/extra-ca.

A shorter path replaces the CA and then the leaf in two writes. Between those two writes the served leaf chains to the old CA while the bundle carries only the new one, so clients briefly reject it.

Use a customer-managed issuer#

Point the gateway at a cert-manager issuer you run, in place of the OpenBao one. Take this step after the cluster is up. Bring the cluster up on the default OpenBao issuer or on a certificate you provide, then switch.

You own the issuer, its controller, its custom resource definitions, its backend credentials, and its signing keys. When the issuer signs from a private CA, add that CA to the trust bundle (refer to Add a private CA to the trust bundle).

  1. Install and operate your issuer. A built-in cert-manager issuer needs no extra controller. An external issuer needs its provider controller and custom resource definitions.

  2. Place a namespaced Issuer in the nmc-gateway namespace, alongside the gateway certificate. A ClusterIssuer works from any namespace.

  3. Confirm the issuer reports Ready and issues a test certificate.

  4. Set tlsMode: cert-manager with tlsCertManagerIssuerName, tlsCertManagerIssuerKind, and tlsCertManagerIssuerGroup for your issuer.

  5. Confirm the gateway serves a certificate your issuer minted.

Secrets#

NMC Gateway consumes no bootstrap secrets by default. On the bring-your-own-certificate path (tlsMode: existing), seed the certificate and key for the gateway to serve. Add them to secrets.yaml:

# Only when serving your own certificate (tlsMode: existing):
k8s_bootstrap_secrets_gateway_tls_crt: "{{ lookup('file', '/path/to/fullchain.pem') }}"   # PEM chain, leaf plus intermediates
k8s_bootstrap_secrets_gateway_tls_key: "{{ lookup('file', '/path/to/key.pem') }}"         # matching unencrypted PEM key
  • k8s_bootstrap_secrets_gateway_tls_crt – the PEM certificate chain, the leaf plus any intermediates. Give an absolute path to the file lookup, or paste the PEM inline as a block scalar.

  • k8s_bootstrap_secrets_gateway_tls_key – the matching private key, in unencrypted PEM.

For the install and running-cluster flows and rotation, refer to Bring your own certificate.

Verify#

Confirm NMC Gateway:

  • Confirm the Application is Synced and Healthy in Argo CD.

  • Confirm the Gateway is programmed and has been assigned the loadBalancerIP from the reserved MetalLB pool.

When HTTPS is enabled, confirm the served certificate for the tlsMode you set:

  • cert-manager: confirm the gateway Certificate is Ready and that its DNS names cover every component the gateway serves.

  • existing: confirm the gateway-tls ExternalSecret reports SecretSynced, the nmc-gateway-tls Secret exists in the nmc-gateway namespace, and its certificate covers every served host name.

From a client that trusts the served certificate, confirm an HTTPS request to a served host name terminates TLS at the gateway and routes to the expected component:

curl -v https://<served-host>/