Kubernetes-Operatoren – worum handelt es sich genau, warum sind sie wichtig und wie werden sie erstellt?

Warum und wie Sie Ihren eigenen Kubernetes-Operator erstellen

DevOpsUPDATED ON November 12, 2021

John Adam K&C head of marketing

Author

kubernetes operator

In diesem Beitrag unserer Reihe „Kubernetes Beratung“ konzentrieren wir uns auf Operatoren.

Bei Kubernetes-Operatoren handelt es sich weder um einen talentierten Ops-Spezialisten noch um ein Team, sondern um ein automatisiertes Operator-Framework, das auf Kubernetes (oder OpenShift) verwendet werden kann. Das Operator-Framework wurde im Jahre 2016 von CoreOS, jetzt Teil von RedHat und ab 2019 von IBM, eingeführt. Das Operators-Framework bietet eine hervorragende Gelegenheit, komplexe Kubernetes-Vorgänge zu verwalten. Hierdurch ist es bereits jetzt zu einem beliebten und zentralen Element von Cloud-nativen DevOps-Architekturen geworden.

K&C – WIR KREIEREN EINZIGARTIGE TECH-LÖSUNGEN SEIT ÜBER 20 JAHREN. WIR VERSCHAFFEN IHNEN IHREN WETTBEWERBSVORTEIL!

Schreiben Sie uns eine Nachricht, um Ihre individuellen Bedürfnisse oder das nächste Projekt zu besprechen.

In diesem Artikel erklären wir die Rolle, die Operatoren in einer skalierbaren und auf Kubernetes basierenden Anwendungsarchitektur spielen und warum sie zu einem so wichtigen Bestandteil der DevOps-Automatisierung geworden sind. Ein Großteil in diesem Beitrag wurde von IBMs großartigem Video zu Kubernetes-Operatoren inspiriert:

Im Folgenden eine schrittweise Anleitung zur Erstellung eines Operators mit Operator SDK und Ansible.

Was ist der Kubernetes Control Loop?

Als Kernbestandteil des Operator-Frameworks ist es sinnvoll, zunächst den Kubernetes Control Loop zu erläutern. Der K8 Control Loop überwacht („Observe“) den Status eines Clusters. Als Nächstes vergleicht Kubernetes den tatsächlichen mit dem gewünschten Status eines Clusters. Dieser Vergleichsprozess wird auch als „Diff“ bezeichnet.

Die letzte Phase eines Kubernetes Control Loops besteht darin, etwaige Diffs zu lösen, indem man auf diese einwirkt. Diese Phase des Control Loops wird daher auch als „Act“ bezeichnet.

The Kubernetes Control Loop

Der Conrol Loop spiegelt den Kern der Funktionsweise von Kubernetes wider. Hierzu gibt es einen Controller, der auf den Loop für jede Standardressource, mit der Kubernetes geliefert wird, einwirkt.

Die Softwareverteilung einer Kubernetes-Anwendung ohne Operatoren

Als Endnutzer besteht der erste Schritt darin, die ein oder andere YAML zu schreiben – die Spezifikation für die Anwendung. Beispielsweise kann eine Softwareverteilung durchgeführt werden, bei der einige Konfigurationen wie folgt definiert werden:

  1. Was ist das Image?
  2. Replika
  3. Andere Konfigurationen

Nun haben wir eine Kubernetes-Ressource, die im Cluster bereitgestellt werden soll. Der Control Loop wird jetzt aktiviert und überprüft den Unterschied zwischen dem, was im Cluster vorgegeben wird und dem tatsächlichen Status. Kubernetes wird beispielsweise feststellen, dass es keine Pods gibt. Es wird dann auf diese Diff einwirken und Pods erstellen.

Eine komplexere Anwendung kann mehr als nur eine YAML haben. Es könnte eine zweite für das Backend geben. Dies wird ebenfalls in einem Cluster bereitgestellt, wobei anschließend ein Pod mithilfe der Controller und des Control Loops bereitgestellt wird.

Wenn wir nun die Anwendung skalieren, einige Änderungen vornehmen, Secrets und Umgebungsvariablen usw. hinzufügen möchten, müssen wir entweder jedes Mal neue Kubernetes-Ressourcen einrichten oder die vorhandenen bearbeiten. Dieser Vorgang kann zeitaufwändig werden.

Die Softwareverteilung einer Kubernetes-Anwendung mit Operatoren

Wie würden wir dieselbe Anwendung mit einem Operator bereitstellen? Der erste Schritt ist die Installation des Operators selbst. Das bedeutet natürlich, dass Sie einen Operator benötigen, der genau die von Ihnen gewünschte Arbeit erledigt. Sie können entweder einen Kubernetes-Operator von jemandem erstellen lassen beziehungsweise dies selbst erledigen, wenn Sie über den entsprechenden technischen Hintergrund verfügen oder Sie können einfach eine geeignete Option in der wachsenden Bibliothek finden, die auf OperatorHub zur Verfügung steht.

Das Erste, was jetzt im Kubernetes-Cluster benötigt wird, ist der Operator Lifecycle Manager (OLM). Das OLM verwaltet die installierten Operatoren. Als Nächstes wird der Operator im Cluster bereitgestellt.

Der Operator

Ein Kubernetes-Operator besteht aus zwei Hauptkomponenten:

  1. CRD
  2. Controller

Die CRD (Custom Resource Definition) wird im Gegensatz zu Standard-Kubernetes-Ressourcen wie Bereitstellungen und Pods entweder vom Benutzer oder vom Operator definiert, sodass YAML entgegen den benutzerdefinierten Konfiguration arbeiten kann.

Der Controller ist ein benutzerdefinierter Kubernetes Control Loop, der als Pod im Cluster und als Control Loop entlang der CRD operiert.

Was wäre der Unterschied, wenn der Operator für dieselbe benutzerdefinierte Bereitstellung der Anwendung wie im ersten Beispiel ohne Operator erstellt würde? Anstelle mehrerer Bereitstellungen, Konfigurationszuordnungen, Secrets usw. schreiben zu müssen, muss nur eine YAML bereitgestellt werden.

Benutzerdefinierte Konfigurationen können dem Operator zugewiesen werden oder die Standardeinstellungen verwenden. Der Operator wird dann direkt im Cluster bereitgestellt. Der Operator ist dafür verantwortlich, den Kubernetes Control Loop zu durchlaufen und herauszufinden, was ausgeführt werden muss.

Der Operator würde beispielsweise feststellen, dass einige Bereitstellungen und Pods erforderlich sind, wenn unsere Anwendung mit der Anwendung identisch ist, die im ersten Beispiel ohne Kubernetes-Controller bereitgestellt wurde.

Warum sollte man Kubernetes-Operatoren verwenden?

Kubernetes-Operatoren liefern den Ansatz zur Verwaltung komplexer Anwendungen, der von Natur aus skalierbarer (und einfacher) sind als die Bereitstellung von Kubernetes-Clustern ohne Operator. Der Endnutzer muss sich somit nur um die Konfiguration kümmern, die ihm zur Verfügung gestellt wurde. Der Operator verwaltet den Control Loop sowie den Status der Anwendung.

Operatoren können zur Automatisierung einer Vielzahl von Prozessen beitragen. Nach der Bereitstellung einer Konfigurationsdatei können wir beispielsweise eine konfigurierte Umgebung oder einen konfigurierten Dienst wie Cache (Redis, Memchace), Proxy (NGNX, HAProxy), Datenbanken (MySQL), etc., in nur wenigen Sekunden erhalten.

Beliebte Kubernetes-Operatoren

Schauen Sie sich diesen spannenden Twitter-Beitrag über empfehlenswerte K8s-Operatoren an:

So erstellen Sie Ihre eigenen Operatoren

Es gibt heutzutage viele fantastische Operatoren, wie den Prometheus-Operator für den nativen Einsatz von Kubernetes und die Verwaltung von Prometheus sowie den dazugehörigen Überwachungskomponenten. In unserem Blog-Eintrag über die Einrichtung des Prometheus-Operators zur Kubernetes-Überwachung findet sich alles Wissenswerte rund um das Thema.

Bevor Sie jedoch gleich über die benutzerdefinierte Erstellung eines Operators nachdenken, ist es immer sinnvoll, vorab zu prüfen, was bereits vorhanden ist. Wie bereits erwähnt, ist OperatorHub eine großartige Ressource, in der die Kubernetes-Community eine Vielzahl von Operatoren teilt.

Was aber, wenn wir einen benutzerdefinierten Operator für etwas entwickeln möchten, das für eine bestimmte Anwendungsarchitektur typisch ist? Dafür gibt es verschiedene Möglichkeiten.

Operator SDK

Mit dem Operator SDK können wir selbst mit dem Aufbau von Operatoren beginnen. Der einfachste Weg, um mit einem Operator zu beginnen, ist die Verwendung des Helm-Operators.

Der Helm-Ansatz

Der Helm-Ansatz ermöglicht es uns, ein Helm-Diagramm zu erstellen und dieses auf einen Operator anzuwenden. Dies kommt einem ausgereiften Operatoren für ein bereits vorhandenes Diagramm am nächsten. Wenn Sie mit Helm nicht besonders vertraut sind, könnte Sie unser Blog-Beitrag interessieren, in dem alles Wissenswerte rund um den Beitrag von Helm zu einer Kubernetes-Architektur behandelt wird.

Reifegrad des Operators

Die Betreiberreife eines Operators lässt sich in fünf Stufen unterteilen:

  • Basisinstallation: Ermöglicht die Bereitstellung der erforderlichen Ressourcen.
  • Upgrades: Unterstützt kleinere und gepatchte Upgrades auf alles, was im Operator definiert ist.
  • Voller Lebenszyklus: Storage-Lebenszyklus, App-Lebenszyklus, Backup und Fehlerbehebung.
  • Einblicke: Metriken, Analyse, Protokollierung, u.v.m.
  • Autopilot: Automatisierte horizontale und vertikale Skalierung, Config. Tuning, Act auf Diffs.

Operator-Reifegrade

Operator-Reifegrade (Quelle)

Helm selbst erreicht die ersten beiden Reifegrade.

Für Operatoren, die die Reifegrade 3-5 erreichen, sind Go und Ansible die beliebtesten Technologien. Mit dem Operator SDK können wir Operatoren mit Helm, Go, Ansible und anderen Technologien erstellen. Vielleicht interessiert Sie auch unser Ansible-Tutorial, das Sie Schritt für Schritt durch die Installation und Einrichtung dieses unglaublich nützlichen Open-Source-Tools von RedHat führt.

Eine Schritt-für-Schritt-Anleitung zur Erstellung eines Kubernetes-Operators mit Operator SDK und Ansible

Der Operator, den wir im folgenden Beispiel mit Operator SDK und Ansible erstellen werden, führt zwei Kernfunktionen aus:

  • Erstellung eines Namespace mit Limit Ranges und Resource Quota
  • Erstellung einer Deployment-Nginx im Namespace

In diesem Abschnitt werden wir uns nicht auf den eigentlichen Installationsprozess konzentrieren. Eine schrittweise Anleitung zur Installation des Kubernetes Operator SDK finden Sie bei GitHub. Hier konzentrieren wir uns auf den Prozess, der zum Schreiben eines Operators benötigt wird.

Schritt 1 – Erstellung eines neuen Projekts

Wir müssen zuerst ein neues Projekt erstellen, was wir über die CLI (Befehlszeilenschnittstelle) machen:

operator-sdk new my-first-operator --api-version=krusche.io/v1alpha1 --kind=/v1alpha1 --kind=ResourcesAndLimits --type=ansible
cd my-first-operator

Dieser Befehl erstellt ein Projekt mit dem Operator, der sich mit der APIVersion krusche.io/v1alpha1 und Kind ResourcesAndLimits bei ResourcesAndLimits anmeldet.

Das Verzeichnis sollte folgendermaßen strukturiert werden:

Directory/File Goal

build/ – Enthält Skripte, mit denen das Operator-SDK zusammengestellt und initialisiert wird

deploy/ – Enthält eine Reihe von Kubernetes-Manifesten, mit denen der Operator im Cluster bereitgestellt wird

roles/ – Enthält Ansible-Roles

watch.yaml – Enthält Group, Version, Kind und Methode zum Starten von Ansible

Die Datei watches enthält:

  • group: Die Gruppe in Custom Resource, bei der sich unser Operator anmeldet.
  • version: Die Version der Custom Resource, bei der sich unser Operator anmeldet.
  • kind: Die Art der Custom Resource, bei der sich unser Operator anmeldet.
  • role (Standard): Der Pfad zu unseren Ansible-Roles.
  • playbook: Der Pfad zum Ansible-Playbook. Immer dann erforderlich, wenn wir anstelle einer Role ein Playbook verwenden.
  • vars: Beschrieben in Form eines Key-Value. Wird als extra_vars übergeben
  • reconcilePeriod (optional): Das Verhandlungsintervall, das definiert, wie oft die Role für diese CR ausgeführt wird.
  • manageStatus (optional): Wenn der Wert auf true (Standard) gesetzt ist, verwaltet der Operator den Status von CR. Wenn der Wert auf false gesetzt ist, wird der Status von CR mithilfe der angegebenen Role / des angegebenen Playbooks eines separaten Controllers an anderer Stelle verwaltet.

Hier ist ein Beispiel für die Datei Watches:

---
- version: v1alpha1
  group: foo.example.com
  kind: Foo
  role: /opt/ansible/roles/Foo
 
- version: v1alpha1
  group: bar.example.com
  kind: Bar
  playbook: /opt/ansible/playbook.yml
 
- version: v1alpha1
  group: baz.example.com
  kind: Baz
  playbook: /opt/ansible/baz.yml
  reconcilePeriod: 0
  manageStatus: false
  vars:
    foo: bar

Vorbereitung und Installation eines Operators in einem Kubernetes-Cluster

Da unser Operator Namespaces erstellt, benötigt er die Rechte für ein Cluster, nicht nur für einen Namespace.

In der Datei deploy/role:

  • Kind: Role zu Kind: ClusterRole ändern
apiVersion: rbac.authorization.k8s.io/v1
#kind: Role
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: my-first-operator

Außerdem müssen Namespaces, Resourcequotas, Limitranges zu Resources und apiGroups: «» zu Rules hinzugefügt werden.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: null
  name: my-first-operator
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - services
  - services/finalizers
  - endpoints
  - persistentvolumeclaims
  - events
  - configmaps
  - secrets
  - namespaces
  - resourcequotas
  - limitranges

In der Datei deploy/role_binding.yaml müssen Sie die folgenden Änderungen vornehmen:

  • RoleBinding für ClusterRoleBinding
  • Role für ClusterRole im Abschnitt roleRef
  • Geben Sie den Namespace an, in dem der Operator erweitert wird
#kind: RoleBinding
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: my-first-operator
subjects:
- kind: ServiceAccount
  name: my-first-operator
  namespace: default
roleRef:
  #kind: Role
  kind: ClusterRole
  name: my-first-operator
  apiGroup: rbac.authorization.k8s.io

In der Datei deploy/operator.yaml müssen Sie die folgende Änderung anwenden:

  • WATCH_NAMESPACE=””
env:
  - name: WATCH_NAMESPACE
    value: ""
    #valueFrom:
    #  fieldRef:
    #    fieldPath: metadata.namespace

In roles/resourcesandlimits/tasks/main.yml ändern wir alles zu:

---
# tasks file for resourcesandlimits
- name: Create namespace
  k8s:
    definition:
      kind: Namespace
      apiVersion: v1
      metadata:
        name: '{{ meta.name }}'
  ignore_errors: true
 
 
- name: Create Resource Quota
  k8s:
    definition: 
      kind: ResourceQuota
      apiVersion: v1
      metadata: 
        name: '{{ meta.name }}-resourcequota'
        namespace: '{{ meta.name }}'
      spec:
        hard:
          limits.cpu: "{{ limits_cpu }}"
          limits.memory: "{{ limits_memory }}"
          requests.cpu: "{{ requests_cpu }}"
          requests.memory: "{{ requests_memory }}"
          requests.storage: "{{ requests_storage }}"
          pods: "{{ limit_pods }}"
          services: "{{ limit_services }}"
          services.loadbalancers: 0
          services.nodeports: 0
          replicationcontrollers: 0
 
- name: Create Limit Ranges
  k8s:
    definition: 
      kind: LimitRange
      apiVersion: v1
      metadata: 
        name: '{{ meta.name }}-limitrange'
        namespace: '{{ meta.name }}'
      spec:
        limits:
        - type: Pod
          maxLimitRequestRatio:
            cpu: "{{ max_limit_request_ratio_cpu }}"
            memory: "{{ max_limit_request_ratio_memmory }}"
        - type: PersistentVolumeClaim
          max:
            storage: "{{ max_storage }}"
          min:
            storage: "{{ min_storage }}"

In der Datei deploy/crds/krusche.io_v1alpha1_resourcesandlimits_cr.yaml ändern wir ebenfalls alles zu:

apiVersion: krusche.io/v1alpha1
kind: ResourcesAndLimits
metadata:
  name: developers-team-a
spec:
  limitsCpu: 5
  limitsMemory: 5Gi
  requestsCpu: 5
  requestsMemory: 5Gi
  requestsStorage: 204Gi
  limitPods: 10
  limitServices: 10
  maxLimitRequestRatioCpu: 2
  maxLimitRequestRatioMemmory: 2
  maxStorage: 100Gi
  minStorage: 20Gi

Das gilt es zu beachten:

Variablen von CR:

  • Im Metadatenabschnitt: name, namespace werden zu Ansible als «{{ meta.name }}», «{{ meta.namespace }}» übertragen
  • In der Spec-Section: somevar ohne Großbuchstaben wird als «{{somevar}}» an Ansible übertragen, mit Großbuchstaben wird es als «{{some_var}}» übertragen

Im nächsten Schritt stellen wir die CRD bereit:

kubectl create -f deploy/crds/krusche.io_resourcesandlimits_crd.yaml

Erstellen Sie den Operator und schreiben Sie Folgendes in die Registry:

operator-sdk build example/my-first-operator:0.0.1
docker push example/my-first-operator:0.0.1

Der nächste Schritt besteht darin, Docker-Image und imagePullPolicy in deploy/operator.yaml zu ändern:

sed -i 's|{{ REPLACE_IMAGE }}|example/my-first-operator:0.0.1|g' deploy/operator.yaml
sed -i 's|{{ pull_policy\|default('\''Always'\'') }}|Always|g' deploy/operator.yaml

Für macOS:

sed -i "" 's|{{ REPLACE_IMAGE }}|example/my-first-operator:0.0.1|g' deploy/operator.yaml
sed -i "" 's|{{ pull_policy\|default('\''Always'\'') }}|Always|g' deploy/operator.yaml

Der nächste Schritt sieht wie folgt aus:

kubectl create -f deploy/service_account.yaml
kubectl create -f deploy/role.yaml
kubectl create -f deploy/role_binding.yaml
kubectl create -f deploy/operator.yaml

 Bereitstellung von Controllern

Nach dem erfolgreichen Start des Operators müssen wir unsere CR bereitstellen, um einen Namespace zu erstellen:

kubectl apply -f deploy/crds/krusche.io_v1alpha1_resourcesandlimits_cr.yaml

Schauen wir uns hierzu unseren CF etwas genauer an:

kubectl describe resourcesandlimits.krusche.io developers-team-a
Name:         developers-team-a
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"krusche.io/v1alpha1","kind":"ResourcesAndLimits","metadata":{"annotations":{},"name":"developers-team-a","namespace":"de...
API Version:  krusche.io/v1alpha1
Kind:         ResourcesAndLimits
Metadata:
  Creation Timestamp:  2019-12-17T11:53:34Z
  Generation:          1
  Resource Version:    20309
  Self Link:           /apis/krusche.io/v1alpha1/namespaces/default/resourcesandlimits/developers-team-a
  UID:                 0db952fb-2bed-4511-9309-9f9fbe11af66
Spec:
  Limit Pods:                       10
  Limit Services:                   10
  Limits Cpu:                       5
  Limits Memory:                    5Gi
  Max Limit Request Ratio Cpu:      2
  Max Limit Request Ratio Memmory:  2
  Max Storage:                      100Gi
  Min Storage:                      20Gi
  Requests Cpu:                     5
  Requests Memory:                  5Gi
  Requests Storage:                 204Gi
Status:
  Conditions:
    Ansible Result:
      Changed:             2
      Completion:          2019-12-17T11:55:50.36218
      Failures:            0
      Ok:                  4
      Skipped:             0
    Last Transition Time:  2019-12-17T11:53:34Z
    Message:               Awaiting next reconciliation
    Reason:                Successful
    Status:                True
    Type:                  Running
Events:                    <none>

Unser Operator sollte den Namespace developers-team-a erstellen:

kubectl get namespaces

Wir können sehen, dass unser Namespace erscheint:

NAME                STATUS   AGE
default             Active   3h16m
developers-team-a   Active   5m46s
kube-node-lease     Active   3h16m
kube-public         Active   3h16m
kube-system         Active   3h16m

Als Nächstes werfen wir einen Blick auf die Einstellungen des Namespace:

kubectl describe namespaces developers-team-a

Wir können sehen, dass die Einstellungen umgesetzt wurden:

Name:         developers-team-a
Labels:       <none>
Annotations:  cattle.io/status:
                {"Conditions":[{"Type":"ResourceQuotaInit","Status":"True","Message":"","LastUpdateTime":"2019-12-17T11:53:43Z"},{"Type":"InitialRolesPopu...
              lifecycle.cattle.io/create.namespace-auth: true
              operator-sdk/primary-resource: default/developers-team-a
              operator-sdk/primary-resource-type: ResourcesAndLimits.krusche.io
Status:       Active
 
Resource Quotas
 Name:                   developers-team-a-resourcequota
 Resource                Used  Hard
 --------                ---   ---
 limits.cpu              0     5
 limits.memory           0     5Gi
 pods                    0     10
 replicationcontrollers  0     0
 requests.cpu            0     5
 requests.memory         0     5Gi
 requests.storage        0     204Gi
 services                0     10
 services.loadbalancers  0     0
 services.nodeports      0     0
 
Resource Limits
 Type                   Resource  Min   Max    Default Request  Default Limit  Max Limit/Request Ratio
 ----                   --------  ---   ---    ---------------  -------------  -----------------------
 Pod                    cpu       -     -      -                -              2
 Pod                    memory    -     -      -                -              2
 PersistentVolumeClaim  storage   20Gi  100Gi  -                -

Nun widmen wir uns einem weiteren Controller und fügen deployment Nginx zum Namespace hinzu.

Erstellung von deploy / crds / nginx_cr.yaml:

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: nginx.krusche.io
spec:
  group: krusche.io
  names:
    kind: Nginx
    listKind: NginxList
    plural: nginx
    singular: nginx
  scope: Namespaced
  subresources:
    status: {}
  validation:
    openAPIV3Schema:
      type: object
      x-kubernetes-preserve-unknown-fields: true
  versions:
  - name: v1alpha1
    served: true
    storage: true

Und deploy/crds/nginx-1.17.6.yaml:

apiVersion: krusche.io/v1alpha1
kind: Nginx
metadata:
  name: nginx-1-17-6
  namespace: nginx-namespace
spec:
  size: 5
  version: 1.17.6

Die folgenden Zeilen werden der watches.yml-Datei hinzugefügt:

- version: v1alpha1
  group: krusche.io
  kind: Nginx
  role: /opt/ansible/roles/nginx

Kopieren Sie das resourcesandlimits Directory und nennen Sie es um in Nginx:

cp -R roles/resourcesandlimits roles/nginx

Ändern Sie die Inhalte von roles/nginx/tasks/main.yml file zu:

---
- name: start nginx
  k8s:
    definition:
      kind: Deployment
      apiVersion: apps/v1
      metadata:
        name: '{{ meta.name }}-nginx'
        namespace: '{{ meta.namespace }}'
      spec:
        replicas: "{{size}}"
        selector:
          matchLabels:
            app: nginx
            version: "nginx-{{version}}"
        template:
          metadata:
            labels:
              app: nginx
              version: "nginx-{{version}}"
          spec:
            containers:
            - name: nginx
              image: "nginx:{{version}}"
              ports:
                - containerPort: 80

Als Nächstes müssen wir den Operator mit der neuen Version des Docker-Images erstellen:

operator-sdk build example/my-first-operator:0.0.2
docker push example/my-first-operator:0.0.2

Ändern Sie das Docker-Image in deploy/operator.yaml:

sed -i 's|example/my-first-operator:0.0.1|example/my-first-operator:0.0.2|g' deploy/operator.yaml

Für macOS:

sed -i "" 's|example/my-first-operator:0.0.1|example/my-first-operator:0.0.2|g' deploy/operator.yaml

CR hinzufügen:

kubectl apply -f deploy/crds/nginx_cr.yaml

Operator updaten:

kubectl apply -f deploy/operator.yaml

Namespace erstellen und unsere CR bereitstellen:

kubectl create namespace nginx-namespace
kubectl apply -f deploy/crds/nginx-1.17.6.yaml

Nun können wir alles prüfen:

kubectl -n nginx-namespace get pod
NAME                                     READY   STATUS    RESTARTS   AGE
kc-nginx-1-17-6-nginx-859d7dcf99-ddbzm   1/1     Running   0          24s
kc-nginx-1-17-6-nginx-859d7dcf99-j884q   1/1     Running   0          24s
kc-nginx-1-17-6-nginx-859d7dcf99-mvj5s   1/1     Running   0          24s
kc-nginx-1-17-6-nginx-859d7dcf99-wpcfj   1/1     Running   0          24s
kc-nginx-1-17-6-nginx-859d7dcf99-x7szg   1/1     Running   0          53s

Glückwunsch! Sie haben soeben Ihren eigenen Kubernetes-Operator erstellt.

Kubernetes-Operator – ein Fazit

Der von uns erstellte Operator übernimmt die K8-Ressourcen über die Kubernetes-API und automatisiert deren Verwaltung, ohne dass manuelle Eingriffe erforderlich sind. Letztendlich helfen Ihnen die Kubernetes-Operatoren bei der Automatisierung von manuellen Routinearbeiten und sollten daher so oft es geht genutzt werden,

Welcher Tech-Stack wurde verwendet? Alles, was wir zum Aufbau unseres Operators benötigt haben, waren das Operator SDK Framework sowie Ansible.

Wann gelingt IT Outsourcing?

(und wann nicht?)