/ Docker

Skaffold

Skaffold ist ein Open-Source-Projekt das im Rahmen der Google Cloud Platform initiiert wurde. Es befindet sich noch im Beta-Status, hat aber in der täglichen Arbeit keine Aussetzer. Allein an der Dokumentation des Projekts erkennt man den frühen Entwicklungsstand. An einigen Stellen befinden sich noch "tbd"-Markierungen.

Mit Skaffold kann die Entwicklung von Kubernetes-Anwendungen automatisiert werden. Nach einer lokalen Änderung des Code, können automatisiert Images gebaut, getagged, gepusht und die Kubernetes-Workloads aktualisiert werden.

Source: skaffold.dev

Ebenfalls wichtig: Kubernetes-native Anwendungen können einfach zwischen Entwicklern geteilt werden. Auch wenn sie kein tiefgründiges Kubernetes-Verständnis haben, können sie ihre Anwendung in Kubernetes starten und debuggen. Diese Eigenschaften eignen sich ebenfalls bestens für die Verwendung in CI/CD-Pipelines

Installation

Die Installation von Skaffold ist in wenigen Schritten erledigt:

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

Erste Schritte

Im Skaffolds GitHub-Repository gibt es einige Beispiele. Im Beispiel "getting-started" wird eine einfache Go-Anwendung als Docker-Image gebaut und als Kubernetes-Pod im Cluster veröffentlicht. Die Dateien "Dockerfile", "k8s-pod.yaml" und die "main.go" beinhalten keine Besonderheiten für die Nutzung mit Skaffold. Sie können ohne Skaffold gebaut und veröffentlicht werden.

main.go: ein einfaches Programm, das jede Sekunde eine neue Zeile in der Konsolenausgabe generiert.

package main

import (
	"fmt"
	"time"
)

func main() {
	for {
		fmt.Println("Hello world!")
		time.Sleep(time.Second * 1)
	}
}

Dockerfile: Anweisungen zum Bau des Docker-Image.

FROM golang:1.12.9-alpine3.10 as builder
COPY main.go .
RUN go build -o /app main.go

FROM alpine:3.10
CMD ["./app"]
COPY --from=builder /app .

k8s-pod.yaml: Die Kubernetes-Ressource, die im Cluster veröffentlicht werden soll.

apiVersion: v1
kind: Pod
metadata:
  name: getting-started
spec:
  containers:
  - name: getting-started
    image: gcr.io/k8s-skaffold/skaffold-example

Allein die skaffold.yaml beinhaltet Anweisungen für Skaffold. In diesem Beispiel ist es die Angabe des Namens des zu bauenden Docker-Images und die Angabe, welche Kubernetes-Objekte deployed werden sollen. Der Zugriff auf das Docker-Repository muss lokal und im Kubernetes-Cluster gewährleistet sein. Ggf. muss eine andere Registry verwendet werden.

apiVersion: skaffold/v1beta17
kind: Config
build:
  artifacts:
  - image: gcr.io/k8s-skaffold/skaffold-example
deploy:
  kubectl:
    manifests:
      - k8s-*

Um bei lokalen Änderungen, alle Ressourcen neu zu erstellen und zu veröffentlichen, wird der Befehl `skaffold dev` ausgeführt. Ohne weitere Angaben wird im Cluster deployed, der im aktiven Kubectl-Context konfiguriert ist. Nach Abspeichern der vorgenommenen Änderungen und kurzer Wartezeit sollte in der Konsole folgende Ausgabe erscheinen:

[getting-started] Hello Skaffold!

Lokal entwickeln mit Skaffold

Mit Skaffold gegen einen Produktiv-Cluster zu entwickeln, vor allem in einer frühen Umsetzungsphase ist nicht empfehlenswert. Häufige Deployments und mögliche Fehler in der Applikation könnten in dem Cluster unnötige Last verursachen. Es ist besser lokal zu entwickeln, solange alle Abhängigkeiten lokal abgebildet werden können. Ein lokaler Cluster kann zum Beispiel mit Minikube installiert werden. Die Installation ist sehr einfach:

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
  && chmod +x minikube
 
sudo mv minikube /usr/local/bin

# Start Minikube
minikube start

Ein weiterer Vorteil ist die fehlende Notwendigkeit die gebauten Images in einer Image-Registry zu speichern. Sie werden direkt vom lokalen Docker Daemon geladen. Hiefür muss in Skaffold nichts konfiguriert werden. Der Cluster kann den lokalen Docker-Daemon erreichen und die gebauten Images ohne Umwege laden.

Mit `skaffold dev` wird ein Image mit dem Namen "skaffold-local-example" lokal erstellt und ein Pod mit diesem Image in Minikube veröffentlicht.

Noch ein Hinweis: wenn man auf dem eigenen Rechner in der Kube-Config mehrere Cluster konfiguriert hat, ist es sinnvoll noch die Angabe `kubeContext` in der skaffold.yaml zu ergänzen.  Sonst muss man immer daran denken, den Context zwischen Minikube und den anderen Clustern umzuschalten.

Fazit

Mit Skaffold kann die Entwicklung von Kubernetes-Applikationwn erheblich beschleunigt werden. Es können alle Bau- und Veröffentlichungsanweisungen zusammengefasst werden. Zusätzlich müssen Applikakationsentwickler kein Wissen über Kubernetes und die Kubernetes-Architektur haben. Mit einer vorgefertigten `skaffold.yaml` können sie ihre Anwendung bauen, in Kubernetes veröffentlichen und debuggen.

Quellen:

https://cloud.google.com/blog/products/gcp/introducing-skaffold-easy-and-repeatable-kubernetes-development

https://skaffold.dev/docs/