Hosten Sie Ihre Anwendung in Google Kubernetes Engine

Foto von True Agency auf Unsplash
Als Entwickler ist es immer eine schwierige Aufgabe, Ihre Kreation auf einer anderen Plattform als Platform as a Service, zum Beispiel Heroku, zu hosten.

In diesem Artikel werde ich Sie durch den Prozess der Bereitstellung einer Anwendung für eine Infrastructure as a Service wie beispielsweise Google Kubernetes Engine führen und hoffe, dass dies Ihre Angst vor Hosting-Diensten auf "niedrigerer Ebene" lindert.

Quelle: presslabs.com

Wir werden die folgenden Schritte ausführen, um unsere Anwendung zu hosten:

  1. Kubernetes Cluster-Erstellung
  2. Dockerisierung der Anwendung
  3. Richten Sie die Kubernetes-Konfiguration ein
  4. Installation und Konfiguration von Nginx
  5. DNS-Konfiguration
  6. Bereitstellung von SSL-Zertifikaten (Secure Socket Layer)

Die Anwendung

Die Anwendung verfügt über ein Frontend mit React und Backend (API mit Python Flask und Postgresql als Datenbank).

Reagieren Sie, Python-Kolben und Postgres
Dies ist im Grunde eine Implementierung der dreistufigen Architektur. Präsentationsschicht (Frontend), Logikschicht (API) und Datenschicht (Datenbank) alle getrennt und unabhängig.
Die Anwendung ist eine "Bucketlist" -Anwendung, in der ein Benutzer Bucketlist-Elemente zusammen mit Aktionselementen aufzeichnen kann, wie sie diese erreichen.

Der erste Schritt zum Hosten dieser Anwendung auf GKE ist das Andocken. Das heißt, Sie können jede der drei Ebenen der Anwendung andocken. Klonen Sie dieses Repository, um es weiterzuverfolgen.

Voraussetzungen

Die Tools, die wir in diesem Artikel verwenden, umfassen folgend:

  1. kubectl
  2. gcloud
  3. Docker
  4. Google Cloud-Projekt

Befolgen Sie die Anweisungen auf dem Bildschirm, um die obigen Tools einzurichten. Dies kann bedeuten, dass Sie sich bei Ihrem Google Cloud-Konto anmelden.

Wenn Sie sie noch nicht eingerichtet haben, fahren Sie fort und richten Sie sie über diese Links ein. Wenn Sie sie bereits eingerichtet haben, passen wir sie an.

Kubernetes Cluster-Erstellung

Beginnen wir mit der Erstellung eines Kubernetes-Clusters und konfigurieren dabei alle erforderlichen Anmeldeinformationen für die Interaktion mit dem neu erstellten Cluster.

Es gibt verschiedene Möglichkeiten, einen Cluster in Kubernetes zu erstellen. Dazu gehören die Verwendung der Google Cloud-Konsole, die Befehlszeile (gcloud) oder REST.

Dafür verwenden wir die Kommandozeile (gcloud). Auf diese Weise können wir von unserem Terminal aus arbeiten, mit dem Sie als Entwickler arbeiten. Stellen Sie zuerst diese Umgebungsvariablen ein.

Ich habe alle diese Umgebungsvariablen in einer env.sh-Datei zusammengefasst. Auf Ihrem Terminal können Sie "source env.sh" ausführen, um alle auf einmal zu füllen.
  1. $ PROJECT: Dies ist die Google-Projekt-ID. Dasselbe Projekt, das Sie erstellt haben oder für dieses Projekt verwenden möchten.
  2. $ CLUSTER: Dies ist der Name des Clusters, den Sie erstellen möchten.
  3. $ ZONE: Dies ist die Zone, in der der Cluster erstellt wird.
  4. $ GCR_REGISTRY: Dies ist die GCR-Registrierung, in der sich die Container-Images befinden.
  5. $ FRONTEND_DOCKER_IMAGE_NAME: Dies ist der Bildname, den Ihr Frontend-Container-Bild haben soll.
  6. $ DATABASE_DOCKER_IMAGE_NAME: Dies ist der Bildname, den Ihr Datenbankcontainer-Bild haben soll.
  7. $ BACKEND_API_DOCKER_IMAGE_NAME: Dies ist der Bildname, den das API-Container-Bild haben soll.

Bevor wir den Cluster erstellen, gibt es noch ein Puzzleteil, das wir noch nicht haben. Ein Dienstkonto. Gehen Sie hierher und erstellen Sie ein Dienstkonto und stellen Sie sicher, dass Sie ihm die folgenden Rollen zuweisen:

  1. rolls / storage.admin wie hier angegeben
  2. Rollen / project.owner

Nachdem alle diese Umgebungsvariablen festgelegt und Dienstkonten und Rollen zugewiesen wurden, können Sie den folgenden Befehl ausführen:

gcloud beta container - projekt "$ PROJECT" cluster erstellen "$ CLUSTER" - zone "$ ZONE"

Dieser Befehl dauert einige Minuten. Nach Abschluss wird die Datei mit den Anmeldeinformationen nach Bedarf ausgefüllt, damit Sie mit dem neu erstellten Kubernetes-Cluster interagieren können.

Jetzt, da wir einen Cluster haben, können die Kubernetes-Spiele beginnen.

Dockerisierung der Anwendung

Quelle: cengn.ca

Ich habe die Anwendung so eingerichtet, dass jede Schicht einen eigenen Ordner hat. Dies erleichtert das Organisieren der Dockerdateien der einzelnen Ebenen.

Wechseln Sie auf Ihrem Terminal in den Frontend-Ordner. Da diese Anwendung der Versionskontrolle unterliegt, müssen Sie den Zweig auschecken, für den Sie das Docker-Image erstellen möchten.

Um in den 3 Ebenen organisiert zu sein, habe ich alle Docker-bezogenen Dateien in den Docker / Ordner gelegt. Führen Sie diesen Befehl aus, während Sie sich im Stammverzeichnis des Frontend-Anwendungsschichtordners befinden

Docker-Build -t $ GCR_REGISTRY / $ PROJECT / $ FRONTEND_DOCKER_IMAGE_NAME: v1 -f Docker / Dockerfile.

Dies dauert einige Minuten, während das Docker-Image für die Frontend-Ebene erstellt und konfiguriert wird. Wenn der Build abgeschlossen ist, erstellen Sie auch die API- und Datenbank-Docker-Images.

Wechseln Sie in Ihrem Terminal in das Verzeichnis api und führen Sie diesen Befehl aus, um das Docker-Image der Back-End-API zu erstellen.

Docker-Build -t $ GCR_REGISTRY / $ PROJECT / $ BACKEND_API_DOCKER_IMAGE_NAME: v1 -f Docker / Dockerfile.

Und zum Schluss bauen wir für die Datenbankschicht. Wechseln Sie auf Ihrem Terminal in das Datenbankverzeichnis und führen Sie Folgendes aus:

Docker-Build -t $ GCR_REGISTRY / $ PROJECT / $ DATABASE_DOCKER_IMAGE_NAME: v1 -f Docker / Dockerfile.

Wenn die obigen Befehle erfolgreich ausgeführt wurden, haben wir 3 Docker-Images. Frontend, API und Datenbank lokal auf Ihrem Desktop / Laptop. Bearbeiten Sie die Datei deployments.yaml im Ordner k8s-configuration mit den Namen der neu erstellten Docker-Images.

Damit Google Kubernetes Engine diese Bilder verwenden kann, müssen sie zugänglich gemacht werden. Eine Möglichkeit, dies zu tun, besteht darin, sie an die Google Container Registry weiterzuleiten.

Google Container Registry, Quelle: blog.deimos.fr
Dies ist die Version des Docker-Hubs von Google Cloud Platform. Container-Image-Repository von Google.

Führen Sie in Ihrem Terminal Folgendes aus:

gcloud auth configure-docker

Dadurch wird Docker so konfiguriert, dass die offiziellen Docker-Image-Repositorys von Google Cloud verwendet werden, z Sie tun für Hafenarbeiter.

Lassen Sie uns nun alle 3 Bilder in die Google Container Registry übertragen. Führen Sie einfach Folgendes aus:

Docker-Push $ GCR_REGISTRY / $ PROJECT / $ FRONTEND_DOCKER_IMAGE_NAME: v1 && Docker-Push $ GCR_REGISTRY / $ PROJECT / $ BACKEND_API_DOCKER_IMAGE_NAME: v1 && Docker-Push $ GCR_REGISTRY_PROJECT / $ PROJECT / $

Nachdem das erledigt ist, wenden wir uns jetzt dem Elefanten im Raum zu. Bereitstellen der Anwendung auf Google Kubernetes Engine.

Quelle: google.com

Kubernetes Konfigurationsordnerstruktur

Ich habe alle kubernetes Konfigurationsdateien in den k8s-configuration Ordner gelegt. Hier haben wir die Implementierungen, Ingress-, Secrets- und Service-Konfigurationen in ähnlich benannten yaml-Dateien zusammengefasst.

  1. deployments.yaml. Eine Bereitstellung ist einfach eine „Arbeitslast“, die Ihre Anwendungs-Pod-Konfigurationen (die einen Container enthalten) enthält. Diese Konfigurationsdatei enthält das Container-Image, Ports, Labels, die Anzahl der Replikate usw.
  2. services.yaml. In Kubernetes sind Dienste der „Klebstoff“ der verschiedenen „Workloads“. Diese bieten Konnektivität zwischen Containern im kubernetes-Ökosystem. Dies liegt daran, dass auf die Art und Weise, wie Kubernetes erstellt wurde, ein Container nicht mit einem anderen Container „sprechen“ kann, wenn er sich nicht im selben Pod befindet. Im Wesentlichen werden das Frontend und die API niemals direkt miteinander kommunizieren, wenn sie sich nicht im selben Pod befinden. In diesem Setup befinden sie sich nicht im selben Pod. Deshalb müssen wir Dienste nutzen.
  3. ingress.yaml. In kubernetes ist ingress ein Regelsatz, der den externen Internetverkehr auf Dienste in einem kubernetes-Cluster umleitet. Dies ist hilfreich, wenn Sie über viele Dienste verfügen, die Bereitstellungen für das Internet verfügbar machen müssen. Mit ingress verwenden Sie nur einen HTTP-Load-Balancer, der den Datenverkehr für alle Bereitstellungen verarbeitet, für die das Internet erforderlich ist, im Gegensatz zur Verwendung eines separaten Load-Balancers für jede Bereitstellung, der in Bezug auf Cloud-Computing-Kosten kostspielig sein kann.
  4. secrets.yaml. Für unsere Anwendung benötigen wir als Geheimnis ein SSL-Zertifikat, um die SSL-Beendigung zu erleichtern. Auf diese Weise kann sicher über HTTPS auf unsere Anwendung zugegriffen werden.

Lassen Sie uns nun fortfahren und den Inhalt der Konfigurationsdateien von kubernetes in tatsächliche Cloud-Computing-Ressourcen umwandeln.

Nach der bewährten Methode von Google werden Dienste zuerst erstellt, bevor sie bereitgestellt werden. Daher wenden wir zuerst die Konfigurationsdatei services.yaml an. Gehen Sie zum Ordner k8s-configuration und beginnen Sie, Code in tatsächliche Rechenressourcen umzuwandeln.

Führen Sie auf Ihrem Terminal im Ordner k8s-configuration Folgendes aus:

kubectl create -f services.yaml

Die Ausgabe sollte folgendermaßen aussehen:

iterm Ausgabe
Dieser Befehl erstellt jede in der angegebenen Datei services.yaml deklarierte Ressource.
Dies ist die deklarative Methode zum Erstellen von Kubernetes-Ressourcen. deklarieren Sie sie alle in einer yaml-Datei und übergeben Sie diese Datei mit dem Flag -f an den Befehl kubectl create, und die ganze Magie findet danach statt.

Machen Sie dasselbe für die Datei secrets.yaml, ingress.yaml und die Datei deployments.yaml. Lauf:

kubectl create -f ingress.yaml && kubectl create -f deployments.yaml && kubectl create -f secrets.yaml

Wenn dieser Befehl erfolgreich ausgeführt wurde, rufen Sie die GCP-Konsole im Abschnitt kubernetes engine> workloads auf. Dort finden Sie Ihre soeben erstellten Ressourcen.

Google Kubernetes Engine-Dashboard

Wenn Sie nichts sehen, stellen Sie sicher, dass Sie in der oberen rechten Ecke zu dem richtigen Konto gewechselt haben, das Sie für dieses Projekt eingerichtet haben, und stellen Sie sicher, dass Sie das richtige Projekt in der oberen linken Ecke ausgewählt haben, wie unten gezeigt.

Konsolen-Dashboard für die Google Cloud-Plattform

Werfen Sie einen Blick auf den Abschnitt Workloads. Sie sollten das Frontend, die API und die Datenbank mit grünen Häkchen versehen haben.

Dashboard für GKE-Workloads

Besuchen Sie auch den Servicebereich und vergewissern Sie sich, dass alle Services verfügbar und funktionsfähig sind.

Dashboard für GKE-Services

An diesem Punkt ist bis auf eine Sache alles in Ordnung. Ein Ingress-Controller, ohne den wir über den Browser auf keinen Teil unserer Anwendung in der Google Cloud zugreifen können.

Ein Ingress-Controller ist für die Ausführung des Ingress verantwortlich, normalerweise mit einem Loadbalancer. Das Erstellen einer Ingress-Ressource allein funktioniert ohne Ingress-Controller nicht. Zum Glück für uns und für das Ruder müssen wir nicht in die komplizierten Details des Einrichtens eines Ingress-Controllers von Null einsteigen.

Ingress-Controller-Konfiguration

Um einen Ingress-Controller in unserem Cluster zum Laufen zu bringen, verwenden wir das Steuer.

Quelle: google.com
Helm ist für Kubernetes, Homebrew für MacOS, Apt-Get für Ubuntu und Pip für Python. Es ist ein Paketmanager für Kubernetes.

Mit Helm können wir Abhängigkeiten und ganze Anwendungen, die zu einem Paket zusammengefasst wurden, mit nur einem Befehl installieren. Beginnen wir mit der Installation und Konfiguration von helm.

Führen Sie in Ihrem Terminal Folgendes aus:

curl -o get_helm.sh https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get && chmod + x get_helm.sh && ./get_helm.sh && helm init

Mit dem obigen Befehl wird die neueste Version des Helm-Clients abgerufen und auf Ihrem lokalen Computer (Laptop / Desktop) installiert.

Damit helm mit unserem Cluster zusammenarbeiten kann, muss eine serverseitige Komponente im Cluster installiert sein, mit der helm „spricht“, um Befehle zu verwalten und an sie weiterzuleiten und so alle Ressourcen zu erstellen, die wir in diesem Fall für einen Ingress benötigen Regler.

Diese Komponente heißt Tiller. Um die Pinne in einem Google Kubernetes-Cluster zu installieren, müssen ein Dienstkonto und eine Clusterrollenbindung für die Pinne konfiguriert sein. Auf diese Weise kann Tiller Kubernetes-Ressourcen in unserem Cluster installieren.

Führen Sie in Ihrem Terminal die folgenden Befehle aus, um die Pinne nach Bedarf zu installieren und zu konfigurieren:

kubectl create serviceaccount --namespace kubectl system tiller && kubectl create clusterrolebinding tiller-cluster-rule --clusterrole = cluster-admin --serviceaccount = kubectl system: tiller && '{"Spec": {"template": {"spec": {"serviceAccount": "tiller"}}}' && helm init --service-account tiller --upgrade

Führen Sie Folgendes aus, um die Installation der Pinne zu bestätigen:

kubectl get deployments -n kube-system | Grep Tiller-Deploy

Dadurch wird Ihre neu erstellte Tiller-Dploy-Bereitstellung ausgegeben.

Wir haben jetzt Ruder und Pinne auf unserer lokalen Arbeitsstation und auf dem entfernten Cluster installiert und konfiguriert. Jetzt können wir einen Ingress-Controller in unserem Cluster installieren.

Nginx Ingress für GKE

Es gibt eine Vielzahl von Ingress-Controllern. Dazu verwenden wir den nginx-Ingress-Controller, wie wir ihn in unserer Konfigurationsdatei ingress.yaml deklariert haben. In Ihrem Terminallauf:

helm install --name nginx-ingress stable / nginx-ingress --set rbac.create = true

Dadurch wird der nginx Ingress-Controller installiert. Um unsere Installation zu bestätigen, führen Sie Folgendes aus:

kubectl bekommt service nginx-ingress-controller

Dadurch erhalten Sie eine Ausgabe des Nginx-Controller-Dienstes vom Typ loadBalancer mit einer externen IP.

Es dauert eine Weile, bis diese externe IP erstellt ist. Wenn Sie also "Ausstehend" sehen, geben Sie Google einige Sekunden / Minuten Zeit, um sie für Sie bereitzustellen.

Zu diesem Zeitpunkt können Sie über die externe IP des Dienstes nginx ingress controller auf das Frontend zugreifen. Aber genau wie Salt-Bae, warum sollte man normal sein? Verknüpfen wir diese IP-Adresse mit einem Domain-Namen, damit wir über http://www.myapp.com statt über http://35.90.3.9 darauf zugreifen können.

Wenn Sie noch keine haben, können Sie eine von Godaddy, Hover, Google-Domains usw. kaufen. Konfigurieren Sie jetzt unsere Domain.

DNS-Konfiguration

Quelle: pngall.com

Ich habe meinen eigenen Domainnamen verwendet, den ich eine Woche nach diesem Demo-Artikel notieren werde. Gehen Sie zu Ihrem Domain-Dashboard und richten Sie einige Subdomain-Namen für das Frontend, die API und die Datenbank ein.

Mein Domainname ist davidmukiibi.com und die von mir erstellten Subdomains sehen folgendermaßen aus:

frontend.davidmukiibi.com
api.davidmukiibi.com
database.davidmukiibi.com
Hover-Domain-Dashboard

Führen Sie in Ihrem Terminal Folgendes aus:

kubectl get services | grep LoadBalancer | awk '{print $ 4}'

Kopieren Sie die Ausgabe dieses Befehls. Dies ist die externe IP-Adresse, über die unsere Anwendung mit dem Internet verbunden ist.

Geben Sie in Ihrem Domain-Dashboard diese externe IP-Adresse als Wert für die 3 von uns erstellten Datensatzgruppen ein.

Wenn Sie unsere Datei ingress.yaml überprüfen, werden Sie feststellen, dass wir unseren Ingress-Controller über die Ingress-Ressource angewiesen haben, alle Anforderungen mit der folgenden Anmerkung an https umzuleiten:

nginx.ingress.kubernetes.io/ssl-redirect: "true"

Dies ermöglicht nur sichere Verbindungen zu unserer Anwendung.

Es empfiehlt sich, nur sichere Verbindungen zu Ihrer Anwendung zuzulassen, insbesondere wenn diese mit Benutzerdaten arbeitet. Vor diesem Hintergrund benötigen wir ein SSL-Zertifikat, um eine End-to-End-Verschlüsselung zwischen unserer Anwendung und dem Benutzer zu ermöglichen.

Quelle: google.com

Wir werden let’s encrypt verwenden, da es kostenlose SSL-Zertifikate mit einer Gültigkeit von 3 Monaten bietet. Sie können alle Zertifikate verwenden, wenn Sie welche haben, ob bezahlt oder kostenlos.

Bereitstellung des SSL-Zertifikats

Um die SSL-Zertifikate von lets encrypt zu erhalten, verwenden wir ein Tool namens certbot. Installieren wir letsencrypt und certbot.

Wechseln Sie in den Ordner k8s-configuration. Wenn Sie Ubuntu Linux verwenden, führen Sie Folgendes aus:

apt-get install letsencrypt

Wenn Sie macOS verwenden, führen Sie Folgendes aus:

brau installiere certbot && pip installiere letsencrypt --user
Hier finden Sie die Installationsschritte für Ihr Betriebssystem.

Da wir 3 Subdomains mit der einen Domain verknüpft haben, erstellen wir ein Wildcard-SSL-Zertifikat. Dies gilt für alle Subdomains der Domain davidmukiibi.com.

Führen Sie in Ihrem Terminal Folgendes aus:

certbot --manual --logs-dir certbot --config-dir certbot --work-dir certbot --prefered-challenges dns certonly --server https://acme-v02.api.letsencrypt.org/directory --email Ihre-E-Mail-Adresse -d "* .davidmukiibi.com"
Ersetzen Sie "Ihre-E-Mail-Adresse" im obigen Befehl durch Ihre eigene E-Mail-Adresse.

Befolgen Sie die Anweisungen auf dem Bildschirm, um das Wildcard-SSL-Zertifikat Ihrer Domain bereitzustellen. Wenn Sie die Eingabeaufforderung erreichen, die lautet:

Stellen Sie unter dem Namen einen DNS-TXT-Eintrag bereit
_acme-challenge.erpnext.davidmukiibi.com mit dem folgenden Wert: 
"Davidmukiibi.com" sollte Ihr eigener Domainname sein

Gehen Sie zu Ihrem Domain-Dashboard und erstellen Sie einen "txt" -Datensatz für _acme-challenge.erpnext.davidmukiibi.com und geben Sie den von certbot auf Ihrem Terminal angegebenen Wert ein.

HINWEIS: "davidmukiibi.com" sollte Ihr eigener Domainname sein
SSL-TXT-ACME-Herausforderung
Nehmen Sie sich ein oder zwei Minuten Zeit, nachdem Sie diesen Datensatz erstellt haben

Kehren Sie zum Terminal zurück und drücken Sie die Eingabetaste auf Ihrer Tastatur, um mit der Zertifikatsbereitstellung fortzufahren.

Der Grund, warum Sie möglicherweise warten müssen, ist, dass die Weitergabe manchmal länger dauert, sodass certbot nicht bereitgestellt werden kann und Sie den gesamten Prozess erneut wiederholen müssen

Wenn alles erledigt ist, hat certbot einen "cerbot" -Ordner in Ihrem aktuellen Arbeitsverzeichnis erstellt. Und die Bildschirmausgabe leitet Sie zu der Position Ihres SSL-Zertifikats zusammen mit den zwei benötigten Importdateien weiter, nämlich den Dateien cert.pem und privkey.pem. Führen Sie im Verzeichnis mit den * .pem-Dateien Folgendes aus:

cat cert.pem | base64 | pbcopy

Dadurch wird cert.pem in base64 codiert und die Ausgabe des cert.pem-codierten Ergebnisses in die Zwischenablage kopiert.

Gehen Sie zur Datei secrets.yaml und fügen Sie sie in den Wert von tls.crt ein:

secrets.yaml

Lauf:

Katze privkey.pem | base64 | pbcopy

Um die Datei privkey.pem zu codieren und das Ergebnis als Wert von tls.key einzufügen: in der Datei secrets.yaml.

Die Befehle: „cat cert.pem | base64 | pbcopy “und„ cat privkey.pem | base64 | pbcopy ”base64 verschlüsselt die Dateien privkey.pem und cert.pem und kopiert gleichzeitig das Ergebnis. Sie haben also keine Ausgabe auf Ihrem Terminal, aber wenn Sie Strg + V oder Cmd + V in einem Texteditor verwenden, sehen Sie das codierte Ergebnis.

Führen Sie mit der wie oben angegebenen Datei secrets.yaml Folgendes aus:

kubectl create -f secrets.yaml

Dadurch wird eine Kubernetes-Ressource vom Typ secret erstellt, die unsere Eingangsressource für die SSL-Beendigung und ein sicheres Surfen mit HTTPS verwendet.

Foto von Mimi Thian auf Unsplash

Wir können jetzt unsere Webbrowser hochfahren und zu frontend.davidmukiibi.com gehen, um unsere Anwendung zu überprüfen.

Beachten Sie, wie es automatisch zu HTTPS umleitet? Das ist die Magie, die mit der Verwendung des Nginx Ingress Controllers einhergeht.

Und da hast du es. Hostete schließlich eine dreistufige Architekturanwendung auf Google Kubernetes Engine.

Löschen Sie die soeben erstellten Ressourcen, wenn Sie sie nicht mehr benötigen, da sie von Google Cloud in Rechnung gestellt werden und noch nicht verwendet werden.

Führen Sie Folgendes aus, um den Cluster und alle zuvor erstellten Ressourcen zu löschen:

gcloud-Containercluster löschen $ CLUSTER

Ein besonderes Dankeschön an John, der die gesamte Bewerbung zusammengestellt hat.

In diesem Artikel, den ich zusammengestellt habe, finden Sie Informationen zu Docker-Befehlen, die Ihren Docker-Workflow ganz schnell vereinfachen.

Sie können jederzeit Änderungen oder Ergänzungen des hier ausgetauschten Wissens vorschlagen. Sie können sich auch über Twitter oder LinkedIn unterhalten.