Kubernetes itself contains a terminology conflict: There are events when watching over the objects/resources, such as in kubectl get pod --watch. And there are events as a built-in object kind, as shown in kubectl describe pod ... in the “Events” section. In this documentation, they are distinguished as “watch-events” and “k8s-events”. This section describes k8s-events only.

Handled objects

Kopf provides some tools to report arbitrary information for the handled objects as Kubernetes events:

import kopf

def create_fn(body, **_):
               message='Some message')

The type and reason are arbitrary and can be anything. Some restrictions apply (e.g. no spaces). The message is also arbitrary free-text. However, newlines are not rendered nicely (they break the whole output of kubectl).

For convenience, a few shortcuts are provided to mimic the Python’s logging:

import kopf

def create_fn(body, **_):
    kopf.warn(body, reason='SomeReason', message='Some message'), reason='SomeReason', message='Some message')
        raise RuntimeError("Exception text.")
        kopf.exception(body, reason="SomeReason", message="Some exception:")

These events are seen in the output of:

kubectl describe kopfexample kopf-example-1
  Type      Reason      Age   From  Message
  ----      ------      ----  ----  -------
  Normal    SomeReason  5s    kopf  Some message
  Normal    Success     5s    kopf  Handler create_fn succeeded.
  SomeType  SomeReason  6s    kopf  Some message
  Normal    Finished    5s    kopf  All handlers succeeded.
  Error     SomeReason  5s    kopf  Some exception: Exception text.
  Warning   SomeReason  5s    kopf  Some message

Other objects

Events can be also attached to other objects, not only those handled at the moment (and not event the children):

import kopf
import kubernetes

def create_fn(name, namespace, uid, **_):

    pod = kubernetes.client.V1Pod()
    api = kubernetes.client.CoreV1Api()
    obj = api.create_namespaced_pod(namespace, pod)

    msg = f"This pod is created by KopfExample {name}", reason='SomeReason', message=msg)


Events are not persistent. They are usually garbage-collected after some time, e.g. one hour. All the reported information must be only for short-term use.

Events for events

As a rule of thumb, it is impossible to create “events for events”.

No error will be raised. The event creation will be silently skipped.

As the primary purpose, this is done to prevent “event explosions” when handling the core v1 events, which creates new core v1 events, causing more handling, so on (similar to “fork-bombs”). Such cases are possible, for example, when using kopf.EVERYTHING (globally or for the v1 API), or when explicitly handling the core v1 events.

As a side-effect, “events for events” are also silenced when manually created via kopf.event(),, kopf.warn(), etc.