Building a Kubernetes Operator in Python without frameworks and SDK

Currently, Go is a de facto monopoly among programming languages that people choose to create Kubernetes operators. Their preferences stem from objective reasons such as:

  1. There is a powerful framework for developing operators with Go — Operator SDK.

  2. Many Go-based applications, such as Docker and Kubernetes, have become game changers. Writing an operator in Go allows you to speak with the ecosystem in the same language.

  3. High performance of Go-based applications as well as simple mechanisms to use the concurrency right out of the box.

But what if lack of time or simply motivation prevents you from studying Go? In this article, we’ll show you how to create a solid operator using one of the most popular programming languages that almost every DevOps engineer is familiar with — Python.

Please welcome Copyrator — the copy operator!

To make things easy and practical, let’s create a simple operator designed to copy ConfigMap when a new namespace shows up or when one of the following two objects — ConfigMap or Secret — changes its state. From the practical side, our new operator can be used for bulk updates of the application’s configuration (by updating ConfigMap) or for resetting secrets, e.g. keys used for Docker Registry (when a Secret is added to the namespace).

So what features should a good Kubernetes operator have? Let’s name them:

  1. The interaction with the operator is made via Custom Resource Definitions (hereinafter CRD).

  2. The operator is configurable. We can use command line flags and environment variables to set it up.

  3. Docker image and Helm chart are created with simplicity in mind so that users can install it effortlessly (basically with just one command) into their Kubernetes clusters.


In order for the operator to know which resources and where to look for, we need to set some rules. Each rule will be represented as a specific CRD object. What fields should this CRD object have?

  1. Type of the resource that we are interested in (ConfigMap or Secret).

  2. List of namespaces that store resources.

  3. Selector which helps us in searching for resources in the particular namespace.

Let’s define our CRD:

kind: CustomResourceDefinition
  - name: v1
    served: true
    storage: true
  scope: Namespaced
    plural: copyrators
    singular: copyrator
    kind: CopyratorRule
    - copyr
      type: object
          type: string
          type: array
            type: string
          type: string

… and immediately add a simple rule to select ConfigMaps with labels matching copyrator: "true" in the default namespace:

kind: CopyratorRule
  name: main-rule
    module: copyrator
ruleType: configmap
  copyrator: "true"
namespace: default

Well done! Now we have to obtain information about our rule somehow. It’s time to say we are not going to make our cluster API’s requests manually. For this purpose we will use a Python library called kubernetes-client:

import kubernetes
from contextlib import suppress

CRD_PLURAL = 'copyrators'

def load_crd(namespace, name):
    client = kubernetes.client.ApiClient()
    custom_api = kubernetes.client.CustomObjectsApi(client)

    with suppress(kubernetes.client.api_client.ApiException):
        crd = custom_api.get_namespaced_custom_object(
    return {x: crd[x] for x in ('ruleType', 'selector', 'namespace')}

By executing the above code, we will get the following result:

{'ruleType': 'configmap', 'selector': {'copyrator': 'true'}, 'namespace': ['default']}

Great! Now we have a specific rule for the operator. What’s important, we’ve been able to do it via the so-called Kubernetes way.

Environment variables or flags? Both!

Now it is time to proceed to the basic operator setup. There are two main approaches to configuring applications:

  • via command line parameters,

  • via environment variables.
    You can retrieve settings via command line parameters with more flexibility and support/validation of data types. We will use an argparser module from the standard Python library. Details and examples of its use are available in the Python documentation.

Here is an example of configuring the retrieval of command line flags, adapted to our case:

parser = ArgumentParser(
        description='Copyrator - copy operator.',
        default=getenv('NAMESPACE', 'default'),
        help='Operator Namespace'
        default=getenv('RULE_NAME', 'main-rule'),
        help='CRD Name'
    args = parser.parse_args()

On the other hand, you can easily pass service information about the pod into the container via environment variables in Kubernetes. For example, you can get information about the namespace where the pod is running via the following structure:

         fieldPath: metadata.namespace

The operating logic of the operator

Let’s use special maps to divide methods for working with ConfigMap and Secret. They will allow us to figure out what methods we need for tracking and creating an object:

    'configmap': 'list_namespaced_config_map',
    'secret': 'list_namespaced_secret',

    'configmap': 'create_namespaced_config_map',
    'secret': 'create_namespaced_secret',

Then you have to receive events from the API server. We will implement that functionality in the following manner:

def handle(specs):
    v1 = kubernetes.client.CoreV1Api()
# Get the method for tracking objects
    method = getattr(v1, LIST_TYPES_MAP[specs['ruleType']])
    func = partial(method, specs['namespace'])

    w =
    for event in, _request_timeout=60):
        handle_event(v1, specs, event)

After the event is received, we proceed to the underlying logic of handling it:

# Types of events to which we will respond
def handle_event(v1, specs, event):
    if event['type'] not in ALLOWED_EVENT_TYPES:

    object_ = event['object']
    labels = object_['metadata'].get('labels', {})
    # Look for the matches using selector
    for key, value in specs['selector'].items():
        if labels.get(key) != value:
    # Get active namespaces
    namespaces = map(
        lambda x:,
            lambda x: x.status.phase == 'Active',
    for namespace in namespaces:
        # Clear the metadata, set the namespace
        object_['metadata'] = {
            'labels': object_['metadata']['labels'],
            'namespace': namespace,
            'name': object_['metadata']['name'],
        # Call the method for creating/updating an object

The basic logic is complete! Now we need to pack it into the single Python package. Let’s create and add metadata about the project to it:

from sys import version_info
from sys import version_info

from setuptools import find_packages, setup

if version_info[:2] < (3, 5):
    raise RuntimeError(
        'Unsupported python version %s.' % '.'.join(version_info)

_NAME = 'copyrator'
        'Development Status :: 3 - Alpha',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'console_scripts': [
            '{0} = {0}.cli:main'.format(_NAME),

NB: Python client library for Kubernetes has its own versioning system. The compatibility of the client’s and Kubernetes’ versions is outlined in this matrix.
Currently, our project has the following structure:

├── copyrator
│ ├── # Command line operating logic
│ ├── # Constants that we described above
│ ├── # CRD loading logic
│ └── operator.pyк # Basic logic of the operator
└── # Package description

Docker and Helm

The resulting Dockerfile will be ridiculously simple: we will take the basic python-alpine image and install our package (let’s postpone its optimization until better times):

FROM python:3.7.3-alpine3.9
ADD . /app
RUN pip3 install /app
ENTRYPOINT ["copyrator"]

The deployment for Copyrator is also very simple:

apiVersion: apps/v1
kind: Deployment
  name: {{ .Chart.Name }}
      name: {{ .Chart.Name }}
        name: {{ .Chart.Name }}
      - name: {{ .Chart.Name }}
        imagePullPolicy: Always
        args: ["--rule-type", "main-rule"]
        - name: NAMESPACE
              fieldPath: metadata.namespace
      serviceAccountName: {{ .Chart.Name }}-acc

Finally, we have to create a relevant role for the operator with the necessary permissions:

apiVersion: v1
kind: ServiceAccount
  name: {{ .Chart.Name }}-acc

kind: ClusterRole
  name: {{ .Chart.Name }}
  - apiGroups: [""]
    resources: ["namespaces"]
    verbs: ["get", "watch", "list"]
  - apiGroups: [""]
    resources: ["secrets", "configmaps"]
    verbs: ["*"]
kind: ClusterRoleBinding
  name: {{ .Chart.Name }**}
  kind: ClusterRole
  name: {{ .Chart.Name }}
- kind: ServiceAccount
  name: {{ .Chart.Name }}-acc


In this article, we showed you how to create your own Python-based operator for Kubernetes. Of course, it still has room to grow: you can enrich it with the abilities to process several rules, monitor changes in its CRDs on its own, benefit from concurrency capabilities…

All code is available in our public repository so you could get acquainted with it. If you’re interested in other examples of Python-based operators, we can recommend you to pay attention to two operators for deploying mongodb (here and here).

#python #Kubernetes

What is GEEK

Buddha Community

Building a  Kubernetes Operator in Python without frameworks and SDK
Christa  Stehr

Christa Stehr


50+ Useful Kubernetes Tools for 2020 - Part 2


Last year, we provided a list of Kubernetes tools that proved so popular we have decided to curate another list of some useful additions for working with the platform—among which are many tools that we personally use here at Caylent. Check out the original tools list here in case you missed it.

According to a recent survey done by Stackrox, the dominance Kubernetes enjoys in the market continues to be reinforced, with 86% of respondents using it for container orchestration.

(State of Kubernetes and Container Security, 2020)

And as you can see below, more and more companies are jumping into containerization for their apps. If you’re among them, here are some tools to aid you going forward as Kubernetes continues its rapid growth.

(State of Kubernetes and Container Security, 2020)

#blog #tools #amazon elastic kubernetes service #application security #aws kms #botkube #caylent #cli #container monitoring #container orchestration tools #container security #containers #continuous delivery #continuous deployment #continuous integration #contour #developers #development #developments #draft #eksctl #firewall #gcp #github #harbor #helm #helm charts #helm-2to3 #helm-aws-secret-plugin #helm-docs #helm-operator-get-started #helm-secrets #iam #json #k-rail #k3s #k3sup #k8s #keycloak #kiali #kiam #klum #knative #krew #ksniff #kube #kube-prod-runtime #kube-ps1 #kube-scan #kube-state-metrics #kube2iam #kubeapps #kubebuilder #kubeconfig #kubectl #kubectl-aws-secrets #kubefwd #kubernetes #kubernetes command line tool #kubernetes configuration #kubernetes deployment #kubernetes in development #kubernetes in production #kubernetes ingress #kubernetes interfaces #kubernetes monitoring #kubernetes networking #kubernetes observability #kubernetes plugins #kubernetes secrets #kubernetes security #kubernetes security best practices #kubernetes security vendors #kubernetes service discovery #kubernetic #kubesec #kubeterminal #kubeval #kudo #kuma #microsoft azure key vault #mozilla sops #octant #octarine #open source #palo alto kubernetes security #permission-manager #pgp #rafay #rakess #rancher #rook #secrets operations #serverless function #service mesh #shell-operator #snyk #snyk container #sonobuoy #strongdm #tcpdump #tenkai #testing #tigera #tilt #vert.x #wireshark #yaml

Ray  Patel

Ray Patel


top 30 Python Tips and Tricks for Beginners

Welcome to my Blog , In this article, you are going to learn the top 10 python tips and tricks.

1) swap two numbers.

2) Reversing a string in Python.

3) Create a single string from all the elements in list.

4) Chaining Of Comparison Operators.

5) Print The File Path Of Imported Modules.

6) Return Multiple Values From Functions.

7) Find The Most Frequent Value In A List.

8) Check The Memory Usage Of An Object.

#python #python hacks tricks #python learning tips #python programming tricks #python tips #python tips and tricks #python tips and tricks advanced #python tips and tricks for beginners #python tips tricks and techniques #python tutorial #tips and tricks in python #tips to learn python #top 30 python tips and tricks for beginners

Ray  Patel

Ray Patel


Lambda, Map, Filter functions in python

Welcome to my Blog, In this article, we will learn python lambda function, Map function, and filter function.

Lambda function in python: Lambda is a one line anonymous function and lambda takes any number of arguments but can only have one expression and python lambda syntax is

Syntax: x = lambda arguments : expression

Now i will show you some python lambda function examples:

#python #anonymous function python #filter function in python #lambda #lambda python 3 #map python #python filter #python filter lambda #python lambda #python lambda examples #python map

Ray  Patel

Ray Patel


Ternary operator in Python?

  1. Ternary Operator in Python

What is a ternary operator: The ternary operator is a conditional expression that means this is a comparison operator and results come on a true or false condition and it is the shortest way to writing an if-else statement. It is a condition in a single line replacing the multiline if-else code.

syntax : condition ? value_if_true : value_if_false

condition: A boolean expression evaluates true or false

value_if_true: a value to be assigned if the expression is evaluated to true.

value_if_false: A value to be assigned if the expression is evaluated to false.

How to use ternary operator in python here are some examples of Python ternary operator if-else.

Brief description of examples we have to take two variables a and b. The value of a is 10 and b is 20. find the minimum number using a ternary operator with one line of code. ( **min = a if a < b else b ) **. if a less than b then print a otherwise print b and second examples are the same as first and the third example is check number is even or odd.

#python #python ternary operator #ternary operator #ternary operator in if-else #ternary operator in python #ternary operator with dict #ternary operator with lambda

August  Larson

August Larson


Python I: Data Types and Operators, variable assignment, and print()

Learn the Python basics so that you can use it for your data science projects.

This blog is part of a series of tutorials called Data in Day. Follow these tutorials to create your first end-to-end data science project in just one day. This is a fun easy project that will teach you the basics of setting up your computer for a data science project and introduce you to some of the most popular tools available. It is a great way to get acquainted with the data science workflow.

I. About Python 🐍

Created by Dutch programmer Guido van Rossum at Centrum Wiskunde & Informatica, Python made its debut in 1991. Over thirty years it has gained popularity earned a reputation of being the “Swiss army knife of programming languages.” Here are a few reasons why:

In emerging fields like data science, artificial intelligence, and machine learning, a robust community, plenty of packages, paradigm flexibility, and syntactical simplicity, allow beginners and professionals to focus on insights and innovation.

#python3 #variables-in-python #data-types-in-python #operators-in-python #python #python i: data types and operators, variable assignment, and print()