Table of Contents
*Der Autor hat Girls Who Code dazu ausgewählt, im Rahmen des Programms Write for DOnations eine Spende zu erhalten.*
Einführung
Die Okteto CLI ist ein Open-Source-Projekt, das ein lokales Entwicklungserlebnis für Anwendungen ermöglicht, die unter Kubernetes ausgeführt werden. Damit können Sie Ihren Code in Ihrer lokalen IDE schreiben und, sobald Sie die Datei speichern, die Änderungen in Ihren Kubernetes-Cluster übertragen, woraufhin Ihre App sofort aktualisiert wird. Das alles ist möglich, ohne dass Sie Docker-Images erstellen oder Kubernetes-Manifeste anwenden müssen. Auf diese Weise können Sie viel Zeit sparen.
In diesem Tutorial nutzen Sie Okteto, um die Produktivität beim Entwickeln von Kubernetes-nativen Anwendungen zu verbessern. Zuerst erstellen Sie einen Kubernetes-Cluster und verwenden ihn zur Ausführung einer standardmäßigen „Hello World“-Anwendung. Dann nutzen Sie Okteto, um Ihre Anwendung zu entwickeln und automatisch zu aktualisieren, ohne dass Sie lokal etwas installieren müssen.
Voraussetzungen
Bevor Sie mit diesem Tutorial beginnen, benötigen Sie Folgendes:
- Ein Kubernetes 1.12+-Cluster. In diesem Tutorial wird ein Kubernetes-Cluster mit drei Knoten verwendet, aber Sie können auf Wunsch auch mit einer anderen Methode einen Cluster erstellen.
kubectlunddoctl, installiert und so konfiguriert, dass sie mit Ihrem Cluster kommunizieren.
- Ein Docker Hub-Konto
- Docker, das auf Ihrem lokalen Rechner ausgeführt wird.
Schritt 1 — Erstellen der Hello World-Anwendung
Das „Hello World“-Programm hat eine lange Tradition in der Webentwicklung. In unserem Fall ist es ein einfacher Webdienst, der auf jede Anfrage mit „Hello World“ antwortet. Nachdem Sie Ihren Kubernetes-Cluster eingerichtet haben, erstellen wir nun eine „Hello World"-App in Golang sowie die Manifeste, die Sie zur Bereitstellung in Kubernetes nutzen werden.
Wechseln Sie zunächst in Ihr Stammverzeichnis:
cd ~
Erstellen Sie nun ein neues Verzeichnis namens hello_world und wechseln Sie hinein:
mkdir hello_world
cd hello_world
Erstellen und öffnen Sie mit Ihrer bevorzugten IDE oder Ihrem bevorzugten Texteditor eine neue Datei namens main.go:
nano main.go
main.go wird ein Golang-Webserver sein, der die Nachricht Hello World! zurückgibt. Verwenden wir also den folgenden Code:
[label main.go]
package main
import (
"fmt"
"net/http"
)
func main() {
fmt.Println("Starting hello-world server...")
http.HandleFunc("/", helloServer)
if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
}
func helloServer(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello world!")
}
Der Code in main.go tut Folgendes:
- Die erste Anweisung in einer Go-Quelldatei muss der Name des
Pakets(package) sein. Ausführbare Befehle müssen stetspackage <^>main<^>nutzen.
- Der
import-Abschnitt gibt an, von welchen Paketen der Code abhängt. In diesem Fall werdenfmtzur Zeichenfolgenbearbeitung undnet/httpfür den HTTP-Server genutzt.
- Die Funktion
mainist der Einstiegspunkt in Ihre Binärdatei. Die Methodehttp.HandleFuncdient dazu, den Server so zu konfigurieren, dass die FunktionhelloServeraufgerufen wird, wenn eine Anfrage an den Pfad/empfangen wird.http.ListenAndServestartet einen HTTP-Server, der an allen Netzwerkschnittstellen an Port8080lauscht.
- Die Funktion
helloServerenthält die Logik Ihres Anforderungshandlers. In diesem Fall wird sieHello World!als Antwort auf die Anforderung schreiben.
Sie müssen ein Docker-Image erstellen und in Ihre Docker-Registrierung verschieben, damit Kubernetes es aufnehmen und die Anwendung ausführen kann.
Öffnen Sie mit Ihrer bevorzugten IDE oder Ihrem bevorzugten Texteditor eine neue Datei namens Dockerfile:
nano Dockerfile
Die Datei Dockerfile enthält die zum Erstellen des Docker-Containers Ihrer Anwendung erforderlichen Befehle. Verwenden Sie folgenden Code:
[label Dockerfile]
FROM golang:alpine as builder
RUN apk --update --no-cache add bash
WORKDIR /app
ADD . .
RUN go build -o app
FROM alpine as prod
WORKDIR /app
COPY --from=builder /app/app /app/app
EXPOSE 8080
CMD ["./app"]
Die Datei Dockerfile enthält zwei Stufen: builder und prod.
- Die Stufe
builderenthält die Go-Build-Tools. Sie ist verantwortlich für das Kopieren der Dateien und das Erstellen der Go-Binärdatei.
- Die Stufe
prodist das endgültige Image. Sie wird nur ein grundlegendes Betriebssystem und die Binärdatei der Anwendung enthalten.
Dies ist eine empfehlenswerte Praxis. Mit dieser Lösung werden Ihre Produktionscontainer kleiner und sicherer, da sie nur Ihre Anwendung und genau das enthalten, was zur Ausführung benötigt wird.
Erstellen Sie das Container-Image (ersetzen Sie <^>your_DockerHub_username<^> durch Ihren Docker Hub-Benutzernamen):
docker build -t <^>your_DockerHub_username<^>/hello-world:latest
Pushen Sie es nun an Docker Hub:
docker push <^>your_DockerHub_username<^>/hello-world:latest
Erstellen Sie als Nächstes einen neuen Ordner für die Kubernetes-Manifeste:
mkdir k8s
Wenn Sie ein Kubernetes-Manifest nutzen, teilen Sie Kubernetes mit, wie Sie Ihre Anwendung ausführen möchten. Dieses Mal erstellen Sie ein deployment-Objekt. Erstellen Sie also mit Ihrer bevorzugten IDE oder Ihrem bevorzugten Texteditor eine neue Datei namens deployment.yaml:
nano k8s/deployment.yaml
Der folgende Inhalt beschreibt ein Kubernetes-Bereitstellungsobjekt, das das Docker-Image okteto/hello-world:latest ausführt. Fügen Sie diesen Inhalt in Ihre neue Datei ein, aber ersetzen Sie in Ihrem Fall okteto, das nach der Bezeichnung image aufgeführt wird, durch <^>your_DockerHub_username<^> (Ihren DockerHub-Benutzernamen):
[label ~/hello_world/k8s/deployment.yaml]
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
selector:
matchLabels:
app: hello-world
replicas: 1
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: <^>your_DockerHub_username<^>/hello-world:latest
ports:
- containerPort: 8080
Das Bereitstellungsmanifest verfügt über drei Hauptabschnitte:
metadatadefiniert den Namen für Ihre Bereitstellung.
replicaslegt fest, wie viele Kopien davon Sie ausführen möchten.
templateteilt Kubernetes mit, was bereitgestellt werden soll und welche Bezeichnungen hinzugefügt werden sollen. In diesem Fall ist es ein einzelner Container mit dem Imageokteto/hello-world:latest, der an Port8080lauscht, mit der Bezeichnungapp: hello-world. Beachten Sie, dass diese Bezeichnung die gleiche ist wie im Bereichselector(Auswahl).
Sie benötigen nun eine Möglichkeit, auf Ihre Anwendung zuzugreifen. Sie können eine Anwendung in Kubernetes verfügbar machen, indem Sie ein Dienstobjekt erstellen. Lassen Sie uns dazu weiterhin Manifeste verwenden. Erstellen Sie also mit Ihrer bevorzugten IDE oder Ihrem bevorzugten Texteditor eine neue Datei namens service.yaml:
nano k8s/service.yaml
Der folgende Inhalt beschreibt einen Dienst, der das hello-world-Bereitstellungsobjekt verfügbar macht, das darunter einen the cloud provider-Load Balancer nutzen wird:
[label k8s/service.yaml]
apiVersion: v1
kind: Service
metadata:
name: hello-world
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 8080
name: http
selector:
app: hello-world
Das Dienstmanifest verfügt über vier Hauptabschnitte:
metadatateilt Kubernetes mit, wie der Dienst heißen soll.
typeteilt Kubernetes mit, wie Sie Ihren Dienst verfügbar machen möchten. In diesem Fall wird er extern über einen the cloud provider-Load Balancer verfügbar gemacht.
- Die Bezeichnung
portsteilt Kubernetes mit, welche Ports Sie verfügbar machen möchten und wie sie Ihrer Bereitstellung zugeordnet werden sollen. In diesem Fall werden Sie Port80extern verfügbar machen und an Port8080in Ihrer Bereitstellung weiterleiten.
selectorteilt Kubernetes mit, wie Datenverkehr weitergeleitet werden soll. In diesem Fall empfängt jeder Pod mit der Bezeichnungapp: hello-worldDatenverkehr.
Sie haben nun alles, um Ihre „Hello World“-Anwendung in Kubernetes bereitzustellen. Das werden wir als Nächstes tun.
Schritt 2 — Bereitstellen Ihrer Hello World-Anwendung
In diesem Schritt werden Sie Ihre „Hello World“-Anwendung in Kubernetes bereitstellen und dann überprüfen, ob sie richtig funktioniert.
Beginnen Sie zunächst mit der Bereitstellung Ihrer Anwendung in Kubernetes:
kubectl apply -f k8s
Sie sehen die folgende Ausgabe:
[secondary_label Output]
deployment.apps "hello-world" created
service "hello-world" created
Nach etwa einer Minute können Sie die IP-Adresse Ihrer Anwendung abrufen. Verwenden Sie den Befehl kubectl, um Ihren Dienst zu überprüfen:
kubectl get service hello-world
Sie sehen eine Ausgabe, die in etwa wie folgt aussieht und Ihre Kubernetes-Dienstobjekte auflistet. Notieren Sie sich die IP-Adresse Ihrer Anwendung in der Spalte EXTERNAL-IP:
[secondary_label Output]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world ClusterIP <^>your_cluster_ip<^> <^>your_external_ip<^> 8080/TCP 37s
Öffnen Sie Ihren Browser und gehen Sie zu <^>your_external_ip<^>, die für Ihre „Hello World“-Anwendung aufgelistet ist. Vergewissern Sie sich, dass Ihre Anwendung ausgeführt, bevor Sie mit dem nächsten Schritt fortfahren.
Bis jetzt sind Sie einem relativ traditionellen Pfad zur Entwicklung von Anwendungen mit Kubernetes gefolgt. Wenn Sie in Zukunft den Code in Ihrer Anwendung ändern möchten, müssen Sie ein neues Docker-Image erstellen und pushen und dann das Image aus Kubernetes abrufen. Dieser Prozess kann etwas länger dauern. Okteto dient dazu, diesen Inner-Loop bei der Entwicklung zu optimieren. Sehen wir uns die Okteto CLI um zu erfahren, wie sie uns helfen kann.
Schritt 3 — Installieren der Okteto CLI
Sie können nun die Produktivität bei der Kubernetes-Entwicklung erhöhen, indem Sie die Okteto CLI installieren. Die Okteto Command Line Interface ist ein Open-Source-Projekt, das Sie Änderungen an Anwendungscode für eine Anwendung, die unter Kubernetes ausgeführt wird, synchronisieren lässt. Sie können Ihre bevorzugten IDEs, Debugger oder Compiler weiter nutzen, ohne Container zum Testen Ihrer Anwendung committen, erstellen, pushen oder neu bereitstellen zu müssen – wie Sie es noch in den vorherigen Schritten getan haben.
Um die Okteto CLI auf einem MacOS- oder Linux-Rechner zu installieren, führen Sie den folgenden Befehl aus:
curl https://get.okteto.com -sSfL | sh
Sehen wir uns diesen Befehl näher an:
- Der Befehl
curldient dazu, Daten an und von einem Server zu übertragen.
- Das Flag
-sunterdrückt jede Ausgabe.
- Das Flag
-Szeigt Fehler an.
- Das Flag
-fbewirkt, dass die Anforderung bei HTTP-Fehlern fehlschlägt.
- Das Flag
-Lsorgt dafür, dass die Anforderung Umleitungen folgt.
- Der Operator
|leitet diese Ausgabe an den Befehlsh, der die neuesteokteto-Binärdatei auf Ihren lokalen Rechner herunterladen und installieren wird.
Wenn Sie Windows ausführen, können Sie die Datei alternativ über Ihren Webbrowser herunterladen und manuell Ihrem $PATH hinzufügen.
Sobald die Okteto CLI installiert ist, können Sie Ihre „Hello World“-Anwendung in den Entwicklungsmodus versetzen.
Schritt 4 — Versetzen Ihrer Hello World-Anwendung in den Entwicklungsmodus
Die Okteto CLI ist so konzipiert, dass die Anwendung, die in einem Kubernetes-Cluster ausgeführt wird, durch den Code, den Sie auf Ihrem Rechner haben, ausgetauscht wird. Okteto verwendet dazu die von einer Okteto Manifest-Datei bereitgestellten Daten. Diese Datei deklariert das Kubernetes-Bereitstellungsobjekt, das mit Ihrem lokalen Code ausgetauscht wird.
Erstellen Sie mit Ihrer bevorzugten IDE oder Ihrem bevorzugten Texteditor eine neue Datei namens okteto.yaml:
nano okteto.yaml
Schreiben wir nun ein einfaches Manifest, in dem wir den Namen des Bereitstellungsobjekts, das zu verwendende Docker-Image und eine Shell definieren. Wir werden später auf diese Daten zurückgreifen. Verwenden Sie die folgende Beispielinhaltsdatei:
[label okteto.yaml]
name: hello-world
image: okteto/golang:1
workdir: /app
command: ["bash"]
Bereiten Sie Ihre Anwendung auf das Versetzen in den Entwicklungsmodus vor, indem Sie folgenden Befehl ausführen:
okteto up
[secondary_label Output]
✓ Development environment activated
✓ Files synchronized
Namespace: default
Name: hello-world
Welcome to your development environment. Happy coding!
default:hello-world /app>
Der Befehl okteto up verschiebt die „Hello World“-Anwendung in eine Entwicklungsumgebung, was bedeutet:
- Der Hello World-Anwendungscontainer wird mit dem Docker-Image
okteto/golang:1aktualisiert. Dieses Image enthält die erforderlichen dev-Tools, um die „Hello World“-Anwendung zu erstellen, zu testen, zu debuggen und auszuführen.
- Ein Dateisynchronisierungsdienst wird erstellt, um Änderungen zwischen Ihrem lokalen Dateisystem und Ihren Anwendungs-Pods zu synchronisieren.
- In Ihrer Entwicklungsumgebung wird eine Remote-Shell gestartet. Sie können Ihre Anwendung nun erstellen, testen und ausführen, als befände Sie sich auf Ihrem lokalen Rechner.
- Egal, welchen Prozess Sie in der Remote-Shell ausführen, werden Sie den gleichen eingehenden Datenverkehr sowie die gleichen Umgebungsvariablen, Volumes oder Geheimnisse wie die ursprünglichen „Hello World“-Anwendungs-Pods erhalten. So profitieren Sie von einer sehr realistischen, produktionsähnlichen Entwicklungsumgebung.
Führen Sie in der gleichen Konsole nun die Anwendung aus, wie Sie es normalerweise tun würden (ohne ein Docker-Image zu erstellen und zu pushen):
go run main.go
[secondary_label Output]
Starting hello-world server...
Bei der ersten Ausführung der Anwendung wird Go Ihre Abhängigkeiten herunterladen und Ihre Anwendung kompilieren. Warten Sie, bis der Prozess abgeschlossen ist, und testen Sie Ihre Anwendung, indem Sie Ihren Browser öffnen und die Seite Ihrer Anwendung aktualisieren, wie Sie es zuvor getan haben.
Sie können nun direkt in Kubernetes mit der Entwicklung beginnen.
Schritt 5 — Entwickeln direkt in Kubernetes
Beginnen wir nun, Änderungen an der „Hello World“-Anwendung vorzunehmen und zu ermitteln, wie sich diese Änderungen in Kubernetes widerspiegeln.
Öffnen Sie die Datei main.go mit Ihrer bevorzugten IDE oder Ihrem bevorzugten Texteditor. Öffnen Sie beispielsweise eine separate Konsole und führen Sie den folgenden Befehl aus:
nano main.go
Ändern Sie dann Ihre Antwortnachricht in <^>Hello World from the cloud provider! <^>:
[label main.go]
package main
import (
"fmt"
"net/http"
)
func main() {
fmt.Println("Starting hello-world server...")
http.HandleFunc("/", helloServer)
if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
}
func helloServer(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "<^>Hello world from the cloud provider!<^>")
}
Hier ändert sich Ihr Workflow. Anstatt Images zu erstellen und Container neu bereitzustellen, um die „Hello World“-Anwendung zu aktualisieren, synchronisiert Okteto Ihre Änderungen mit Ihrer Entwicklungsumgebung in Kubernetes.
Löschen Sie über die Konsole, in der Sie den Befehl okteto up ausgeführt haben, die Ausführung von go run main.go, indem Sie STRG + C drücken. Führen Sie die Anwendung nun erneut aus:
default:hello-world /app> go run main.go
[secondary_label Output]
Starting hello-world server...
Kehren Sie zurück zum Browser und laden Sie die Seite für Ihre „Hello World“-Anwendung neu.
Ihre Codeänderungen wurden auf Kubernetes sofort angewendet, ohne Commit-, Build- oder Push-Operationen.
Zusammenfassung
Okteto verwandelt Ihren Kubernetes-Cluster mit nur einem Klick in eine vollwertige Entwicklungsplattform. In diesem Tutorial haben Sie die Okteto CLI installiert und konfiguriert, um Ihre Codeänderungen direkt in Kubernetes zu iterieren – und zwar so schnell, wie Sie Code eingeben. Überprüfen Sie nun das Okteto-Beispielrepository, um zu sehen, wie sich Okteto mit verschiedenen Programmiersprachen und Debuggern verwenden lässt.
Wenn Sie einen Kubernetes-Cluster mit Ihrem Team teilen, sollten Sie den einzelnen Mitgliedern Zugriff auf einen sicheren Kubernetes-Namespace gewähren, der so konfiguriert ist, dass er von anderen Entwicklern, die im gleichen Cluster arbeiten, isoliert wird. Diese praktische Funktion wird auch von der Okteto App im Kubernetes Marketplace bereitgestellt.