6.3 KiB
Configuration Functions Specification
This document specifies a standard for client-side functions that operate on Kubernetes declarative configurations. This standard enables creating small, interoperable, and language-independent executable programs packaged as containers that can be chained together as part of a configuration management pipeline. The end result of such a pipeline are fully rendered configurations that can then be applied to a control plane (e.g. Using ‘kubectl apply’ for Kubernetes control plane). As such, although this document references Kubernetes Resource Model and API conventions, it is completely decoupled from Kubernetes API machinery and does not depend on any in-cluster components.
This document references terms described in Kubernetes API Conventions.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Use Cases
Configuration functions enable shift-left practices (client-side) through:
- Pre-commit / delivery validation and linting of configuration
- e.g. Fail if any containers don't have PodSecurityPolicy or CPU / Memory limits
- Implementation of abstractions as client actuated APIs (e.g. templating)
- e.g. Create a client-side "CRD" for generating configuration checked into git
- Aspect Orient configuration / Injection of cross-cutting configuration
- e.g. T-Shirt size containers by annotating Resources with
small,medium,largeand inject the cpu and memory resources into containers accordingly. - e.g. Inject
initandside-carcontainers into Resources based off of Resource Type, annotations, etc.
- e.g. T-Shirt size containers by annotating Resources with
Performing these on the client rather than the server enables:
- Configuration to be reviewed prior to being sent to the API server
- Configuration to be validated as part of the CI/CD pipeline
- Configuration for Resources to validated holistically rather than individually
per-Resource
- e.g. ensure the
Service.selectorandDeployment.spec.templatelabels match. - e.g. MutatingWebHooks are scoped to a single Resource instance at a time.
- e.g. ensure the
- Low-level tweaks to the output of high-level abstractions
- e.g. add an
init containerto a client "CRD" Resource after it was generated.
- e.g. add an
- Composition and layering of multiple functions together
- Compose generation, injection, validation together
Spec
Input Type
A function MUST accept as input a single Kubernetes List type.
The items field in the input will contain a sequence of Object types.
A function MAY not support Simple types and List types.
An example using v1/ConfigMapList as input:
apiVersion: v1
kind: ConfigMapList
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: config1
data:
p1: v1
p2: v2
- apiVersion: v1
kind: ConfigMap
metadata:
name: config2
An example using v1/List as input:
apiVersion: v1
kind: List
items:
- apiVersion: foo-corp.com/v1
kind: FulfillmentCenter
metadata:
name: staging
address: "100 Main St."
- apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-reader
rules:
- resources:
- namespaces
apiGroups:
- ""
verbs:
- get
- watch
- list
In addition, a function MUST accept as input a List of kind ResourceList where the
functionConfig field, if present, will contain the invocation-specific configuration passed to the function
by the orchestrator.
Functions MAY consider this field optional so that they can be triggered in an ad-hoc fashion.
An example using config.kubernetes.io/v1beta1/ResourceList as input:
apiVersion: config.kubernetes.io/v1beta1
kind: ResourceList
functionConfig:
apiVersion: foo-corp.com/v1
kind: FulfillmentCenter
metadata:
name: staging
metadata:
annotations:
config.k8s.io/function: |
container:
image: gcr.io/example/foo:v1.0.0
spec:
address: "100 Main St."
items:
- apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-reader
rules:
- resources:
- namespaces
apiGroups:
- ""
verbs:
- get
- watch
- list
Here FulfillmentCenter kind with name staging is passed as the invocation-specific configuration
to the function.
Output Type
A function’s output MUST be the same as the input specification above
-- i.e. ResourceList or List.
This is necessary to enable chaining two or more functions together in a pipeline.
The serialization format of the output SHOULD match that of its input on each invocation
-- e.g. if the input was a ResourceList, the output should also be a ResourceList.
Serialization Format
A function MUST support YAML as a serialization format for the input and output. A function MUST use utf8 encoding (as YAML is a superset of JSON, JSON will also be supported by any conforming function).
Operations
A function MAY Create, Update, or Delete any number of items in the items field and output the
resultant list.
A function MAY modify annotations with prefix config.kubernetes.io, but must be careful about
doing so since they’re used for orchestration purposes and will likely impact subsequent functions
in the pipeline.
A function SHOULD preserve comments when input serialization format is YAML. This allows for human authoring of configuration to coexist with changes made by functions.
Containerization
A function MUST be implemented as a container.
A function container MUST be capable of running as a non-root user if it does not require access to host filesystem or makes network calls.
stdin/stdout/stderr and Exit Codes
A function MUST accept input from stdin and emit output to stdout.
Any error messages MUST be emitted to stderr.
An exit code of zero indicates function execution was successful. A non-zero exit code indicates a failure.