Skip to main content

Ingress

Ingress (nginx-ingress) routes outside traffic to your apps. It runs the NGINX ingress controller behind one load balancer: an app is reached through it by an Ingress with ingressClassName: nginx, and custom domains route through it. It runs on any cluster and needs no cloud credential; your cloud creates the load balancer in front of it.

When to use it​

  • You want an image app on a hostname, over HTTPS. Without Ingress, the dry run and the deploy warn Nothing may serve this hostname: "The nginx-ingress add-on isn't installed on this cluster, so unless the cluster runs its own Ingress controller, nothing will serve this application's hostname. Install the nginx-ingress add-on." With it and Certificates, setting the app's domain is enough: AstroPulse writes its Ingress and asks for its certificate. See Put an application on your domain.
  • You run several apps and want them behind one load balancer. Without it, each app exposed with accessType: LoadBalancer gets a cloud load balancer of its own. With it, they share one, and NGINX picks each app's certificate by hostname.
  • You add apps under one domain often. With the wildcard certificate on, a new app one level below the domain needs no certificate of its own. See TLS modes.
  • An app must end TLS itself. The Passthrough TLS mode hands it the encrypted connection on the shared load balancer.
  • You expose a model on a cluster without the Gateway add-on. Without Ingress, the deploy is refused with Ingress exposure needs the nginx-ingress add-on.

You don't need it when your apps are reached only from inside the cluster, when an app speaks plain TCP (use accessType: LoadBalancer), or when every app you expose is a model behind an access policy, which only the Gateway serves.

Before you start​

  • A cluster. On a cluster with no cloud load balancer, such as a local or bare-metal one, turn on Enable node port.
  • For the wildcard certificate: Certificates with an issuer, and a domain under one of your organization's verified domains.

In the console​

After Version, its steps are Settings, Auto scaling and Wildcard certificate, then Advanced and Resources. Review runs the dry run, and Ask Nova at the top of the steps answers about the open step.

  1. Open the cluster from the cluster list, select the Add-ons tab, then Install Add-on, and pick Ingress.

  2. Keep the defaults for one controller behind a cloud load balancer, or set the settings below. SSL passthrough and Wildcard certificate turn on the TLS modes; its steps also hold Default TLS mode, Exposure, Ingress class name, Enable node port, Replicas, Auto scaling, Node selector and Annotations.

    Open zoom view

    Ingress settings: Default TLS mode, Ingress class and Expose via NodePort

    Ingress settings: Default TLS mode, Ingress class and Expose via NodePortIngress settings: Default TLS mode, Ingress class and Expose via NodePort
  3. On Review, the dry run runs by itself; select Continue to deploy once it passes, then Deploy nginx-ingress.

You should see​

The add-on reads Deployed, and its Overview shows the load balancer's address under Access, or the node ports and node addresses with Enable node port on. astroctl infra k8s addons get <cluster> nginx-ingress reports the same. While the load balancer is still being created, Events shows why.

Open zoom view

Ingress on its Overview: Deployed, Access with NodePort, the http and https ports and the node address, and the TLS modes

Ingress on its Overview: Deployed, Access with NodePort, the http and https ports and the node address, and the TLS modesIngress on its Overview: Deployed, Access with NodePort, the http and https ports and the node address, and the TLS modes

TLS modes​

An image application served through Ingress is always HTTPS. Its externalAccess.tls.mode says who presents the certificate:

ModeThe client seesNeeds on the add-onUse it for
CertificateA certificate issued for the application's hostnameNothing (Certificates issues it)Any application, any hostname
WildcardThe add-on's certificate for *.<domain>Wildcard certificateMany applications under one domain: nothing is issued per application, so a new one never waits for a certificate
PassthroughThe application's own certificateSSL passthroughAn application that must end TLS itself, such as gRPC or MQTT with client certificates

An application that names no mode gets the add-on's Default TLS mode when that mode covers its hostname, otherwise Certificate. Model applications always use Certificate. Helm, Git repository and YAML applications serve their own Ingress and take no tls field: Expose each source type.

Passthrough needs TLS that carries a server name (SNI). Plain TCP has none: serve it with accessType: LoadBalancer instead. While SSL passthrough is on, NGINX reads the server name of every new connection on port 443, which adds a little latency, so leave it off if no app needs it.

Turn on the wildcard and passthrough​

  1. Open the cluster's Add-ons tab, select Ingress, open Update, then select Change configuration.
  2. Turn on SSL passthrough if an application will use Passthrough.
  3. Under Wildcard certificate, turn on Enabled and enter the Domain, such as apps.example.com, without *..
  4. Optional: set Default TLS mode. Not set follows the rule above.
  5. Go to Review: it lists what changes and runs the dry run. Select Continue to apply once it passes, type nginx-ingress, then select Update nginx-ingress.

The wildcard certificate is astro-wildcard in the ingress-nginx namespace. Security: its private key stays in that namespace and is never copied to the applications it serves; an application can only use a hostname under your verified domains. Let's Encrypt issues a wildcard only through a DNS check, so Certificates needs a DNS solver; an EKS cluster AstroPulse created has one, and anywhere else add identity and dnsSolver to Certificates first. A self-signed issuer issues it at once, and clients must trust it themselves.

The add-on's ingressTls block, in astroctl infra k8s addons get <cluster> nginx-ingress -o yaml, lists the TLS modes the cluster offers, the default mode, the wildcard domain and the app URL shape, and for each mode it does not offer, what turns it on. wildcardWait says why the wildcard certificate is not issued yet, and wildcardStale says Certificates changed its issuer since this add-on was applied: apply Ingress again.

One application per mode​

In the console, an image app's Access step in the deploy wizard sets its domain under External access, then its TLS mode: Add-on default, Certificate, Wildcard or Passthrough. A mode the cluster does not offer is turned off, with what turns it on. On a running app, its Update tab changes TLS mode and keeps the domain.

shop.yaml
apiVersion: platform.astropulse.io/v1
kind: Application
metadata:
name: shop
spec:
profileName: production
source:
type: Image
image:
repository: nginxinc/nginx-unprivileged
tag: 1.27-alpine
port: 8080
externalAccess:
hostname: shop.example.com
tls:
mode: Certificate

Serves https://shop.example.com with a certificate issued for shop.example.com.

The dry run says where each application will be served and which certificate it presents, for example "Your app will be at https://shop.example.com, presenting a certificate issued for shop.example.com."

Three applications on one load balancer​

With both the wildcard and passthrough on, the three applications above share one load balancer, and NGINX picks the certificate by hostname. Check what each one presents (-ext needs OpenSSL 1.1.1 or later):

Terminal
for host in shop.example.com docs.apps.example.com tls-echo.example.com; do
echo | openssl s_client -connect "$host:443" -servername "$host" 2>/dev/null \
| openssl x509 -noout -issuer -ext subjectAltName
done

Change an application's mode​

Change externalAccess.tls.mode and apply again. Each change is a new version, so a rollback returns to the earlier mode. Moving off Certificate removes the application's own certificate; moving back issues it again.

Turning the wildcard on moves every application that names no mode, and whose hostname it covers, onto the wildcard at that application's next deploy that changes something. To keep an application on its own certificate, set tls.mode: Certificate on it, or set Default TLS mode to Certificate on the add-on.

Behavior and limits​

  • An Ingress of your own with a tls block gets HTTPS from NGINX; pair it with Certificates to issue and renew the certificate (Automatic HTTPS). With the wildcard on, an Ingress that lists a host one level below the wildcard domain under spec.tls, with no secretName, is served the wildcard certificate.
  • Enable node port is for clusters without a cloud load balancer, such as kind and bare metal.
  • exposure decides who can reach the load balancer, and so every Ingress it serves: Public, the internet (the default), or Private, only the cluster's network. In the console, Exposure. Security: set Private when no app on the cluster should be reachable from the internet.

Run it in production​

Every request into the cluster's Ingresses passes through it, so treat it as critical.

  • Two copies. The controller runs 2 copies on a cluster AstroPulse created with 2 or more fixed nodes, and 1 otherwise. With Enabled on under Auto scaling, set Min replicas to 2 or more, or it can scale down to one pod.
  • While it is down, traffic through it stops, and new or changed Ingresses are refused.
  • Changing Exposure replaces the load balancer. Moving between public and private creates a new load balancer with a new address. Plan the DNS change first.
  • The load balancer is billed by your cloud (a Network Load Balancer on AWS) for as long as the add-on is installed.
  • It grows with traffic. The controller reserves 100m CPU and 384Mi memory, with no memory limit. Raise Resources as traffic grows: Availability and resources.

Other ways in​

  • Nova: ask it, for example "install Ingress on eks-prod with the wildcard certificate for apps.example.com".
  • SDK and API: the same operations, in the API reference.

With astroctl​

nginx-ingress.yaml
apiVersion: platform.astropulse.io/v1
kind: K8sClusterAddon
metadata:
name: nginx-ingress
spec:
clusterName: eks-prod
configuration:
nginx:
sslPassthrough: true
wildcardCertificate:
enabled: true
domain: apps.example.com
Terminal
astroctl infra k8s addons apply -f nginx-ingress.yaml --dry-run
astroctl infra k8s addons apply -f nginx-ingress.yaml

astroctl infra k8s addons template <cluster> nginx-ingress writes every setting with what it does.

Settings​

Its own settings, under nginx, plus availability and resources. Every one is optional.

SSL passthroughnginx.sslPassthrough

Lets applications that serve their own TLS receive it still encrypted: an image application using TLS mode Passthrough, or an Ingress of your own annotated nginx.ingress.kubernetes.io/ssl-passthrough. Every other application's TLS ends at the controller.

Default
Off.
Enablednginx.wildcardCertificate.enabled

Issues one certificate for a domain and every name one level below it, and serves it to applications using TLS mode Wildcard. Needs Certificates.

Default
Off.
Domainnginx.wildcardCertificate.domain

The domain the certificate covers, without *.: apps.example.com covers apps.example.com and every name one level below it. Required with the wildcard on.

Accepts
A domain under one of your organization's verified domains.
Default TLS modenginx.defaultTlsMode

The TLS mode an application gets when it names none.

Accepts
Certificate, Wildcard or Passthrough.
Default
Wildcard while the wildcard certificate is on, otherwise Certificate.
Exposurenginx.exposure

Who can reach the controller's load balancer, and so every Ingress it serves.

Accepts
  • Public Public Reachable from the internet.
  • Private Private Reachable only from inside the cluster's network.
Default

Public

Enable node portnginx.enableNodePort

Publishes the controller on a NodePort instead of a cloud load balancer, for clusters that have none.

Default
Off.
Ingress class namenginx.ingressClassName

The class this controller answers to.

Default
nginx.
Replicasnginx.replicas

How many controller pods to run.

Default
AstroPulse's default.
Auto scalingnginx.autoScaling

Scales the controller itself with load: enabled, minReplicas, maxReplicas and targetCPUPercent, the CPU use replicas are scaled to hold.

Default
Off.
Node selectornginx.nodeSelector

Confines the controller to matching nodes.

Accepts
key=value, for example disktype=ssd.
Annotationsnginx.annotations

Added to the controller's Service, for the load balancer settings your cloud reads from there.

If it's refused​

"wildcardCertificate.domain is required when wildcardCertificate.enabled is true, for example apps.example.com"
Cause
The wildcard is on with no Domain.
Fix
Enter the Domain, such as apps.example.com.
"defaultTlsMode wildcard needs wildcardCertificate.enabled: turn the wildcard certificate on, or use defaultTlsMode certificate"
Cause
Default TLS mode is Wildcard with the wildcard off.
Fix
Under Wildcard certificate, turn on Enabled, or set Default TLS mode to Certificate.
"<domain> is not one of your organization's verified domains or under one. Add <domain> to your organization's domains in AstroPulse, publish the TXT record it gives you and verify the domain, then apply again."
Cause
The wildcard Domain is outside your organization's verified domains.
Fix
Add and verify the domain (Custom domains), then apply again.
"The wildcard certificate for <domain> needs the cert-manager add-on: install cert-manager with a DNS solver (dnsSolver), then apply nginx-ingress again."
Cause
Certificates is not installed.
Fix
Install Certificates with a DNS solver, then apply Ingress again.
"Let's Encrypt issues the wildcard certificate for *.<domain> only through DNS-01, and the cert-manager add-on has no DNS solver: set its dnsSolver (and identity) for the zone of <domain>, then apply nginx-ingress again."
Cause
Certificates uses Let's Encrypt without a DNS check.
Fix
Set dnsSolver and identity on Certificates, then apply Ingress again.
"The wildcard certificate for <domain> needs a certificate issuer, and the cert-manager add-on has none: set its email (Let's Encrypt) or issuerType selfsigned, then apply nginx-ingress again."
Cause
Certificates has no issuer.
Fix
Give Certificates an Email, or the self-signed issuer type.

These come on an application's dry run and apply, on externalAccess.tls:

"The application asks for the Wildcard TLS mode, and this cluster's Ingress add-on has no wildcard certificate."
Cause
The application asks for Wildcard, and the add-on's wildcard is off.
Fix
Under Wildcard certificate, turn on Enabled, or use Certificate.
"The application asks for the Wildcard TLS mode, and the wildcard certificate covers *.apps.example.com, one level below apps.example.com only; shop.example.com is not one of those names."
Cause
The hostname is not one level below the wildcard domain.
Fix
Use a hostname one level below the domain, or Certificate.
"The application asks for the Passthrough TLS mode, and this cluster's Ingress add-on does not pass TLS through to applications."
Cause
SSL passthrough is off.
Fix
Turn on SSL passthrough, or use Certificate.
"externalAccess.tls.mode is <mode>, and a model's endpoint is served with a certificate issued for its hostname."
Cause
A model application names a mode other than Certificate.
Fix
Remove tls from the model, or set Certificate.
"passthrough is for an image application that serves TLS itself. Use certificate."
Cause
A model application asks for Passthrough.
Fix
Set Certificate, or remove tls.
"is used only by image and model applications. Remove it."
Cause
A Helm, Git repository or YAML application sets externalAccess.tls.
Fix
Remove tls: these applications serve their own Ingress.

Next​