August 13, 2024·6 min read·engineeringkubernetescloudupgrades

Kubernetes 1.31 ends the built-in cloud provider fallback

Kubernetes 1.31 removes the remaining built-in cloud integrations. Its external contracts clarify provider ownership, while storage removals show that compatibility paths differ between integrations.

Kubernetes 1.31 removes the remaining in-tree cloud-provider integrations. The August 13 release announcement turns a long-running architectural transition into a concrete release boundary. Clusters can still integrate with cloud infrastructure, but those integrations now require external implementations. The old compiled-in implementation is no longer a fallback available through a configuration exception.

That distinction matters most for installations that used a temporary exception in an earlier release. The 1.29 migration announcement disabled legacy integrations by default while allowing affected operators to opt back in. It explicitly described that option as temporary. With 1.31, the remaining code is gone, so retaining an old feature-gate setting cannot preserve the implementation.

I favor the external controller model because Kubernetes's common API machinery should not require every cluster to carry every provider's implementation. The operational obligation remains substantial. Removing a built-in capability only works when its replacement is installed and owns the same necessary interactions with the environment.

Defaults and removal are different transitions

In 1.29, the DisableCloudProviders and DisableKubeletCloudCredentialProviders gates changed the default behavior. The earlier guidance names Azure, GCE and vSphere as the remaining built-in integrations affected by that change. It also records that OpenStack and AWS integration code had already left in earlier releases. The extraction therefore reached users at different times depending on their provider and starting version.

That staged history explains why a statement such as cloud extraction is complete needs a release context. The May migration report announced completed migration work and pointed to 1.31 for permanent disabling and removal. Today's release is that distribution boundary. Code completion and the availability of a release containing the final removal were separate events.

The practical consequence is a different meaning for old configuration. A gate that once selected a retained legacy path cannot recreate deleted code. The relevant configuration must identify and enable the external provider arrangement, and the cluster must actually run the components supplying it. This is an architectural migration whose final step appears as a release upgrade.

For operators already using external integrations, the removal does not mean that Kubernetes has abandoned their cloud. The release announcement explicitly distinguishes external integrations maintained within the Kubernetes project from third-party implementations. The shared change is where the provider-specific implementation lives. Ownership and release processes can differ among the available integrations.

Four contracts replace scattered implementation code

The May report explains why an external cloud controller alone cannot account for the entire change. The migration required four replacement systems. Each addresses provider-specific knowledge that had become embedded in a different part of Kubernetes. Their separate responsibilities help explain what an installation must preserve across the upgrade.

A cloud controller manager supplies node metadata such as region and zone, along with addresses known to the provider. It also runs the controller that provisions cloud load balancers for Services of type LoadBalancer. The Kubernetes API object still expresses the desired integration. The external controller performs the corresponding provider-specific operations.

Control-plane network access uses another contract. The API Server Network Proxy replaces SSH tunneler behavior that depended on provider details in the API server. A generic proxy path lets that component communicate with nodes without embedding the provider's tunneling implementation. This dependency is distinct from load-balancer reconciliation, even if both require access to the same infrastructure environment.

Kubelet credential provider plugins replace built-in logic for obtaining image-registry credentials. The kubelet can invoke an external binary to retrieve credentials dynamically. An image pull therefore depends on the configured credential implementation, while the kubelet keeps the generic responsibility for requesting credentials and starting workloads. Provider extraction does not make private image authentication unnecessary.

Storage uses CSI drivers and a translation layer for supported in-tree volume APIs. The report describes translating those APIs into equivalent CSI operations, which allows implementation removal while retaining compatibility for existing objects. That mechanism is important because storage definitions can outlive several component upgrades. Their continued meaning needs an explicit implementation path.

These contracts also identify different failure domains. A node can have correct cloud metadata while image authentication fails. A working load balancer does not prove that storage translation and its driver are configured. Treating cloud integration as one binary status loses the distinctions needed to understand the replacement architecture.

Storage removal has specific exceptions

The 1.31 announcement separately removes the CephFS volume plugin and makes the cephfs volume type non-functional. It recommends the CephFS CSI driver and says applications using the old plugin must be redeployed to use the new driver. That is stronger than an implementation moving transparently behind an unchanged volume declaration.

The release likewise removes the Ceph RBD volume plugin and its CSI migration support, making the rbd volume type non-functional. It recommends the RBD CSI driver and again calls for redeployment of affected applications. These explicit release notes should prevent a general statement about CSI translation from being mistaken for a universal promise covering every removed storage integration.

This distinction is central to upgrade reasoning. A translation mechanism preserves particular APIs under specified conditions. It does not guarantee that every historical volume type remains operational forever. The precise plugin and its documented migration behavior determine whether an existing object can continue to describe working storage.

I consider those exceptions more useful than a broad claim that externalization is transparent. The project can reduce core implementation code while still requiring real workload changes at specific boundaries. An upgrade description should name those boundaries so storage owners can distinguish an external-driver dependency from a required change to the application's volume configuration.

The release also removes several in-tree plugin unregister feature gates. The announcement explains that these gates supported testing removal scenarios without actually removing the plugins. Once the associated transition makes them redundant, their continued presence no longer supplies useful control. Their removal is another example of temporary migration configuration reaching the end of its purpose.

New integrations become more explicit

Other 1.31 changes follow the same preference for explicit contracts. Dynamic resource allocation gains an updated API centered on structured parameters. The release describes making resource information and requests visible to Kubernetes and clients, including the scheduler. With structured parameters, the scheduler allocates ResourceClaims while scheduling the pod.

The release retains controller-based allocation through what it calls classic DRA, behind a separate DRAControlPlaneController gate that must be enabled explicitly. That distinction separates allocation understood by the scheduler from policies still supplied by a driver controller. The updated DRA design is alpha in this release. Its presence should not be described as a stable replacement for every existing device-management arrangement.

Networking has another explicit implementation choice as the nftables kube-proxy backend reaches beta. The release says its feature gate is enabled by default, which makes the mode available without claiming that every installation now uses it. The mode is Linux-only and requires kernel 5.13 or later. Compatibility with the installed network plugin remains part of whether that backend can serve a particular cluster.

The announcement also identifies NodePort behavior differences between nftables and iptables modes. An implementation change can preserve the Service API while changing details operators depend on. That is the same general problem visible in cloud extraction, a stable declaration still requires a compatible implementation with understood behavior.

The upgrade boundary is now enforceable

The release makes another lifecycle distinction by moving cgroup v1 support into maintenance mode. Its announcement promises critical security fixes, with other bug fixing on a best-effort basis, and says new capabilities will not be added to that support. This is a different status from the deleted cloud integrations. The code remains available under a reduced maintenance commitment. Reading the two changes together shows why upgrade guidance needs precise lifecycle language, a deprecated option, a retained implementation in maintenance mode and a removed integration each impose different constraints on an installation.

Cloud-provider removal gives 1.31 a clear architectural consequence. Core components no longer carry the remaining embedded provider implementations, and the temporary fallback available during the earlier transition ends. The cluster's external integrations now provide the required infrastructure behavior through the replacement contracts described by the project.

For affected installations, the relevant dependency is the concrete external implementation serving each capability. Storage deserves particular precision because the release documents volume types that become non-functional and need application changes. The final removal narrows the core codebase while making those installed dependencies and their compatibility obligations part of the cluster's ordinary operating model.