File: write-an-operator.rst

package info (click to toggle)
python-pykube-ng 22.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 424 kB
  • sloc: python: 2,336; makefile: 44
file content (152 lines) | stat: -rw-r--r-- 4,063 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
How to write an Operator
========================

Pykube can be used to implement Kubernetes Operators. Here is how to write a very simple operator which adds a label ``foo`` with value ``bar`` to every deployment object which has the ``pykube-test-operator`` annotation:

.. code-block:: python

    # simplified example script, no error handling!
    import pykube, time

    while True:
        # loads in-cluster auth or local ~/.kube/config for testing
        config = pykube.KubeConfig.from_env()
        api = pykube.HTTPClient(config)
        for deploy in pykube.Deployment.objects(api, namespace=pykube.all):
            if 'pykube-test-operator' in deploy.annotations:
                print(f'Updating deployment {deploy.namespace}/{deploy.name}..')
                deploy.labels['foo'] = 'bar'
                deploy.update()
        time.sleep(15)

Save the above Python script as ``main.py``.

Testing
-------

You can now test the script locally with Pipenv_ and Minikube_ (run ``minikube start`` first):

.. code-block:: bash

    pipenv install pykube-ng
    pipenv run python3 main.py

See the operator in action by creating a deployment with the right annotation:

.. code-block:: bash

    kubectl run nginx --image=nginx
    kubectl annotate deploy nginx pykube-test-operator=true

The operator should should now assign the ``foo`` label to the ``nginx`` deployment.

Building the Docker image
-------------------------

Create a ``Dockerfile`` in the same directory as ``main.py``:

.. code-block:: Dockerfile

    FROM python:3.7-alpine3.10

    WORKDIR /

    RUN pip3 install pykube-ng

    COPY main.py /

    ENTRYPOINT ["python3", "main.py"]

Now build it:

.. code-block:: bash

    docker build -t pykube-test-operator .

You need to push the Docker image to some Docker registry before you can deploy it.


Deployment
----------

Now deploy the Docker image to your Kubernetes cluster using a service account with the necessary permissions (in this case to list and update deployments).
To create such an service account with the necessary RBAC rights create ``rbac.yaml`` with these contents:

.. code-block:: yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: pykube-test-operator
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: pykube-test-operator
    rules:
    - apiGroups:
      - apps
      resources:
      - deployments
      verbs:
      - get
      - watch
      - list
      - update
      - patch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: pykube-test-operator
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: pykube-test-operator
    subjects:
    - kind: ServiceAccount
      name: pykube-test-operator
      namespace: default

Apply the RBAC role via ``kubectl apply -f rbac.yaml``.

Finally, the deployment of the operator would then look like (``deployment.yaml``):

.. code-block:: yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pykube-test-operator
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: pykube-test-operator
      template:
        metadata:
          labels:
            app: pykube-test-operator
        spec:
          serviceAccountName: pykube-test-operator
          containers:
          - name: operator
            # this image needs have been pushed to some Docker registry!
            image: pykube-test-operator
            resources:
              limits:
                memory: 50Mi
              requests:
                cpu: 5m
                memory: 50Mi
            securityContext:
              readOnlyRootFilesystem: true
              runAsNonRoot: true
              runAsUser: 1000

Create the deployment via ``kubectl apply -f deployment.yaml``.

You should now have a working operator deployment in your cluster.

.. _Pipenv: https://pipenv.readthedocs.io/en/latest/
.. _Minikube: https://github.com/kubernetes/minikube