A Python framework to write Kubernetes operators in just a few lines of code
MIT License
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).
However, it brings its own vision on how to write operators and controllers, which is not always in line with the agreed best practices of the Kubernetes world, sometimes the opposite of those. Here is the indicative publicly available summary:
Please do not use Kopf, it is a nightmare of controller bad practices and some of its implicit behaviors will annihilate your API server. The individual handler approach it encourages is the exact opposite of how you should write a Kubernetes controller. Like fundamentally it teaches you the exact opposite mindset you should be in. Using Kopf legitimately has taken years off my life and it took down our clusters several times because of poor code practices on our side and sh***y defaults on its end. We have undergone the herculean effort to move all our controllers to pure golang and the result has been a much more stable ecosystem. /Jmc_da_boss/
Think twice before you step into this territory ;-)
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!).
Dockerfile
+ a Python file (*).(*) 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.
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.
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.
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.
We use SemVer for versioning. For the versions available, see the releases on this repository.
This project is licensed under the MIT License — see the LICENSE file for details.