Kubernetes Operator Pythonic Framework (Kopf)
Kopf (Kubernetes Operator Pythonic Framework) is a Python framework designed to simplify the development of Kubernetes operators. It enables developers to write event-driven or state-driven handler functions with minimal boilerplate, focusing on domain logic rather than Kubernetes API infrastructure. The library is production-ready and stable (semantic v1), with current version 1.44.5, and receives regular maintenance for new Python and Kubernetes versions, without active development of new major functionality or imminent breaking changes.
Warnings
- breaking Kubernetes versions 1.16 and later introduce strict structural schemas that prune unknown fields in custom resources. If Kopf's status storage is not configured to use annotations, any status fields written by Kopf might be silently lost unless `x-kubernetes-preserve-unknown-fields: true` is explicitly added to your Custom Resource Definition (CRD) schema.
- gotcha Prior to Kopf version 1.44.0, operators could experience connection freezes or silent disconnections when running behind load balancers in Kubernetes clusters, especially during periods of inactivity. This was due to load balancers closing idle connections while the operator remained unaware.
- gotcha Running multiple instances of a Kopf operator for the same resource kind without proper peering configuration can lead to double-processing of events and inconsistent states.
- gotcha When developing admission webhooks or using features like self-signed certificates and Ngrok tunnels for local development, the `kopf[dev]` extra package is required. Without it, Kopf will raise startup errors if these functionalities are attempted.
Install
-
pip install kopf -
pip install 'kopf[dev]' -
pip install 'kopf[full-auth]'
Imports
- kopf
import kopf
Quickstart
import kopf
import os
@kopf.on.create('kopfexamples')
def create_fn(spec, name, logger, **kwargs):
message = f"Hello from Kopf! Created {name} with spec: {spec}"
logger.info(message)
return {'message': message}
@kopf.on.update('kopfexamples')
def update_fn(old, new, diff, name, logger, **kwargs):
logger.info(f"Updated {name} with changes: {diff}")
return {'message': f"Updated {name} with changes."}
@kopf.on.delete('kopfexamples')
def delete_fn(name, logger, **kwargs):
logger.info(f"Deleted {name}. Goodbye!")
return {'message': f"Deleted {name}."}
# To run this operator:
# 1. Apply the kopfexamples CRD: kubectl apply -f https://github.com/nolar/kopf/raw/main/examples/crd.yaml
# 2. Run the operator: kopf run your_operator_file.py --verbose
# 3. Create a custom resource: kubectl apply -f - <<EOF
# apiVersion: kopf.dev/v1
# kind: KopfExample
# metadata:
# name: my-example
# spec:
# field: value
# EOF