nolar / kopf

A Python framework to write Kubernetes operators in just a few lines of code
https://kopf.readthedocs.io/
MIT License
2.15k stars 163 forks source link
admission-controller admission-controllers admission-webhook asyncio framework kopf kubernetes kubernetes-concepts kubernetes-operator kubernetes-operators operator operator-framework operators python python-framework python3

Kubernetes Operator Pythonic Framework (Kopf)

GitHub CI Supported Python versions codecov Coverage Status

Kopf —Kubernetes Operator Pythonic Framework— is a framework and a library to make Kubernetes operators development easier, just in a few lines of Python code.

The main goal is to bring the Domain-Driven Design to the infrastructure level, with Kubernetes being an orchestrator/database of the domain objects (custom resources), and the operators containing the domain logic (with no or minimal infrastructure logic).

The project was originally started as zalando-incubator/kopf in March 2019, and then forked as nolar/kopf in August 2020: but it is the same codebase, the same packages, the same developer(s).

As of now, the project is in maintenance mode since approximately mid-2021: Python, Kubernetes, CI tooling, dependencies are upgraded, new bugs are fixed, new versions are released from time to time, but no new big features are added — there is nothing to add to this project without exploding its scope beyond the "operator framework" definition (ideas are welcome!).

Documentation

Features

(*) Small font: two files of the operator itself, plus some amount of deployment files like RBAC roles, bindings, service accounts, network policies — everything needed to deploy an application in your specific infrastructure.

Examples

See examples for the examples of the typical use-cases.

A minimalistic operator can look like this:

import kopf

@kopf.on.create('kopfexamples')
def create_fn(spec, name, meta, status, **kwargs):
    print(f"And here we are! Created {name} with spec: {spec}")

Numerous kwargs are available, such as body, meta, spec, status, name, namespace, retry, diff, old, new, logger, etc: see Arguments

To run a never-exiting function for every resource as long as it exists:

import time
import kopf

@kopf.daemon('kopfexamples')
def my_daemon(spec, stopped, **kwargs):
    while not stopped:
        print(f"Object's spec: {spec}")
        time.sleep(1)

Or the same with the timers:

import kopf

@kopf.timer('kopfexamples', interval=1)
def my_timer(spec, **kwargs):
    print(f"Object's spec: {spec}")

That easy! For more features, see the documentation.

Usage

Python 3.8+ is required: CPython and PyPy are officially supported and tested; other Python implementations can work too.

We assume that when the operator is executed in the cluster, it must be packaged into a docker image with a CI/CD tool of your preference.

FROM python:3.12
ADD . /src
RUN pip install kopf
CMD kopf run /src/handlers.py --verbose

Where handlers.py is your Python script with the handlers (see examples/*/example.py for the examples).

See kopf run --help for other ways of attaching the handlers.

Contributing

Please read CONTRIBUTING.md for details on our process for submitting pull requests to us, and please ensure you follow the CODE_OF_CONDUCT.md.

To install the environment for the local development, read DEVELOPMENT.md.

Versioning

We use SemVer for versioning. For the versions available, see the releases on this repository.

License

This project is licensed under the MIT License — see the LICENSE file for details.

Acknowledgments