Skip to content
This repository has been archived by the owner on Sep 14, 2020. It is now read-only.

if child is deletd its not recreated automatically #153

Open
amolkavitkar opened this issue Jul 17, 2019 · 1 comment
Open

if child is deletd its not recreated automatically #153

amolkavitkar opened this issue Jul 17, 2019 · 1 comment
Labels
bug Something isn't working

Comments

@amolkavitkar
Copy link

Expected Behavior

I have created simple operator using kopf and its has children service created which is a clusterip service using adopt. if this service is deleted it should be recreated automatically

Actual Behavior

Child service of operator is not recreated automatically

Steps to Reproduce the Problem

  1. create operator using this tutorial: https://medium.com/swlh/building-a-kubernetes-operator-in-python-with-zalandos-kopf-37c311d8edff
  2. delete adopted service
  3. operator stays but child service gets deleted, either we shouldn't allow to delete or recreate it

Is there way to adopt child in such a way that we can recreate automatically or is there vent handler available

Specifications

  • Platform:
  • Kubernetes version: (use kubectl version) 1.14
  • Python version: (use python --version) 3.7
  • Python packages installed: (use pip freeze --all)
@nolar
Copy link
Contributor

nolar commented Jul 18, 2019

You can use Kubernetes finalizers for that.

@kopf.on.create(...)
def create_fn(**_):
    svc = {'apiVersion': 'v1', 'metadata': {'name' : name}, 'spec': { 'selector': {'app': 'db'}, 'type': 'NodePort'}}
    svc['metadata']['finalizers'] = ['your-domain.com/myoperator-svc-protector']
    kopf.adopt(svc, owner=body)
    obj = api.create_namespaced_service(namespace, svc)

If at least one finalizer exists on the object, k8s will not delete it, but only mark for deletion (by setting metadata.deletionTimestamp).

The operator must release its child object from duties somehow, when it decides it is suitable — by removing its own finalizer (but keeping the others if necessary):

@kopf.on.delete(...)
def delete_fn(name, namespace, **_):

    obj = api.read_namespaced_service(name, namespace)

    finalizers = list(obj.metadata.finalizers)
    if finalizers and 'your-domain.com/myoperator-svc-protector' in finalizers:
        finalizers.remove('your-domain.com/myoperator-svc-protector')

    kopf.adopt(svc, owner=body)
    obj = api.patch_namespaced_service(name, namespace, {
        'metadata': {'finalizers': finalizers}
    })

This operation will read the child Service to get its current list of finalizers, remove its own finalizer, and put the modified list of the finalizers back to the object.

PS: Keep in mind, this patching can be broken with kubernetes==10.0.0 due to kubernetes-client/python#866.


Another way is to indeed add an additional handler — e.g. the spy-handlers.

Please use kopf>=0.19 for this. The apiVersion: v1 objects are supported only in 0.19rc2 & 0.19+.

@kopf.on.create(...)
def create_fn(**_):
    svc = {'apiVersion': 'v1', 'metadata': {'name' : name}, 'spec': { 'selector': {'app': 'db'}, 'type': 'NodePort'}}
    kopf.adopt(svc, owner=body)
    kopf.label(svc, {'my-app': True})
    obj = api.create_namespaced_service(namespace, svc)

@kopf.on.event('', 'v1', 'services')
def service_event(meta, name, namespace, event, **_):
    # filter out irrelevant services
    if not meta.get('labels', {}).get('my-app'):
        return

    # Now, it is surely our service.
    # NB: the old service is already absent at this event, so there will be no HTTP 409 conflict.
    if event['type'] == 'DELETED':
        _recreate_service(name, namespace)

This will produce extra log messages for all existing services in the namespace/cluster, which looks not nice, but does not create problems. This could be solved soon with decorator-level filtering instead of calling the handler for a single if statement (see issues).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants