Wir werden sehen, wie in
Ansible Galaxy veröffentlichte Rollen als Operatoren verwendet werden, die Anwendungen in Kubernetes verwalten, und wie wir einen Operator erstellen, der die Anwendung einfach installiert und ihr Verhalten je nach Umgebung flexibel anpasst.

Wir werden
Ansible Operator und das
k8s-Modul verwenden, um zu zeigen, wie Ansible zum Erstellen von Kubernetes-Anwendungen verwendet wird.
Ansible Operator ist Teil des
Operator SDK und ermöglicht es Ihnen, die Betriebsvorschriften der Anwendung (wie sie installiert und gewartet werden sollte) in der Sprache der Ansible-Rollen und Playbooks zu formulieren. Das k8s-Modul erweitert wiederum die Möglichkeit, Objekte in Kubernetes zu verwalten, wenn solche Rollen und Playbooks erstellt werden.
Ein Operator wird einfach so erstellt.
FROM quay.io/operator-framework/ansible-operator RUN ansible-galaxy install djzager.hello_world_k8s RUN echo $'--- \n\ - version: v1alpha1\n\ group: examples.djzager.io\n\ kind: HelloWorld\n\ role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml
Starttaste
Zunächst ein
paar Worte
zum k8s Ansible-Modul . Es erschien in Ansible 2.6 und erweitert die Möglichkeiten der Arbeit mit Kubernetes-Objekten von Ansible und in allen Kubernetes-Distributionen, einschließlich Red Hat OpenShift. Ansible Blog hatte einen
separaten Beitrag über dieses Modul und den
dynamischen Python-Client für Red Hat OpenShift . Unserer Meinung nach ist die Arbeit mit Kubernetes-Objekten über Ansible ohne Verwendung des k8s-Moduls falsch. Der Operatormechanismus wurde ursprünglich zum Ausführen von Anwendungen in Kubernetes erstellt. Das Operator SDK bietet Tools zum Zusammenstellen, Testen und Verpacken von Operatoren. Ansible Operator wird wiederum benötigt, um die Betriebsvorschriften der Anwendung in Ansible-Sprache festzulegen. Der entsprechende Workflow ist ganz einfach organisiert: Zuerst führen wir operator-sdk new --type = Ansible aus, um die erforderlichen Dateien für den Ansible-Operator zu generieren, dann zeichnen wir Ansible und schließlich erstellen wir operator-sdk, um die Anwendung für die Arbeit in Kubernetes zu erstellen. Wenn wir jedoch bereits eine Rolle in Ansible Galaxy haben, das die Anwendung in Kubernetes steuert, wird es noch einfacher. Im Folgenden werden wir Folgendes tun:
- Lassen Sie uns eine Ansible-Rolle zum Verwalten der Hello World-Anwendung in Kubernetes erstellen, mit deren Hilfe wir die Funktionen des Ansible-Moduls von k8s demonstrieren können.
- Wir werden diese Rolle in Ansible Galaxy veröffentlichen.
Stellen wir also den Ansible-Operator mithilfe der in Ansible Galaxy veröffentlichten Rolle zusammen. Warum überhaupt einen Operator mit einer Rolle von Ansible Galaxy erstellen? Es gibt zwei Gründe:
- Um nicht zu wiederholen . Wenn wir die Ansible-Rolle für die Verwaltung der Hello World-Anwendung bereits programmiert und in Ansible Galaxy veröffentlicht haben, ist es logisch, sie beim Erstellen des Ansible-Operators zu verwenden.
- Aufgrund der Aufgabentrennung . Wir möchten, dass die Hello World Ansible-Rolle die gleichnamige Anwendung in Kubernetes verwaltet und die betriebliche Logik im Bediener verbleibt. In unserem Beispiel ist die Betriebslogik äußerst einfach: Sie ruft einfach jedes Mal die Rolle djzager.hello_world_k8s auf, wenn Sie eine benutzerdefinierte HelloWorld-Ressource erstellen oder ändern. In Zukunft wird diese Trennung jedoch an Bedeutung gewinnen. Beispielsweise werden wir der Hello World-Anwendung über die Rolle Ansible eine Validierung hinzufügen und die Statussteuerung der benutzerdefinierten HelloWorld-Ressourcen über die Operatorlogik implementieren.
Hallo Kubernetes, treffe Ansible
Was brauchen wir?
- Ansible - Lesen Sie die Installationsanleitung, wenn Sie Ansible nicht installiert haben.
- Python-Client für OpenShift (optional). Wird nur für den lokalen Start benötigt. Installationsanweisungen finden Sie hier .
Fangen wir an. Erstellen Sie zunächst ein Rollenskelett mithilfe der Ansible-Galaxie:
# I like clear names on projects. # In meta/main.yml I will make role_name: hello-world-k8s $ ansible-galaxy init ansible-role-hello-world-k8s
Unmittelbar nach dem Erstellen einer neuen Ansible-Rolle setzen wir alle Standardwerte so, dass gleichzeitig die gültigen Konfigurationsparameter dokumentiert werden. Darüber hinaus ist unser Hello World-Beispiel in dieser Hinsicht nicht besonders kompliziert. So sieht unsere Datei defaults / main.yml aus:
--- # NOTE: meta.name(space) comes from CR metadata when run with Ansible Operator # deploy/crds has an example CR for reference name: "{{ meta.name | default('hello-world') }}" namespace: "{{ meta.namespace | default('hello-world') }}" image: docker.io/ansibleplaybookbundle/hello-world:latest # To uninstall from the cluster # state: absent state: present # The size of the hello-world deployment size: 1
Nachdem Sie die Standardwerte festgelegt haben, müssen Sie entscheiden, was die Rolle tun soll. Die Hello World-Anwendung muss Folgendes tun:
- Informationen zu den verfügbaren APIs im Cluster abrufen.
- Erstellen Sie mehrere Vorlagen und stellen Sie sicher, dass sie im Cluster vorhanden sind oder nicht.
Daher sieht unsere Dateiasks / main.yml folgendermaßen aus:
--- - name: "Get information about the cluster" set_fact: api_groups: "{{ lookup('k8s', cluster_info='api_groups') }}" - name: 'Set hello-world objects state={{ state }}' k8s: state: '{{ state }}' definition: "{{ lookup('template', item.name) | from_yaml }}" when: item.api_exists | default(True) loop: - name: deployment.yml.j2 - name: service.yml.j2 - name: route.yml.j2 api_exists: "{{ True if 'route.openshift.io' in api_groups else False }}"
Beachten Sie diese Zeile in der Aufgabendatei, bevor Sie mit den Vorlagen fortfahren:
api_exists: "{{ True if 'route.openshift.io' in api_groups else False }}"
Mit set_fact erhalten wir eine Liste aller im Cluster verfügbaren APIs, sodass wir selektiv Vorlagen generieren können, je nachdem, ob die API vorhanden ist - in diesem Fall route.openshift.io. Standardmäßig sind im Kubernetes-Cluster von OpenShift keine Routen verfügbar und werden nicht benötigt. Daher arbeiten wir nur mit dem Route-Objekt, wenn sich route.openshift.io im Cluster befindet.
Wir können nicht nur Objekte im Cluster abhängig von der Verfügbarkeit bestimmter APIs selektiv verwalten, sondern auch die Jinja2-Vorlagen verwenden, um die OpenShift DeploymentConfig in unserer Deployment-Vorlage zu verwenden, wenn der Cluster über die API apps.openshift.io verfügt. So sieht unsere Datei templates / deploy.yml.j2 aus:
--- {% if 'apps.openshift.io' in api_groups %} apiVersion: apps.openshift.io/v1 kind: DeploymentConfig {% else %} apiVersion: apps/v1 kind: Deployment {% endif %} metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: replicas: {{ size }} {% if 'apps.openshift.io' in api_groups %} selector: app: {{ name }} service: {{ name }} {% else %} selector: matchLabels: app: {{ name }} service: {{ name }} {% endif %} template: metadata: labels: app: {{ name }} service: {{ name }} spec: containers: - image: {{ image }} name: hello-world ports: - containerPort: 8080 protocol: TCP
Dateivorlagen / service.yml.j2:
--- apiVersion: v1 kind: Service metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: ports: - name: web port: 8080 protocol: TCP targetPort: 8080 selector: app: {{ name }} service: {{ name }}
Und schließlich die Datei templates / route.yml.j2:
--- apiVersion: route.openshift.io/v1 kind: Route metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: port: targetPort: web to: kind: Service name: {{ name }}
Wir haben die Datei meta / main.yml weggelassen, aber sie finden Sie
hier .
Infolgedessen haben wir die Ansible-Rolle, die die Hello World-Anwendung in Kubernetes verwaltet, und wir können die im Cluster verfügbaren APIs verwenden. Mit anderen Worten, das k8s-Modul und der dynamische Client vereinfachen die Arbeit mit Objekten in Kubernetes. Wir hoffen, dass wir am Beispiel dieser Rolle das Potenzial von Ansible bei der Arbeit mit Kubernetes zeigen konnten.
Hallo Galaxy, treffe Kubernetes
Ansible Galaxy hat viele Rollen zum Einrichten von Servern und zum Verwalten von Anwendungen, aber es gibt nicht so viele Rollen zum Verwalten von Kubernetes-Anwendungen, daher werden wir einen kleinen Beitrag leisten.
Nachdem wir unsere Rolle auf
GitHub veröffentlicht hatten, war nur noch
Folgendes übrig:
- Melden Sie sich bei Ansible Galaxy an, um Zugriff auf unsere Repositories auf GitHub zu erhalten.
- Importieren Sie unsere Rolle.
Das war's, jetzt ist unsere Rolle hello_world_k8s
hier in Ansible Galaxy öffentlich verfügbar.
Hallo Ansible Operator, treffe Galaxy
Wenn Sie unser
Hello World-Projekt auf GitHub sorgfältig studieren, werden Sie feststellen, dass wir dort einige Dinge hinzugefügt haben, die zum Erstellen eines Ansible-Operators erforderlich sind, nämlich:
- Eine Watches-Datei , die benutzerdefinierte Ressourcen von Kubernetes Ansible-Rollen oder Playbooks zuordnet.
- Dockerfile zum Aufbau unseres Betreibers.
- Stellen Sie ein Verzeichnis mit Kubernetes-Objekten bereit, die zum Ausführen unseres Operators erforderlich sind.
Wenn Sie mehr darüber erfahren möchten, wie Sie Ihre eigenen Ansible-Anweisungen erstellen, verwenden Sie das
Benutzerhandbuch . Da wir jedoch versprochen haben, einen Ansible-Operator mit der in Ansible Galaxy veröffentlichten Rolle zu erstellen, benötigen wir nur eine Docker-Datei:
FROM quay.io/operator-framework/ansible-operator RUN ansible-galaxy install djzager.hello_world_k8s RUN echo $'--- \n\ - version: v1alpha1\n\ group: examples.djzager.io\n\ kind: HelloWorld\n\ role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml
Jetzt sammeln wir den Operator:
$ docker build -t hello-world-operator -f Dockerfile . Sending build context to Docker daemon 157.2 kB Step 1/3 : FROM quay.io/operator-framework/ansible-operator latest: Pulling from operator-framework/ansible-operator Digest: sha256:1156066a05fb1e1dd5d4286085518e5ce15acabfff10a8145eef8da088475db3 Status: Downloaded newer image for quay.io/water-hole/ansible-operator:latest ---> 39cc1d19649d Step 2/3 : RUN ansible-galaxy install djzager.hello_world_k8s ---> Running in 83ba8c21f233 - downloading role 'hello_world_k8s', owned by djzager - downloading role from https://github.com/djzager/ansible-role-hello-world-k8s/archive/master.tar.gz - extracting djzager.hello_world_k8s to /opt/ansible/roles/djzager.hello_world_k8s - djzager.hello_world_k8s (master) was installed successfully Removing intermediate container 83ba8c21f233 ---> 2f303b45576c Step 3/3 : RUN echo $'--- \n- version: v1alpha1\n group: examples.djzager.io\n kind: HelloWorld\n role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml ---> Running in cced495a9cb4 Removing intermediate container cced495a9cb4 ---> 5827bc3c1ca3 Successfully built 5827bc3c1ca3 Successfully tagged hello-world-operator:latest
Es ist klar, dass Sie zur
Verwendung dieses Operators den Inhalt des
Bereitstellungsverzeichnisses aus unserem Projekt benötigen, um ein Dienstkonto, eine Rollen- und Rollenbindung, eine benutzerdefinierte Ressourcendefinition zu erstellen und den Operator selbst bereitzustellen. Nach der Bereitstellung des Operators müssen Sie eine benutzerdefinierte Ressource erstellen, um eine Instanz der Hello World-Anwendung abzurufen:
apiVersion: examples.djzager.io/v1alpha1 kind: HelloWorld metadata: name: example-helloworld namespace: default spec: size: 3
Operatorbereiche: Namespace und Cluster
Etwas höher haben wir bereits vorgeschlagen, unser
Bereitstellungsverzeichnis zu durchsuchen und dort nach Kubernetes-Objekten zu suchen, die zum Starten des Operators erforderlich sind. Es gibt drei Dinge, die den Umfang des Operators einschränken, wenn benutzerdefinierte Ressourcen mit dem Namespace verwaltet werden, in dem der Operator selbst bereitgestellt wird:
- Die Umgebungsvariable WATCH_NAMESPACE in der Datei operator.yaml , die dem Bediener mitteilt, wo nach benutzerdefinierten Ressourcen gesucht werden soll
- role.yaml
- Rollenbindung
Diese Einschränkung ist sicherlich bei der Entwicklung von Betreibern nützlich. Wenn wir jedoch möchten, dass unsere Anwendung für alle Benutzer des Clusters zugänglich ist, benötigen wir die Hilfe eines Administrators. Ich müsste folgendes tun:
- Erstellen Sie ClusterRole anstelle von Role.
- Erstellen Sie eine ServiceAccount-Anweisung in dem Namespace, in dem die Anweisung bereitgestellt wird.
- Erstellen Sie eine ClusterRoleBinding, die ein ServiceAccount aus einem bestimmten Namespace mit einer ClusterRole verknüpft.
- Erweitern Sie die Anweisung mit einer undefinierten Umgebungsvariablen WATCH_NAMESPACE (d. H. "").
Wenn Sie all diese Dinge tun, können die übrigen Clusterbenutzer Instanzen unserer Hello World-Anwendung bereitstellen. Wenn Sie an diesem Thema interessiert sind, empfehlen wir Ihnen, den
Operator Lifecycle Manager (Teil des Operator Frameworks) zu studieren.
Star Trek
Wir haben gezeigt, wie Sie eine Ansible-Rolle erstellen, um eine Anwendung in Kubernetes zu steuern, diese Rolle in Ansible Galaxy zu veröffentlichen und im Ansible-Operator zu verwenden. Wir hoffen Sie jetzt:
- Sie verwenden das k8s Ansible-Modul .
- Veröffentlichen Sie Ihre Rollen für die Verwaltung von Kubernetes-Apps auf Ansible Galaxy .
- Interessieren Sie sich für das Operator SDK und abonnieren Sie unseren Operator Framework-Newsletter .
Unsere Hello World-Anwendung wurde absichtlich extrem einfach gestaltet, aber es gibt Dinge, die dazu beitragen können, sie noch zuverlässiger zu machen, und hier sind einige:
- Verwenden des Operator SDK - In unserem Beispiel haben wir dies absichtlich nicht getan, um zu betonen, wie einfach es ist, von der Ansible-Rolle zum Operator zu wechseln. Es ist jedoch besser, diese Rolle weiterhin mit dem SDK zu verwenden (dh operator-sdk new). Darüber hinaus benötigen Sie dies möglicherweise in den nächsten Schritten.
- Validierung - In unserer aktuellen Version kann der Benutzer eine CR mit der Größe abc erstellen, was zwangsläufig zu einem Fehler in der Bereitstellungsphase führt. Es ist daher besser, Fehler in der Spezifikationsphase und nicht nach Arbeitsbeginn zu erkennen.
- Lebenszyklus - In komplexeren Beispielen kann es sich um dasselbe Versionsupdate handeln. In Szenarien wie unseren, in denen es nur eine Version der Hello World-Anwendung gibt, können wir feststellen, ob das Image eines Arbeitscontainers veraltet ist, indem wir es mit den verfügbaren Images in der entsprechenden Containerregistrierung vergleichen und die laufenden Instanzen bei Bedarf aktualisieren.
- Testen - Molecule ist sehr nützlich beim Entwickeln und Testen von Ansible-Rollen.
- Operator Lifecycle Manager ist ein Toolkit zum Verwalten von Operatoren. Die Integration hilft bei der Installation und Aktualisierung unseres Betreibers.
- Status - Wir könnten die Status-Unterressource in unserer Hello World-CRD aktivieren und das k8s_status-Modul, das Teil des Ansible Operator-Images ist, verwenden, um Statusinformationen in die benutzerdefinierte Ressource aufzunehmen.