Sorry OpenShift, wir haben dich nicht genug geschätzt und dich nicht als selbstverständlich angesehen

Dieser Beitrag wurde verfasst, weil unsere Mitarbeiter viele Gespräche mit Kunden über die Entwicklung von Anwendungen auf Kubernetes und über die Besonderheiten einer solchen Entwicklung unter OpenShift geführt haben.







Wir beginnen normalerweise mit der These, dass Kubernetes nur Kubernetes ist und OpenShift bereits eine Kubernetes-Plattform wie Microsoft AKS oder Amazon EKS ist. Jede dieser Plattformen hat ihre eigenen Vorteile, die sich an die eine oder andere Zielgruppe richten. Danach geht das Gespräch bereits in den Vergleich der Stärken und Schwächen bestimmter Plattformen über.



Im Allgemeinen dachten wir, diesen Beitrag mit einer Schlussfolgerung wie "Hören Sie, es spielt keine Rolle, wo der Code ausgeführt werden soll, auf OpenShift oder auf AKS, auf EKS, auf einigen benutzerdefinierten Kubernetes oder auf irgendwelchen Kubernetes (der Kürze halber nennen wir es) zu schreiben KUK) ist wirklich einfach, sowohl dort als auch dort. "



Dann wollten wir die einfachste "Hallo Welt" nehmen und anhand ihres Beispiels zeigen, was gemeinsam ist und was die Unterschiede zwischen KUK und Red Hat OpenShift Container Platform (im Folgenden OCP oder einfach OpenShift) sind.



Als wir diesen Beitrag geschrieben haben, haben wir jedoch festgestellt, dass wir uns so lange und so sehr an OpenShift gewöhnt haben, dass wir einfach nicht wissen, wie es gewachsen ist und sich zu einer erstaunlichen Plattform entwickelt hat, die viel mehr als nur eine Kubernetes-Distribution geworden ist. Wir sind es gewohnt, die Reife und Einfachheit von OpenShift als selbstverständlich zu betrachten und dabei seine Brillanz aus den Augen zu verlieren.



Im Allgemeinen ist die Zeit für aktive Umkehr gekommen, und jetzt werden wir Schritt für Schritt die Inbetriebnahme unserer "Hallo Welt" auf KUK und OpenShift vergleichen und dies so objektiv wie möglich tun (naja, vielleicht manchmal eine persönliche Einstellung zum Thema zeigen). Wenn Sie an einer rein subjektiven Meinung zu diesem Thema interessiert sind, können Sie diese hier lesen (EN) . In diesem Beitrag werden wir uns nur an Fakten und Fakten halten.



Cluster



Unsere "Hallo Welt" braucht also Cluster. Sagen wir sofort "Nein" zu öffentlichen Clouds, um nicht für Server, Register, Netzwerke, Datenübertragung usw. zu bezahlen. Dementsprechend wählen wir einen einfachen Einzelknotencluster in Minikube (für KUK) und Code Ready Containers (für OpenShift-Cluster). Beide Optionen sind sehr einfach zu installieren, erfordern jedoch eine Menge Ressourcen auf Ihrem Laptop.







Versammlung auf KUK-e



So lass uns gehen.



Schritt 1 - Erstellen Sie unser Container-Image



Ich beginne mit der Bereitstellung unserer "Hello World" in der Minikube. Dies erfordert:



  1. 1. Installierter Docker.
  2. 2. Git installiert.
  3. 3. Installierter Maven (tatsächlich verwendet dieses Projekt die mvnw-Binärdatei, sodass Sie darauf verzichten können).
  4. 4. Tatsächlich ist die Quelle selbst, d.h. Klon des Repository github.com/gcolman/quarkus-hello-world.git


Der erste Schritt besteht darin, ein Quarkus-Projekt zu erstellen. Seien Sie nicht beunruhigt, wenn Sie noch nie mit Quarkus.io gearbeitet haben - es ist einfach. Sie wählen einfach die Komponenten aus, die Sie im Projekt verwenden möchten (RestEasy, Hibernate, Amazon SQS, Camel usw.), und dann konfiguriert Quarkus selbst ohne Ihre Teilnahme den Maven-Archetyp und lädt alles auf Github hoch. Das heißt, buchstäblich ein Mausklick - und Sie sind fertig. Deshalb lieben wir Quarkus.







Der einfachste Weg, unsere "Hallo Welt" in ein Container-Image zu integrieren, ist die Verwendung der Quarkus-Maven-Docker-Erweiterungen, die die ganze Arbeit erledigen. Mit dem Aufkommen von Quarkus ist dies sehr einfach geworden: Fügen Sie die Container-Image-Docker-Erweiterung hinzu, und Sie können Bilder mit Maven-Befehlen erstellen.



./mvnw quarkus:add-extension -Dextensions=”container-image-docker”


Schließlich erstellen wir unser Image mit Maven. Dadurch wird unser Quellcode zu einem vorgefertigten Container-Image, das bereits zur Container-Laufzeit gestartet werden kann.







./mvnw -X clean package -Dquarkus.container-image.build=true


Das ist in der Tat alles. Jetzt können Sie den Container mit dem Docker-Befehl run starten, nachdem Sie unseren Service auf Port 8080 abgebildet haben, damit Sie darauf zugreifen können.



docker run -i — rm -p 8080:8080 gcolman/quarkus-hello-world








Nach dem Start der Containerinstanz muss nur noch mit dem Befehl curl überprüft werden, ob unser Dienst ausgeführt wird:







Also alles funktioniert und es war wirklich einfach und unkompliziert.



Schritt 2 - Verschieben unseres Containers in das Container-Image-Repository



Bisher wurde das von uns erstellte Image lokal in unserem lokalen Containerspeicher gespeichert. Wenn wir dieses Image in unserer KUK-Umgebung verwenden möchten, muss es in einem anderen Repository abgelegt werden. Kubernetes hat solche Funktionen nicht, daher verwenden wir Dockerhub. Weil es zum einen kostenlos ist und zum anderen (fast) jeder es tut.



Dies ist auch sehr einfach und Sie benötigen nur ein Dockerhub-Konto.



Also setzen wir Dockerhub und senden unser Bild dorthin.







Schritt 3 - Kubernetes starten



Es gibt viele Möglichkeiten, die Kubernetes-Konfiguration für die Ausführung unserer Hello World zusammenzustellen, aber wir werden die einfachste verwenden. Wir sind die Art von Menschen, die wir sind ...



Starten Sie zuerst den Minikube-Cluster:



minikube start


Schritt 4 - Bereitstellen unseres Container-Images



Jetzt müssen wir unseren Code und unser Container-Image in die Kubernetes-Konfiguration umwandeln. Mit anderen Worten, wir benötigen eine Pod- und Bereitstellungsdefinition mit einem Hinweis auf unser Container-Image auf Dockerhub. Eine der einfachsten Möglichkeiten, dies zu tun, besteht darin, den Befehl create deploy auszuführen, der auf unser Image verweist:







kubectl create deployment hello-quarkus — image =gcolman/quarkus-hello-world:1.0.0-SNAPSHOT


Mit diesem Befehl haben wir unseren KUK angewiesen, eine Bereitstellungskonfiguration zu erstellen, die die Pod-Spezifikation für unser Container-Image enthalten soll. Dieser Befehl wendet diese Konfiguration auch auf unseren Minikube-Cluster an und erstellt eine Bereitstellung, die unser Container-Image herunterlädt und den Pod im Cluster startet.



Schritt 5 - offener Zugang zu unserem Service



Nachdem wir ein bereitgestelltes Container-Image haben, ist es an der Zeit, darüber nachzudenken, wie der externe Zugriff auf diesen Restful-Dienst konfiguriert werden kann, der tatsächlich in unserem Code programmiert ist.



Es gibt viele Wege. Mit dem Befehl expose können Sie beispielsweise automatisch die entsprechenden Kubernetes-Komponenten wie Dienste und Endpunkte erstellen. Dies ist, was wir tun werden, indem wir den Befehl expose für unser Bereitstellungsobjekt ausführen:



kubectl expose deployment hello-quarkus — type=NodePort — port=8080


Lassen Sie uns einen Moment auf die Option "- type" des Befehls expose eingehen.



Wenn wir die Komponenten bereitstellen und erstellen, die für die Ausführung unseres Dienstes erforderlich sind, möchten wir unter anderem eine Verbindung von außen mit dem Hallo-Quarkus-Dienst herstellen können, der sich in unserem SDN befindet. Und die Typ - Parameter ermöglichen es uns , zu erstellen und zu verbinden Dinge wie Loadbalancer zu leiten den Verkehr zu diesem Netzwerk.



Zum Beispiel durch Schreiben von type = LoadBalancerwerden wir den Load Balancer in der öffentlichen Cloud automatisch initialisieren, um eine Verbindung zu unserem Kubernetes-Cluster herzustellen. Das ist natürlich großartig, aber Sie müssen verstehen, dass eine solche Konfiguration fest an eine bestimmte öffentliche Cloud gebunden ist und es schwieriger ist, sie zwischen Kubernetes-Instanzen in verschiedenen Umgebungen zu übertragen.



In unserem Beispiel geben Sie = NodePort ein , dh der Anruf an unseren Dienst erfolgt über die IP-Adresse des Knotens und die Portnummer. Mit dieser Option können Sie keine öffentlichen Clouds verwenden, erfordern jedoch eine Reihe zusätzlicher Schritte. Zunächst benötigen Sie Ihren eigenen Load Balancer, damit wir einen NGINX Load Balancer in unserem Cluster bereitstellen.



Schritt 6 - Installieren Sie den Load Balancer



Minikube verfügt über eine Reihe von Plattformfunktionen, mit denen sich auf einfache Weise Komponenten erstellen lassen, die für den externen Zugriff erforderlich sind, z. B. Ingress-Controller. Minikube wird mit dem Nginx Ingress Controller geliefert, den wir nur aktivieren und konfigurieren müssen.



minikube addons enable ingress


Jetzt erstellen wir mit nur einem Befehl einen Nginx-Ingress-Controller, der in unserem Minikube-Cluster funktioniert:



ingress-nginx-controller-69ccf5d9d8-j5gs9 1/1 Running 1 33m


Schritt 7 - Ingress konfigurieren



Jetzt müssen wir den Nginx Ingress Controller so konfigurieren, dass er Hallo-Quarkus-Anfragen akzeptiert.











Schließlich müssen wir diese Konfiguration anwenden.







kubectl apply -f ingress.yml








Da wir dies alles auf unserem Computer tun, fügen wir einfach die IP-Adresse unseres Knotens zur Datei / etc / hosts hinzu, um http-Anforderungen an unseren Minikube an den NGINX-Load-Balancer weiterzuleiten.



192.168.99.100 hello-quarkus.info


Jetzt ist unser Minikube-Service von außen über den Nginx Ingress Controller zugänglich.







Das war einfach, oder? Oder nicht wirklich?









Starten Sie auf OpenShift (Code Ready Containers)



Nun wollen wir sehen, wie alles auf der Red Hat OpenShift Container Platform (OCP) funktioniert.



Wie bei minikube wählen wir ein Schema mit einem OpenShift-Cluster mit einem einzelnen Knoten in Form von Code Ready Containers (CRC). Früher hieß es Minishift und basierte auf dem OpenShift Origin-Projekt. Jetzt ist es ein CRC und basiert auf der OpenShift Container Platform von Red Hat.



Hier können wir leider nicht anders als zu sagen: "OpenShift ist großartig!"



Anfangs dachten wir zu schreiben, dass sich die Entwicklung auf OpenShift nicht von der Entwicklung auf Kubernetes unterscheidet. Und tatsächlich ist es so. Beim Schreiben dieses Beitrags haben wir uns jedoch daran erinnert, wie viele unnötige Bewegungen Sie ausführen müssen, wenn Sie nicht über OpenShift verfügen, und daher ist es auch hier wunderbar. Wir lieben es, wenn alles einfach ist und wie einfach es im Vergleich zu Minikube ist. Unser Beispiel wird unter OpenShift bereitgestellt und ausgeführt. Dies hat uns dazu veranlasst, diesen Beitrag zu schreiben.



Lassen Sie uns den Prozess durchgehen und sehen, was wir tun müssen.



Im Minikube-Beispiel haben wir also mit Docker begonnen ... Stop, Docker muss nicht mehr auf dem Computer installiert sein.



Und wir brauchen keinen lokalen Idioten.

Und Maven wird nicht benötigt.

Und Sie müssen kein Containerbild mit Ihren Händen erstellen.

Es ist nicht erforderlich, nach einem Repository für Container-Images zu suchen.

Und Sie müssen keinen Ingress-Controller installieren.

Und Sie müssen Ingress auch nicht konfigurieren.




Verstehst du, richtig? Sie benötigen keine der oben genannten Voraussetzungen, um unsere Anwendung unter OpenShift bereitzustellen und auszuführen. Und der Prozess selbst sieht so aus.



Schritt 1 - Starten Ihres OpenShift-Clusters



Wir verwenden Code Ready-Container von Red Hat, bei denen es sich im Wesentlichen um denselben Minikube handelt, jedoch nur mit einem vollwertigen Open-Shift-Cluster mit einem Knoten.



crc start


Schritt 2 - Erstellen und Bereitstellen der Anwendung im OpenShift-Cluster



In diesem Schritt manifestiert sich die Einfachheit und Bequemlichkeit von OpenShift in seiner ganzen Pracht. Wie bei allen Kubernetes-Distributionen gibt es viele Möglichkeiten, eine Anwendung in einem Cluster auszuführen. Und wie bei KUK wählen wir bewusst die einfachste.



OpenShift wurde immer als Plattform zum Erstellen und Ausführen von Containeranwendungen entwickelt. Das Erstellen von Containern war schon immer ein wesentlicher Bestandteil dieser Plattform, daher gibt es eine Reihe zusätzlicher Kubernetes-Ressourcen für verwandte Aufgaben.



Wir werden den OpenShift Source 2 Image (S2I) -Prozess verwenden, der verschiedene Möglichkeiten bietet, unsere Quelle (Code oder Binärdateien) in ein Container-Image umzuwandeln, das auf einem OpenShift-Cluster ausgeführt wird.



Dafür brauchen wir zwei Dinge:



  • Unser Quellcode im Git-Repository
  • Builder-Image, auf dessen Grundlage der Build ausgeführt wird.


Es gibt viele solcher Images, die sowohl von Red Hat als auch von der Community-Ebene verwaltet werden. Wir werden das OpenJDK-Image verwenden, da ich eine Java-Anwendung erstelle.



Sie können S2I Build sowohl über die grafische OpenShift Developer-Konsole als auch über die Befehlszeile starten. Wir werden den Befehl new-app verwenden, um anzugeben, wo das Builder-Image und unser Quellcode abgerufen werden sollen.







oc new-app registry.access.redhat.com/ubi8/openjdk-11:latest~https://github.com/gcolman/quarkus-hello-world.git


Das war's, unsere Anwendung wurde erstellt. Dabei hat der S2I-Prozess folgende Aktionen ausgeführt:



  • Erstellt einen Service-Build-Pod für alle möglichen Dinge im Zusammenhang mit der Erstellung der Anwendung.
  • Erstellt die OpenShift Build-Konfiguration.
  • Das Builder-Image wurde in die interne Docker-Registrierung von OpenShift heruntergeladen.
  • "Hello World" in lokales Repository geklont.
  • Ich habe gesehen, dass da ein Maven Pom drin ist und habe die App mit Maven kompiliert.
  • Erstellt ein neues Container-Image mit der kompilierten Java-Anwendung und fügt dieses Image in die interne Container-Registrierung ein.
  • Erstellt Kubernetes Deployment mit Pod-Spezifikationen, Service usw.
  • Die Bereitstellung des Container-Images wurde gestartet.
  • Der Service-Build-Pod wurde entfernt.


Diese Liste enthält viele Dinge, aber die Hauptsache ist, dass der gesamte Build ausschließlich in OpenShift stattfindet, die interne Docker-Registrierung in OpenShift erfolgt und der Build-Prozess alle Kubernetes-Komponenten erstellt und im Cluster ausführt.



Wenn Sie den Start von S2I in der Konsole visuell verfolgen, können Sie sehen, wie der Build-Pod während des Builds gestartet wird.







Schauen wir uns nun die Protokolle des Builder-Pods an: Zunächst wird gezeigt, wie Maven seine Arbeit erledigt, und die Abhängigkeiten zum Erstellen unserer Java-Anwendung heruntergeladen.







Nachdem der Maven-Build abgeschlossen ist, wird der Container-Image-Build gestartet und dieses erstellte Image in das interne Repository verschoben.







Das war's, der Montageprozess ist abgeschlossen. Stellen wir nun sicher, dass die Pods und Dienste unserer Anwendung im Cluster ausgeführt werden.



oc get service








Das ist alles. Und nur ein Team. Wir müssen diesen Service nur für den externen Zugriff verfügbar machen.



Schritt 3 - Stellen Sie den Dienst für den externen Zugriff bereit



Wie im Fall von KUK benötigt auch unsere "Hello World" auf der OpenShift-Plattform einen Router, um externen Datenverkehr zu einem Dienst innerhalb des Clusters zu leiten. OpenShift macht dies sehr einfach. Zunächst wird die HAProxy-Routingkomponente standardmäßig im Cluster installiert (Sie können sie in denselben NGINX ändern). Zweitens gibt es spezielle und hoch konfigurierbare Ressourcen namens Routen, die Ingress-Objekten in guten alten Kubernetes ähneln (tatsächlich haben die Routen von OpenShift das Design von Ingress-Objekten stark beeinflusst, die jetzt in OpenShift verwendet werden können). , aber für unsere "Hallo Welt" und in fast allen anderen Fällen reicht uns die Standardroute ohne zusätzliche Konfiguration.



Um einen routbaren FQDN für "Hello World" zu erstellen (ja, OpenShiift verfügt über einen eigenen DNS für das Routing nach Dienstnamen), legen wir einfach unseren Dienst offen:







oc expose service quarkus-hello-world


Wenn Sie sich die neu erstellte Route ansehen, finden Sie dort den FQDN und andere Routing-Informationen:



oc get route








Schließlich greifen wir über den Browser auf unseren Service zu:







Jetzt war es wirklich einfach!



Wir lieben Kubernetes und alles, was uns die Technologie ermöglicht, und wir lieben auch Einfachheit und Leichtigkeit. Kubernetes wurde entwickelt, um die Bedienung verteilter, skalierbarer Container unglaublich einfach zu machen, aber seine Einfachheit reicht nicht mehr aus, um Anwendungen einzuführen. Und hier kommt OpenShift ins Spiel, das mit der Zeit Schritt hält und Kubernetes anbietet, das sich hauptsächlich auf den Entwickler konzentriert. Es wurden große Anstrengungen unternommen, um die OpenShift-Plattform genau für den Entwickler zu entwickeln, einschließlich der Erstellung von Tools wie S2I, ODI, Entwicklerportal, OpenShift Operator Framework, IDE-Integration, Entwicklerkatalogen, Helm-Integration, Überwachung und vielen anderen.



Wir hoffen, dieser Artikel war interessant und nützlich für Sie. Weitere Ressourcen, Materialien und andere nützliche Dinge für die Entwicklung auf der OpenShift-Plattform finden Sie im Red Hat Developers- Portal .



All Articles