Swift auf Kubernetes deployen: Vom lokalen Build zum Production-Cluster
\nSwift ist nicht nur eine Sprache für iOS und macOS. Dank Frameworks wie Vapor und Kitura wird Swift zunehmend für die Entwicklung von Serveranwendungen eingesetzt. Aber wie bringt man eine solche Anwendung zu den Nutzern? Die Antwort: Kubernetes. In diesem Leitfaden werden wir durchgehen, wie man eine Swift-Anwendung in Docker verpackt, CI/CD einrichtet und sie in einem K8s-Cluster bereitstellt. Sie erfahren, welche Besonderheiten es beim Bau von Swift unter Linux gibt, wie man das Image optimiert und wie man die richtigen Manifeste für Kubernetes erstellt.
\n\n1. Vorbereitung der Swift-Anwendung für die Containerisierung
\nDas Erste, dem ein Entwickler begegnet, ist Swift unter Linux. Wenn Sie unter macOS entwickeln, müssen Sie Ihre Anwendung für Linux (amd64/arm64) cross-kompilieren. Betrachten wir ein Beispiel basierend auf Vapor 4.
\nErstellen wir eine einfache HTTP-Anwendung:
\n// Sources/App/routes.swift\nimport Vapor\n\nfunc routes(_ app: Application) throws {\n app.get { req async in\n "Hello from Swift on Kubernetes!"\n }\n app.get("health") { req async in\n "OK"\n }\n}\n\nFür den Bau unter Linux verwenden wir das offizielle Swift-Image. Erstellen wir ein Dockerfile mit einem mehrstufigen Build:
# Erste Stufe: Bau\nFROM swift:5.9-focal as builder\nWORKDIR /app\nCOPY Package.swift Package.resolved ./\nRUN swift package resolve\nCOPY . .\nRUN swift build -c release --static-swift-stdlib\n\n# Zweite Stufe: Minimales Image\nFROM ubuntu:22.04\nRUN apt-get update && apt-get install -y ca-certificates libsqlite3-0 && rm -rf /var/lib/apt/lists/*\nWORKDIR /app\nCOPY --from=builder /app/.build/release/Run .\nEXPOSE 8080\nCMD ["./Run"]\n\nDer entscheidende Punkt ist das Flag --static-swift-stdlib. Es aktiviert die statische Verlinkung der Swift-Standardbibliothek, was die Image-Größe reduziert und das Deployment vereinfacht. Ohne dieses Flag kann das Image 1+ GB wiegen.
2. Bau des Images und Hochladen in die Registry
\nBauen wir das Image und pushen es in Docker Hub (oder eine andere Registry):
\n# Bau\ndocker build -t myrepo/swift-k8s-demo:1.0.0 .\n\n# Lokale Überprüfung\ndocker run -p 8080:8080 myrepo/swift-k8s-demo:1.0.0\ncurl http://localhost:8080\n# Antwort: Hello from Swift on Kubernetes!\n\n# Push in die Registry\ndocker push myrepo/swift-k8s-demo:1.0.0\n\nGrößenoptimierung: Ein Image basierend auf ubuntu:22.04 wiegt ~150 MB. Bei Verwendung von alpine kann es auf 50 MB reduziert werden, aber dann muss das Problem mit glibc gelöst werden (Swift benötigt es). Es wird empfohlen, offizielle Ubuntu- oder Debian-Images zu verwenden.
3. Kubernetes-Manifeste für die Swift-Anwendung
\nJetzt deployen wir unsere Anwendung im Cluster. Erstellen wir ein Deployment und einen Service.
\ndeployment.yaml:
\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: swift-app\n labels:\n app: swift-app\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: swift-app\n template:\n metadata:\n labels:\n app: swift-app\n spec:\n containers:\n - name: swift-app\n image: myrepo/swift-k8s-demo:1.0.0\n ports:\n - containerPort: 8080\n livenessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 10\n readinessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 3\n periodSeconds: 5\n resources:\n requests:\n memory: "64Mi"\n cpu: "100m"\n limits:\n memory: "128Mi"\n cpu: "250m"\n\nservice.yaml:
\napiVersion: v1\nkind: Service\nmetadata:\n name: swift-app-service\nspec:\n selector:\n app: swift-app\n ports:\n - protocol: TCP\n port: 80\n targetPort: 8080\n type: ClusterIP\n\nBeachten Sie die Probes (Prüfungen).