DevOps Glossary

Kubernetes IngressClass

Kubernetes IngressClass links an Ingress to the controller that routes outside traffic for cluster services.

Kubernetes IngressClass is a Kubernetes resource that tells the cluster which Ingress controller should handle a specific Ingress. In practical terms, it connects an Ingress rule to the routing implementation that will receive external HTTP or HTTPS traffic and forward it to Services inside the cluster.

What Kubernetes IngressClass does

An Ingress defines routing rules, such as “send traffic for api.example.com to the API Service.” An IngressClass defines which controller should implement those rules, such as NGINX Ingress Controller, AWS Load Balancer Controller, Traefik, HAProxy, or another controller.

This matters when a cluster has more than one Ingress controller. For example, you might run:

  • An external controller for public internet traffic
  • An internal controller for private corporate traffic
  • A cloud-specific controller that creates managed load balancers
  • A separate controller for a specific team, tenant, or environment

How it works

An IngressClass is defined with the Kubernetes API group networking.k8s.io. Its most important field is spec.controller, which identifies the controller that should process Ingress objects using that class.

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: public-nginx
spec:
  controller: k8s.io/ingress-nginx

An Ingress then references the class through spec.ingressClassName:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
spec:
  ingressClassName: public-nginx
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80

When the matching Ingress controller sees this Ingress, it configures its proxy, load balancer, or cloud resource to route traffic as requested.

Key fields and related concepts

  • metadata.name: The name used by Ingress objects in spec.ingressClassName.
  • spec.controller: A controller identifier, usually set by the Ingress controller project or cloud provider.
  • spec.parameters: Optional reference to extra controller-specific configuration.
  • Default IngressClass: A class can be marked as the default for Ingress objects that do not set ingressClassName.
  • Ingress controller: The running component that watches Ingress resources and applies routing changes.

Default IngressClass

You can mark one IngressClass as the default by adding the annotation ingressclass.kubernetes.io/is-default-class: "true".

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: public-nginx
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
spec:
  controller: k8s.io/ingress-nginx

If an Ingress does not specify spec.ingressClassName, Kubernetes can assign the default class. Use this carefully. In clusters with multiple teams or traffic paths, an implicit default can route traffic through the wrong controller if teams forget to set the field.

IngressClass vs Ingress vs Ingress controller

  • Ingress: Defines host, path, TLS, and backend Service routing rules.
  • IngressClass: Selects which controller should handle those rules.
  • Ingress controller: Runs in the cluster and turns Ingress rules into real routing behavior.

For example, an Ingress might say app.example.com should route to web-service. The IngressClass might say that this Ingress belongs to the AWS Load Balancer Controller. The controller then creates or updates the relevant AWS load balancer configuration.

Common use cases

  • Multiple ingress controllers: Run NGINX for internal traffic and a cloud load balancer controller for public traffic.
  • Environment separation: Use different classes for dev, staging, and production ingress behavior.
  • Team ownership: Give platform teams control over approved ingress paths while application teams define their own Ingress objects.
  • Cloud-specific routing: Use a controller that integrates with AWS, GCP, Azure, or another infrastructure provider.
  • Controller-specific settings: Connect an IngressClass to extra parameters when the controller supports them.

Real-world example

Suppose your startup runs two Ingress controllers in the same production cluster:

  • public-alb for customer-facing traffic through AWS Application Load Balancers
  • internal-nginx for private tools such as dashboards, admin panels, and internal APIs

Your customer API Ingress uses:

spec:
  ingressClassName: public-alb

Your internal admin app uses:

spec:
  ingressClassName: internal-nginx

This keeps public and private routing paths separate while using the same Kubernetes cluster. If you are deploying workloads on Amazon EKS, a pattern like this often appears alongside application guides such as deploying Apache Airflow on AWS Elastic Kubernetes Service.

Benefits

  • Clear controller selection: Teams can see which controller owns each Ingress.
  • Safer multi-controller clusters: You reduce the chance that two controllers act on the same Ingress.
  • Better platform control: Platform teams can define approved ingress classes for specific traffic patterns.
  • Cleaner manifests: spec.ingressClassName replaces older controller selection through annotations.

Tradeoffs and limitations

  • Controller behavior still varies: IngressClass standardizes selection, but each controller may support different annotations, TLS options, and load balancer features.
  • Misconfiguration can break routing: If spec.controller does not match a running controller, the Ingress may never become active.
  • Defaults can hide mistakes: A default IngressClass is convenient, but explicit ingressClassName is usually safer in shared clusters.
  • It does not replace network policy: IngressClass chooses an ingress implementation. It does not control pod-to-pod traffic or enforce application authorization.

Operational notes

  • Use consistent names, such as public-nginx, internal-nginx, or public-alb.
  • Document which IngressClass each team should use.
  • Validate Ingress manifests in CI so production services do not ship without the expected ingressClassName.
  • Check controller logs when an Ingress does not get an address or load balancer.
  • Include IngressClass resources in infrastructure-as-code workflows when possible. For example, teams that manage cluster objects with Terraform can treat IngressClass like other Kubernetes manifests, as shown in this guide to deploy Kubernetes resources using Terraform.

Deprecated annotation

Older Kubernetes configurations often used the annotation kubernetes.io/ingress.class on the Ingress object. Modern Kubernetes versions prefer spec.ingressClassName.

You may still see the annotation in legacy manifests, Helm charts, or older controller examples. For new manifests, use spec.ingressClassName unless your controller documentation says otherwise.

Related infrastructure workflows

IngressClass often sits close to cloud load balancer provisioning, DNS, certificates, and Kubernetes release management. If your platform manages cloud infrastructure from Kubernetes, tools such as Crossplane can fit into the same workflow. For example, you can review how teams deploy AWS resources using Crossplane on Kubernetes when designing a broader platform model.

Ingress behavior can also change during controller or cluster upgrades. Before upgrading Kubernetes, confirm that your Ingress controller version supports your target Kubernetes version, then test a few representative Ingress objects. This belongs on the same checklist as API deprecations, controller compatibility, and rollback planning, similar to the topics covered in practical Kubernetes upgrade tips for startups.

Summary

Kubernetes IngressClass gives you an explicit way to bind an Ingress to the controller that should handle it. It is most useful in clusters with multiple ingress controllers, cloud-specific routing needs, or shared platform ownership. For reliable operations, name classes clearly, avoid accidental defaults in shared environments, and make spec.ingressClassName part of your standard Ingress manifests.