NMC Gateway (air-gapped)#

NMC Gateway is the entry point for the Keycloak and NMC Launchpad web interfaces. It is a second Kubernetes Gateway API Gateway, separate from the BCM gateway you configured during Kubernetes installation. It terminates TLS and routes each host name to the component behind it, and each component attaches to it with its own HTTPRoute.

Install NMC Gateway before the components that attach to it.

Prerequisites#

  • Two controllers, both installed with BCM Kubernetes: kgateway, which programs the gateway, and MetalLB, which assigns it an address.

  • One free IP address on the BCM internal network, internalnet. On the default 10.141.0.0/16 layout, 10.141.255.252 through 10.141.255.254 serve the head nodes, the head-node high-availability address, and the BCM gateway, so choose a lower address in the range and confirm that it is unused. The address does not have to be reachable from outside the cluster, because clients can reach the interfaces through the BCM head node.

  • A DNS domain for the NMC web interfaces, for example nmc.example.com. Each interface takes a host name under that domain. Public DNS is not required, as long as the names resolve for the clients that use them. Reach the NMC interfaces covers what those names resolve to.

  • A TLS certificate and its private key covering every host name the gateway serves. Create the TLS secret loads them into the cluster.

Create the TLS secret#

The gateway terminates TLS for every host name it serves. A certificate that lists each host name as a subject alternative name works, but you must reissue it whenever you add a component that the gateway serves. A wildcard for the domain you chose, for example *.nmc.example.com, covers the components you install later without a reissue.

The certificate file holds the full PEM chain, the leaf first and then any intermediates. A client that receives only the leaf cannot build a path to the issuing authority and rejects the connection.

Create the namespace and the secret:

kubectl create namespace nmc-gateway

kubectl create secret tls nmc-gateway-tls \
  --cert=<path-to-fullchain.pem> --key=<path-to-key.pem> -n nmc-gateway

The secret must be in the same namespace as the gateway.

Note

This secret does not renew itself. Every NMC interface behind the gateway shares it, so all of them stop serving when the certificate expires. Track the expiry date and replace the secret before it expires.

Prepare the values file#

cat <<'EOF' > values-nmc-gateway.yaml
gatewayClassName: kgateway-ha2

loadBalancer:
  ip: "<gateway-ip>"

listeners:
  http:
    enabled: true
    port: 80
    hostname: "*.<your-domain>"
  https:
    enabled: true
    port: 443
    hostname: "*.<your-domain>"

allowedRoutes:
  namespaces:
    from: All

tls:
  mode: existing
  existing:
    secretName: nmc-gateway-tls

metallb:
  enabled: true
  namespace: metallb-system
  mode: L2
  ipAddressPool:
    addresses:
      - "<gateway-ip>/32"
    autoAssign: false
EOF

Set these values:

  • gatewayClassName: the GatewayClass that kgateway registers, kgateway-ha2. Confirm it with kubectl get gatewayclass.

  • loadBalancer.ip: the IP address you reserved for the gateway. Replace <gateway-ip> in both places it appears.

  • listeners.http.hostname and listeners.https.hostname: a wildcard for the domain you chose, for example *.nmc.example.com. Match it to the certificate. The head-node proxy reads these host names when it generates its forwarding rules.

  • allowedRoutes.namespaces.from: leave it as All so components can attach routes from their own namespaces.

  • tls.existing.secretName: the TLS secret you created.

  • metallb.ipAddressPool.addresses: the reserved address in CIDR notation. MetalLB assigns it to the gateway.

  • metallb.ipAddressPool.autoAssign: false reserves the pool for the gateway, so MetalLB cannot give the address to another service.

  • metallb.mode: L2 announces the address by ARP on the local segment. Use BGP when the nodes are not on the same segment as the upstream router.

Install NMC Gateway from the bundle#

helm install nmc-gateway ./bundle/helm/nmc-gateway-0.3.0.tgz \
  --namespace nmc-gateway -f values-nmc-gateway.yaml

The release name sets the gateway name. Components attach to the gateway by name, and the component pages in this guide use a gateway named nmc-gateway in the nmc-gateway namespace. Keep the release name to follow those pages as written.

Verify#

Wait for the gateway to be programmed:

kubectl wait --for=condition=Programmed gateway/nmc-gateway \
  -n nmc-gateway --timeout=5m

Confirm it holds the address you reserved:

kubectl get gateway nmc-gateway -n nmc-gateway

The ADDRESS column shows the reserved IP address.

Reach the NMC interfaces#

Every host name the gateway serves resolves to one of two addresses: the BCM head node, or the gateway address itself.

Through the BCM head node

This is the standard path, the same way you reach the other NMC services. Resolve each host name to the BCM head node’s external or floating IP address, the address you use to reach the head node over SSH. In a high-availability setup, use the floating IP address. The head node forwards HTTPS to the gateway by host name.

The head node needs a forwarding rule for each gateway host name. Generate the rules as root on the active head node:

cm-kubernetes-setup --cluster k8s-admin --configure-gateway-proxy

The command reads the gateway’s listener host names and writes the matching forwarding rules. It needs the Kubernetes ingress proxy, which you enable when you create the k8s-admin cluster. Run the command again whenever the host names or the gateway address change.

NMC Launchpad sends its sign-in redirect to the Keycloak host name, which resolves through this same path. Generate the rules before you test single sign-on.

Directly to the gateway

Resolve each host name to the gateway address in your site DNS, from a host that can route to that address. This path needs no head-node forwarding.

Trust the served certificate

Clients validate the certificate the gateway serves. A certificate from a publicly trusted certificate authority is already trusted. Import a private certificate authority into the trust store of every client that connects, using your own trust distribution.