August 26, 2020·6 min read·engineeringkubernetesingressreleasesoperations

Kubernetes 1.19 stabilizes the Ingress contract

Ingress reaches v1 after prolonged beta use, while Kubernetes extends patch support to one year. The release separates a stable routing API from the controllers that implement it.

An API can become essential to users while remaining in beta. Ingress reached that position through adoption by application teams and ingress controller providers. Kubernetes 1.19 resolves the mismatch by making the API generally available. The release announcement argues that abandoning the existing API without a complete replacement would be impractical, because its established use cases still need support.

The August 26 announcement also extends the patch support window to one year starting with this release. These decisions address different kinds of continuity. Ingress gives users a stable API contract for a widely deployed capability. The longer support period gives operators more time to keep deployed Kubernetes versions within the project's patch window.

I value Kubernetes as a framework for controllers, which makes both decisions consequential. A stable object definition gives controllers and their clients a firmer agreement. A realistic patch window gives the people operating that framework more room to maintain it without leaving supported versions.

Stability recognizes the existing use cases

The announcement describes Ingress as having reached practical maturity through usage even before formal graduation. It does not claim that the current API satisfies every possible routing requirement. The project can support this version while considering a different or broader API for additional requirements. Those goals do not require withholding a stable contract from current users.

The v1.19.0 networking API definitions make the agreement concrete. An Ingress rule associates a host and HTTP paths with backends. Incoming requests first match a host, then the relevant rule selects a backend. The backend can refer to a Service and its port, with the Service in the same namespace as the Ingress.

That object is configuration for an implementation. Its API definition describes how a controller should interpret the class and matching rules. It does not turn the API server into an HTTP proxy. The distinction remains necessary when diagnosing why an accepted object does not produce the expected traffic behavior. The responsible ingress controller has to implement the declared rule.

Path matching becomes an explicit choice

The API provides Exact, Prefix, and ImplementationSpecific path types. Exact matching is case sensitive. Prefix matching uses slash-separated path elements, which differs from testing whether one raw string starts with another. The type definition gives /foo/bar as a match for /foo/bar/baz and excludes /foo/barbaz.

That example matters for application boundaries. A route intended for a directory-like path should not automatically include names that merely share the last element's characters. Element-based matching expresses the intended relationship between paths. It also gives controller authors a defined behavior that clients can expect.

Implementation-specific matching leaves interpretation to the IngressClass. The API permits an implementation to treat it as a separate type or like prefix or exact matching. That remains a deliberate place where behavior can differ. Calling the API stable does not remove every controller-specific choice from existing configurations.

The following object illustrates the stable Service backend structure. It assumes a suitable public IngressClass and a catalog Service with port 80 already exist in the same namespace.

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

Under the documented prefix semantics, /catalog/items matches this rule while /catalogue does not. This is a routing declaration, so it neither creates the Service nor establishes application authentication. Its purpose is to select the backend for the matching request path through the chosen controller.

A class identifies implementation responsibility

The API's ingressClassName refers to an IngressClass resource. That resource identifies the controller responsible for the class and can refer to further configuration. Multiple classes can therefore represent different configurations implemented by the same controller. The controller identifier itself is an immutable field in the class definition.

IngressClass also supports a default-class annotation. When one class is marked as the default, new Ingress resources without an explicit class receive it. This is a configuration decision that affects newly created objects. An explicit class reference, as in the example, makes the intended selection visible in the Ingress itself.

The source definition records compatibility with the deprecated kubernetes.io/ingress.class annotation. When that annotation is present, it must take precedence over the new field, and a controller may warn about differing values. That detail is relevant to existing manifests carrying old annotations alongside new fields. Merely adding ingressClassName does not erase the compatibility rule.

I prefer explicit class selection because it identifies which implementation is expected to act. That is especially useful when the API object and the proxy handling traffic belong to different operational concerns. A valid resource still needs the selected controller and its configuration to produce the desired result.

Support duration responds to upgrade constraints

The release announcement cites an early 2019 Long Term Support working group survey. A substantial group of users could not upgrade within the existing nine-month support period. The survey suggested that extending patch support to twelve to fourteen months would let more users remain on supported versions, regardless of whether they used self-built or commercially supplied distributions.

Kubernetes 1.19 adopts a one-year period. That changes the time available for supported operation. It does not remove the work of upgrading or establish that every downstream distribution provides the same lifecycle. The announcement's commitment concerns the project's patch support window beginning with this minor release.

The cycle producing 1.19 lasted twenty weeks. The release team describes extending the schedule in response to COVID-19, the George Floyd protests, and other global events affecting contributors. That account is separate from the long-term support decision, which draws on the earlier survey. Both concern the people required to deliver and operate the software, but their stated causes differ.

Storage scheduling gains information about capacity

The release also introduces alpha storage capacity tracking. The announcement explains the scheduler's previous assumption that additional persistent storage was available without a capacity constraint. Topology restrictions had addressed where storage could be available, but remaining capacity could still make a selected placement unusable.

The new API lets a CSI driver report storage capacity, and the scheduler can use that information when selecting a node. The project presents this as a step toward dynamically provisioned local volumes and other capacity-constrained storage. It is alpha functionality, with a different maturity commitment from the stable Ingress API.

Generic ephemeral volumes are another alpha addition. They use dynamic provisioning while binding the volume lifecycle to the pod. The announcement describes using drivers that already support provisioning to supply scratch storage with different characteristics from the root disk. This extends the choice of storage implementation without requiring an application to treat the volume as independently long lived.

The release-time changelog describes the use of normal PersistentVolumeClaim provisioning for those volumes. That design allows usual volume capabilities to remain relevant, rather than inventing a separate provisioning model for temporary use. It also means the alpha lifecycle feature still depends on the chosen storage driver's capabilities.

Kubelet credentials have a stable renewal process

Kubelet client TLS certificate rotation also graduates to stable. The announcement describes a startup sequence that looks for an existing managed certificate and private key on disk. If those are unavailable, the kubelet examines its configuration for a certificate or file reference. Bootstrap credentials can then support generating a key and requesting a signed certificate through the API server.

As expiry approaches, the certificate manager generates new keys and requests replacement certificates. That process addresses the ongoing lifecycle of a node's client credentials. It differs from the one-time question of whether a node can authenticate immediately after installation. A cluster that continues operating needs its credential process to remain functional beyond initial bootstrap.

The announcement connects manageable administration with automatic approval of the kubelet's certificate signing requests. Renewal involves both the requesting kubelet and the cluster's signing and approval arrangement. Stable client rotation describes the supported mechanism, while the configured approval behavior remains part of making that mechanism work in a particular cluster.

The distinction between those maturity levels helps interpret 1.19. Ingress supplies a supported v1 description of established routing behavior, including explicit path types and class selection. Capacity tracking and generic ephemeral volumes introduce new mechanisms that remain alpha. For existing ingress deployments, the immediate work is to represent the intended matching and controller selection accurately in the stable API, including compatibility with annotations already present in manifests.