Given the lessons learned from Knative’s implementation of duck type support, we would like to produce an upstream implementation of the tools and apis needed to make duck types on the Kubernetes control plane an approachable solution for anyone.
We are requesting a new kubernetes-sigs repo to produce a PoC for the Kubernetes ecosystem. (kubernetes-sigs/ducktypes) This should be sponsored by the API Machinery WG.
Knative has developed both a set of tools for composing and interacting with duck types as well as a discovery api to aid in finding and reporting duck types, both custom or adopted. The core value proposition of Knative is not duck types, but the concept has allowed us to compose our resources in a way that prompts loose coupling within the project pillars, as well as any other Kubernetes extension that opts into the duck type ecosystem.
There has been an increasing number of requests to enable the usage of duck types to the broader ecosystem because as the Kubernetes communities develop extensions to the API it becomes clear that there is a need to consider resource kinds as a class of things that can be observed or acted upon.
Produce tooling enables the generation of clientsets, listers, and informers for duck types.
This enables the observation, interaction, mutation, and reconciliation of duck types.
Procedures to advertise a resource should be considered as a duck type.
Sometimes a resource author knows of a set of duck types they would like to be considered as, and other times this resource might be opted in by a third party.
Produce an API to define a duck type for a cluster.
The end result of these goals is to enable a duck type ecosystem to develop where a resource author can make api shape choices to conform with known duck types they are targeting and opt into existing duck type use cases. So the tooling and discovery become two fold: one side are duck type authors, developing the contract that duck adheres to; and the other are resources selecting shapes based on known conventions. The duck type support in Kubernetes allows for those conventions to be discoverable, or at least definable in a neutral way.
Define a set of duck types for Kubernetes.
This would be enabled by the work if it proves useful.
Change the ux around resources in kubectl.
Also enabled by the work, but requires client engineering work to integrate.
Tight integration with kubebuilder / controller runtime or any other reconciler framework.
Require the use of duck types for any projects which don’t wish to participate.
There are two user personas to consider when thinking about a duck type ecosystem:
Designer - This persona would like to operate on a set of resources of different Kinds in a consistent way. Defining the duck type would be something like a light specification for the control plane for that resource.
Provider - This persona may or may not be aware the resource they have provided is the duck type. This is by design.
As a Designer, their goal is to provide one or more duck type definitions for a specific goal, and define the control plane expectations for that class of kinds. Example ducks found in the wild:
Addressable - (from Knative) a kind instance exposes a status.address.url to be used to address that resource on a dataplane.
ProvisionedServiceable - (from Service Binding) the kind instance exposes a status.binding.name (name of secret) and contained inside is further typing information on how to use this in the target application.
Managed - (From Crossplane) is an instance kind that can be examined to pick out common things like provider, config and management settings.
Machine - (from Cluster API) represents the mechanics of bringing a machine in and out of a cluster and cross referencing nodes for a cluster. Machine is a pure duck type, and implementations are brought by providers.
Given a duck type a definition, a Provider can choose to structure their resources to provide that shape. At the moment this is left as an exercise for each Designer to document the duck shape expectations.
There is a class of work that is enabled by knowing the existence of duck types in a cluster, Knative has been experimenting with adding syntax “sugar” to resources: adding an annotation causes some other resource to be created or modified in a way that is related to the annotated resource configuration or existence.
In a WIP project we have a reconciler reconciling cluster duck types for addressables. For each addressable duck, we spin out a controller for that kind. When one of these are identified we use the target annotation to produce another resource (a DomainMapping) configured by the annotation contents and owned by the annotated resource. Sugar.
We propose this work falls under the supervision of api machinery, with regular progress updates in the api machinery working group meeting. The work breaks down into several phases that are dependent on interest and adaptation by the community. The decision to proceed to later phases or turn down the project will be determined by the demonstrated utility of the previous stage.
Create a kubernetes-sigs/ducktypes repo and begin landing a new implementation of:
Duck type codegen (similar to clientgen but using the partial schema go structs that define the resource shape of the duck type) results in strongly typed listers and informers for a duck type, providing kind on their creation.
Tooling to enable mutation of duck types from controllers (or go in general) using client and/or server side apply.
An optional new resource that represents a duck type that would be end user installable in a cluster. This would be the equivalent of the discovery api for duck types. It actively reflects the state of a cluster’s ducks as they are installed or removed.
This would include native Kubernetes resources.
As we see adoption, we also see places for improvements. We enter the phase of enhancing the supporting infrastructure to better support the concept of duck types in the Kubernetes ecosystem.
Likely there are Custom Resource Definition resource shape additions or changes that would help the discovery or selection of duck types. We would evaluate and implement these changes via low scope KEPs to make targeted changes.
One first class way a resource may opt to be a duck type could be a custom subresource endpoint that allows for observation or mutation of the resource as if it is a duck type.
Duck type support becomes expected and asked for, we would upstream the resources and tooling to enable duck types directly in Kubernetes.
The tooling would become part of the standard codegen tooling support provided by kubernetes clientgen.
The Kubernetes control plane (discovery api?) would include the new duck type definition resource by default.
Tekton
EventListener is an addressable (Knative style) duck type.
Knative
Original Knative Duck Typing proposal
Nearly every object ref used inside of Knative is used as a duck type, (v1 duck types).
Many Knative resources expose themselves as one or more duck types, see the knative cluster duck types.
Crossplane
Many duck type interfaces defined at the go level for interacting with resources.
Example the _Managed_ interface for resources.
Cluster API
See the CRDs provided by Cluster API
Cluster Addons
Addons for Kubernetes clusters managed by the kubebuilder-declarative-patterns project.
Example _Patchable_ interface for resources
Service Bindings
Lots of duck types defined in the Spec, focused around applying secrets and other runtime config from a service onto an Application.
Rather than attempt to enable duck types at the kubernetes level, we could attempt to do this as an independent project aimed at anyone who would like to leverage duck typing.
We leave the tooling and APIs inside of Knative and various other projects.