5.14 Kubernetes API Defaulting Model
Kubernetes API Defaulting Model automatically fills in missing fields when creating resources, ensuring consistency and reducing manual configuration efforts.
Kubernetes API Defaulting Model is the process by which the API server fills in unset fields of a submitted object with predetermined values before persisting it, reducing the burden on clients to specify every possible field explicitly while ensuring every stored object is complete and internally consistent according to rules defined either declaratively in a resource's schema or imperatively in defaulting code.
Why Defaulting Exists
Reducing Client Burden
Most resource types have dozens of optional fields, and requiring every client to specify explicit values for all of them would make manifests unwieldy and would tightly couple every client to the full detail of a resource's schema; defaulting allows a client to specify only what matters for their use case while the system fills in sensible values for everything else.
Ensuring Consistency at Storage Time
Because defaulting happens before an object is persisted, the version stored in etcd is always fully populated according to the applicable defaults at the time of creation, meaning controllers and other readers of the object do not need to separately handle the case of an unset field carrying an implicit, undocumented default.
Declarative Defaulting for Custom Resources
Schema-Based Default Values
CustomResourceDefinitions support specifying a default value directly within a field's OpenAPI schema, and the API server automatically applies that value whenever the field is omitted from a submitted object, without requiring any custom defaulting code to be written.
Defaults Applied at Multiple Levels
Defaults can be specified at any level of a nested schema, from top-level fields down to properties within deeply nested objects or array items, giving CRD authors fine-grained control over exactly which fields receive automatic values and what those values are.
Defaulting and Conversion Interaction
When a Custom Resource is served at multiple versions, defaulting is applied consistently regardless of which version a client submits, since defaulting occurs relative to the internal, converted representation, ensuring the same logical default applies no matter which served version was used for the original request.
Built-In Type Defaulting
Type-Specific Defaulting Functions
Built-in Kubernetes types use defaulting functions written directly in Go as part of the API server's code, applied during the conversion process between the wire format version and the internal representation, handling defaults too complex or conditional to express purely through a static schema value.
Examples of Built-In Defaults
Common examples include a container's imagePullPolicy defaulting based on whether the image tag is latest, a Service's type defaulting to ClusterIP when unspecified, and a Pod's restartPolicy defaulting to Always, each reflecting a sensible baseline behavior chosen by the project for the overwhelmingly common case.
Conditional and Cross-Field Defaults
Some built-in defaulting logic depends on the value of other fields within the same object, such as defaulting behavior that differs depending on whether a Pod specifies hostNetwork, a level of conditional logic that goes beyond what static schema-declared defaults alone can express.
Mutating Admission Webhooks as Extended Defaulting
Defaulting Beyond Schema Capabilities
For scenarios requiring defaulting logic more complex than declarative schema defaults or built-in type defaulting can provide, cluster operators can register mutating admission webhooks, external services invoked during admission that can programmatically set or adjust fields on an incoming object before it is persisted.
Ordering Relative to Other Admission Steps
Mutating webhooks run before validating webhooks in the admission chain, ensuring any fields they set or adjust are present and can be checked by subsequent validation steps, and multiple mutating webhooks can be chained, each seeing the result of prior mutations.
Defaulting and User Expectations
Defaults Are Not Always Obvious
Because defaults can be applied silently, a client that omits a field may end up with a persisted object that behaves differently from what they assumed, which is why tools like kubectl get -o yaml against a live object, rather than referring only to the originally submitted manifest, are important for confirming the actual, fully defaulted state that was stored.
Explicit Values Override Defaults
Any field a client explicitly sets, including a value identical to what the default would have been, is treated as an explicit value going forward, meaning the field will not silently revert to tracking future changes in the default value if the resource's defaulting logic is later updated in a newer Kubernetes version.