Überblick über Skaffold für die Entwicklung unter Kubernetes

Überblick über Skaffold für die Entwicklung unter Kubernetes

Vor anderthalb Jahren, am 5. März 2018, veröffentlichte die Firma Google die erste Alpha-Version ihres Open Source-Projekts für CI/CD mit dem Titel Skaffold, dessen Ziel es war, eine „einfache und reproduzierbare Entwicklung für Kubernetes“ zu schaffen, damit sich Entwickler auf die Entwicklung und nicht auf die Administration konzentrieren können. Was macht Skaffold interessant? Wie sich herausstellte, hat es einige Trümpfe im Ärmel, die es zu einem starken Werkzeug für Entwickler, aber auch für Betriebstechniker machen können. Lassen Sie uns das Projekt und seine Möglichkeiten kennenlernen.

NB: Übrigens haben wir bereits kurz über Skaffold in unserem allgemeinen Bericht über Entwicklerwerkzeuge, deren Lebenslauf mit Kubernetes verbunden ist.

Theorie. Zweck und Möglichkeiten

Wenn man also allgemein spricht, löst Skaffold die Aufgabe der Automatisierung des CI/CD-Zyklus (in den Phasen Build, Push, Deploy), indem es dem Entwickler schnelle Rückmeldungen bietet, d.h. die Möglichkeit, schnell Ergebnisse von den letzten Codeänderungen zu erhalten - in Form einer aktualisierten Anwendung, die im Kubernetes-Cluster läuft. Und es kann in verschiedenen Umgebungen (dev, stage, production…) arbeiten, für die Skaffold hilft, entsprechende Pipelines für das Deployment zu beschreiben.

Der Quellcode von Skaffold ist in der Programmiersprache Go geschrieben, wird verbreitet unter der freien Lizenz Apache License 2.0 (GitHub).

Betrachten wir die Hauptfunktionen und -merkmale. Zu den ersten zählen folgende:

  • Skaffold bietet Werkzeug zur Erstellung von CI/CD-Pipelines.
  • Es ermöglicht die Überwachung von Änderungen im Quellcode im Hintergrund und startet automatisierte Prozesse zur Codierung in Container-Images, zur Veröffentlichung dieser Images im Docker Registry und deren Deployment in das Kubernetes-Cluster.
  • Es synchronisiert Dateien im Repository mit dem Arbeitsverzeichnis im Container.
  • Es testet automatisch mit container-structure-test.
  • Es leitet Ports weiter.
  • Es liest die Protokolle der Anwendung, die im Container läuft.
  • Es hilft bei der Fehlerbehebung von Anwendungen, die in Java, Node.js, Python, Go geschrieben sind.

Jetzt zu den Besonderheiten:

  • Skaffold selbst hat keine Komponenten auf der Cluster-Seite. Das heißt, es ist keine zusätzliche Konfiguration von Kubernetes erforderlich, um dieses Dienstprogramm zu verwenden.
  • Verschiedene Pipelines für Ihre Anwendung. Müssen Sie den Code lokal in Minikube bereitstellen, während Sie die Entwicklung betreiben, und anschließend in die Stage oder Produktion? Dafür sind Profile und Benutzerkonfigurationen, Umgebungsvariablen und Flags, die es ermöglichen, unterschiedliche Pipelines für eine Anwendung zu beschreiben.
  • CLI. Nur ein Konsolenwerkzeug und Konfigurationen in YAML. Im Internet findet man Hinweise auf Versuche, eine experimentelle GUI, jedoch bedeutet dies derzeit eher, dass es jemand benötigt, aber nicht sehr.
  • Modularität. Skaffold ist kein eigenständiger Alleskönner, sondern strebt an, separate Module oder bereits bestehende Lösungen für spezifische Aufgaben zu verwenden.

Illustration des Letzteren:

  • In der Build-Phase können folgende verwendet werden:
    • docker build lokal, im Cluster mit kaniko oder in Google Cloud Build;
    • Bazel lokal;
    • Jib Maven und Jib Gradle lokal oder in Google Cloud Build;
    • benutzerdefinierte Build-Skripte, die lokal ausgeführt werden. Wenn Sie eine andere (flexiblere/gewöhnlichere/…) Lösung für den Build benötigen, wird diese im Skript beschrieben, damit Skaffold genau diese ausführt (Beispiel aus der Dokumentation). Dies ermöglicht die Verwendung von praktisch jedem Compiler, der über ein Skript aufgerufen werden kann;
  • In der Testphase wird bereits erwähnt, dass container-structure-test;
  • Für das Deployment sind vorgesehen:
    • Kubectl;
    • Helm;
    • kustomize.

Dankdessen kann man Skaffold als eine Art CI/CD-Framework. Hier ist ein Beispiel für den Arbeitsablauf bei seiner Nutzung (aus der Projektdokumentation):

Überblick über Skaffold für die Entwicklung unter Kubernetes

Wie sieht die Arbeit von Skaffold im Großen und Ganzen aus?

  1. Das Werkzeug überwacht Änderungen im Verzeichnis mit dem Quellcode. Wenn Dateien modifiziert werden, werden sie mit dem Pod der Anwendung im Kubernetes-Cluster synchronisiert. Wenn möglich — ohne das Bild erneut zu bauen. Andernfalls wird ein neues Bild erstellt.
  2. Das erstellte Bild wird mit container-structure-test überprüft, mit einem Tag versehen und in das Docker-Registry geladen.
  3. Nachdem das Bild bereitgestellt wurde — es wird im Kubernetes-Cluster ausgerollt.
  4. Wenn der Start mittels des Befehls skaffold dev, dann beginnen wir, die Logs von der Anwendung zu empfangen, und Skaffold wartet auf Änderungen, um alle Aktionen zu wiederholen.

Überblick über Skaffold für die Entwicklung unter Kubernetes
Illustration der Hauptphasen der Arbeit von Skaffold

Praxis. Wir testen Skaffold

Um die Verwendung von Skaffold zu demonstrieren, nehme ich ein Beispiel aus dem GitHub-Repository des Projekts. Übrigens, dort finden sich auch viele andere Beispiele, die unterschiedliche Spezifika berücksichtigen. Alle Aktionen werde ich lokal in Minikube durchführen. Die Installation ist einfach und dauert einige Minuten, und für den Start werden kubectl benötigt.

Lassen Sie uns Skaffold installieren:

curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
chmod +x skaffold
sudo mv skaffold /usr/local/bin
skaffold version
v0.37.1

Lass uns das Repository von Skaffold mit den benötigten Beispielen klonen:

git clone https://github.com/GoogleContainerTools/skaffold
cd skaffold/examples/microservices

Ich habe das Beispiel mit zwei Pods gewählt, von denen jeder eine kleine Anwendung in Go enthält. Eine Anwendung ist das Frontend (leeroy-web), das Anfragen an die zweite Anwendung - das Backend (leeroy-app) - weiterleitet. Schauen wir uns das an:

~/skaffold/examples/microservices # tree
.
├── leeroy-app
│   ├── app.go
│   ├── Dockerfile
│   └── kubernetes
│       └── deployment.yaml
├── leeroy-web
│   ├── Dockerfile
│   ├── kubernetes
│   │   └── deployment.yaml
│   └── web.go
├── README.adoc
└── skaffold.yaml
 
4 Verzeichnisse, 8 Dateien

leeroy-app und leeroy-web enthalten Go-Code und einfache Dockerfiles für den lokalen Bau dieses Codes:

~/skaffold/examples/microservices # cat leeroy-app/Dockerfile
FROM golang:1.12.9-alpine3.10 as builder
COPY app.go .
RUN go build -o /app .
 
FROM alpine:3.10
CMD ["./app"]
COPY --from=builder /app .

Ich werde den Code der Anwendungen nicht anführen - es reicht zu wissen, dass leeroy-web Anfragen entgegennimmt und sie an leeroy-appweiterleitet. Daher gibt es in den Dateien Deployment.yaml einen Service nur für App (zur internen Routenführung). Den Port des Pods web werden wir uns weiterleiten, um schnellen Zugriff auf die Anwendung zu aufbauen.

Wie sieht skaffold.yaml:

~/skaffold/examples/microservices # cat skaffold.yaml
apiVersion: skaffold/v1beta13
kind: Config
build:
  artifacts:
    - image: leeroy-web
      context: ./leeroy-web/
    - image: leeroy-app
      context: ./leeroy-app/
deploy:
  kubectl:
    manifests:
      - ./leeroy-web/kubernetes/*
      - ./leeroy-app/kubernetes/*
portForward:
  - resourceType: deployment
    resourceName: leeroy-web
    port: 8080
    localPort: 9000

Hier werden alle oben genannten Phasen beschrieben. Neben dieser Konfiguration gibt es auch eine Datei mit globalen Einstellungen - ~/ .skaffold/config. Diese kann man manuell oder über die CLI bearbeiten - zum Beispiel so:

skaffold config set --global local-cluster true

Dieser Befehl setzt die globale Variable local-cluster auf den Wert true, wonach Skaffold nicht mehr versuchen wird, Images in ein entferntes Registry zu pushen. Wenn Sie lokal entwickeln, können Sie diesen Befehl verwenden, um Images ebenfalls lokal zu speichern.

Kommen wir zurück zu skaffold.yaml:

  • In der Phase build wir geben an, dass das Image lokal gebaut und gespeichert werden muss. Nachdem der Build zum ersten Mal ausgeführt wurde, sehen wir Folgendes:
    // т.к. Minikube создает кластер в отдельной виртуальной машине,
    // придется проникнуть внутрь, чтобы найти образы
    # minikube ssh
    $ docker images
    REPOSITORY                                TAG                                                                IMAGE ID            CREATED             SIZE 
    leeroy-app                                7d55a50803590b2ff62e47e6f240723451f3ef6f8c89aeb83b34e661aa287d2e   7d55a5080359        4 hours ago         13MB 
    leeroy-app                                v0.37.1-171-g0270a0c-dirty                                         7d55a5080359        4 hours ago         13MB
    leeroy-web                                5063bfb29d984db1ff70661f17d6efcc5537f2bbe6aa6907004ad1ab38879681   5063bfb29d98        5 hours ago         13.1MB
    leeroy-web                                v0.37.1-171-g0270a0c-dirty                                         5063bfb29d98        5 hours ago         13.1MB

    Wie zu sehen ist, hat Skaffold die Images selbst getaggt. Übrigens werden mehrere Tagging-Politiken unterstützt.

  • Weiterhin wird in der Konfiguration angegeben, context: ./leeroy-app/, das heißt, der Kontext, in dem das Image gebaut wird, ist festgelegt.
  • In der Bereitstellungsphase wird festgelegt, dass wir kubectl und eine Maske für die benötigten Manifeste verwenden werden.
  • PortForward: ähnlich wie wir normalerweise Ports mit Hilfe von kubectl port-forward, geben wir Skaffold Anweisungen, um diesen Befehl aufzurufen. In diesem Fall wird der lokale Port 9000 auf 8080 im Deployment mit dem Namen leeroy-web.

Es ist an der Zeit, zu starten skaffold dev: der Befehl erstellt einen fortlaufenden "Feedback-Zyklus", d. h. er wird nicht nur alles sammeln und in den Cluster bereitstellen, sondern auch den Zustand der Pods zu diesem Zeitpunkt melden, Veränderungen überwachen und den Zustand der Pods aktualisieren.

Hier ist das Ergebnis des Starts skaffold dev --port-forward bei einer erneuten Erstellung:

Überblick über Skaffold für die Entwicklung unter Kubernetes

Zunächst ist erkennbar, dass der Cache verwendet wird. Weiterhin wird die Anwendung erstellt, bereitgestellt und Ports weitergeleitet. Da --port-forward, hat Skaffold den Port wie gewünscht zu webweitergeleitet, während er App einen nach eigenem Ermessen (den nächsten verfügbaren) weitergeleitet hat. Danach erhalten wir die ersten Logs von den Anwendungen.

Überprüfen wir die Funktionsfähigkeit?

~/skaffold/examples/microservices # kubectl get po
NAME                          READY   STATUS    RESTARTS   AGE
leeroy-app-6998dfcc95-2nxvf   1/1     Running   0          103s
leeroy-web-69f7d47c9d-5ff77   1/1     Running   0          103s
~/skaffold/examples/microservices # curl localhost:9000
leeroooooy App!!!

Wir modifizieren die Datei leeroy-app/app.go — es vergehen einige Sekunden… und:

~/skaffold/examples/microservices # kubectl get po
NAME                          READY   STATUS    RESTARTS   AGE
leeroy-app-ffd79d986-l6nwp    1/1     Running   0          11s
leeroy-web-69f7d47c9d-5ff77   1/1     Running   0          4m59s
~/skaffold/examples/microservices # curl localhost:9000
leeroooooy Habr!!!

Dabei gab Skaffold in der Konsole dasselbe aus wie zuvor, mit einer Ausnahme: Er hat nur leeroy-app, und nicht alles auf einmal ausgegeben.

Mehr Praxis

Es sei auch erwähnt, dass bei der Erstellung eines neuen Projekts die Konfigurationen für Skaffold mit dem Befehl initauf sehr bequeme Weise "gebootstrapped" werden können. Zudem können mehrere Konfigurationen erstellt werden: Die Entwicklung kann mit der Standardkonfiguration stattfinden, gefolgt von der Bereitstellung auf Stage mit dem Befehl run (der gleiche Prozess wie bei dev, nur ohne Änderungen zu überwachen), indem man eine andere Konfiguration verwendet.

Auf katacoda gibt es Anleitung ein Beispiel, das noch einfacher ist. Dort wird eine fertige Sandbox mit Kubernetes, Anwendung und Skaffold angeboten. Eine großartige Option, wenn Sie die Grundlagen selbst ausprobieren möchten.

Eine der möglichen Anwendungen von Skaffold ist die Entwicklung auf einem Remote-Cluster. Nicht jeder hat die Möglichkeit, Minikube auf eigener Hardware zu starten, die Anwendung bereitzustellen und auf deren ordnungsgemäße Funktion zu warten... In diesem Fall bietet Skaffold eine hervorragende Lösung für das genannte Problem, was unter anderem von Ingenieuren bei Reddit bestätigt werden kann, worüber wir bereits geschrieben in unserem Blog.

Und bei dieser Veröffentlichung Weaveworks finden Sie ein Beispiel für die Erstellung eines Produktions-Pipelines.

Fazit

Skaffold ist ein praktisches Tool zum Erstellen von Pipelines für die Bereitstellung von Anwendungen in Kubernetes, das zunächst auf die Bedürfnisse der Entwicklung ausgerichtet ist. Es ist recht einfach, eine "kurze" Pipeline zu erstellen, die die grundlegenden Bedürfnisse der Entwickler berücksichtigt; bei Bedarf können jedoch auch umfangreichere Prozesse organisiert werden. Als eines der anschaulichen Beispiele dafür, wie Skaffold in CI/CD-Prozesse integriert wird, wird solches ein Testprojekt mit 10 Mikrodiensten vorgestellt, die die Möglichkeiten von Kubernetes, gRPC, Istio und OpenCensus Tracing nutzen.

Skaffold hat bereits fast 8000+ Sterne auf GitHub erhalten, wird von Google entwickelt und ist Teil der GoogleContainerTools — insgesamt gibt es derzeit alle Gründe zu glauben, dass das Projekt lange und erfolgreich weiterentwickelt wird.

P.S.

Lesen Sie auch in unserem Blog:

Quelle: habr.com

60GB SSD 8Gb DDR4