Einheit 3.3: CI/CD-Pipelines für IONOS CLOUD
Einführung
Sie haben TaskBoard containerisiert, die Images in die IONOS CLOUD Container Registry hochgeladen und manuell in Managed Kubernetes bereitgestellt. Das Ausführen von docker push und kubectl apply vom Laptop aus skaliert nicht auf ein Team und übersteht auch nicht den Moment, in dem Sie vergessen, welches Image-Tag in der Produktion läuft. In dieser Einheit verdrahten Sie den gesamten Ablauf so, dass git push der einzige manuelle Schritt ist. Ein Commit löst einen Build aus, das Image landet in der Container Registry mit dem Git-SHA als Tag, und das neue Tag wird im Cluster ausgerollt.
Sie unterwerfen auch die Infrastruktur derselben Disziplin. Terraform plan wird bei jedem Pull Request ausgeführt, damit Reviewer den Diff sehen, bevor sich etwas ändert, und apply wird nur nach dem Merge ausgeführt. Zwei IONOS CLOUD-Einschränkungen prägen jede Pipeline, die Sie hier schreiben: Die API ist asynchron, daher müssen Deploys auf die Bereitschaft warten, statt sie vorauszusetzen. Und die Authentifizierung der Container Registry erfolgt ausschließlich über tokenbasiertes docker login, ohne RBAC und ohne teamweise Repositories, sodass die Zugangsdaten in CI-Secrets gespeichert werden.
1. Pipeline-Design für IONOS CLOUD
Eine CI/CD-Pipeline auf IONOS CLOUD gliedert sich in zwei getrennte Abläufe, die denselben Job nicht teilen sollten. Anwendungänderungen folgen build -> test -> push image -> deploy to Kubernetes. Infrastrukturänderungen folgen plan -> apply. Wenn beide vermischt werden, kann ein Tippfehler in einem Kubernetes-Manifest eine dringende Infrastrukturkorrektur blockieren, und eine langsame terraform apply verzögert jede Anwendungsbereitstellung.
Der Anwendungsablauf endet mit kubectl apply oder, genauer gesagt, mit einer kontrollierten Aktualisierung des Image-Tags für eine bestehende Deployment. Der Infrastrukturablauf endet mit terraform apply für Ihre IONOS CLOUD-Ressourcen. Beide Abläufe authentifizieren sich bei IONOS CLOUD, verwenden jedoch unterschiedliche Zugangsdaten: Der Anwendungsablauf benötigt ein Container Registry-Token und eine kubeconfig, während der Infrastrukturablauf ein IONOS_TOKEN-Bearer-Token für die Cloud API benötigt.
1.1 Images mit dem Git-SHA kennzeichnen
Stellen Sie niemals :latest bereit. Ein veränderliches Tag macht Rollbacks mehrdeutig und unterbricht die Verknüpfung zwischen einem laufenden Pod und dem Commit, der ihn erzeugt hat. Kennzeichnen Sie jedes Image mit dem unveränderlichen Git-SHA, damit die laufende Revision stets nachvollziehbar ist.
# Derive an immutable tag from the commit
REGISTRY="taskboard.cr.de-fra.ionos.com"
SHA=$(git rev-parse --short HEAD)
IMAGE="${REGISTRY}/taskboard-api:${SHA}"
docker build -t "${IMAGE}" ./api
docker push "${IMAGE}"
Der Registry-Hostname folgt dem Muster {registry-name}.cr.{location-with-dash}.ionos.com, beispielsweise tue1608es.cr.es-vit.ionos.com. Der Hostname wird erst zugewiesen, nachdem die Registry den Zustand „Running“ erreicht hat, und ist bis dahin leer. Daher muss eine Pipeline, die eine neue Registry bereitstellt, den Hostname aus der Terraform-Ausgabe lesen, anstatt ihn hart zu kodieren.
1.2 Trennung der Repositories für Anwendung und Infrastruktur
Bewahren Sie Terraform in einem Infrastruktur-Repository auf und die Kubernetes-Manifeste sowie den Anwendungscode in einem Anwendungs-Repository. Das Infrastruktur-Repository wird bei Merge angewendet; das Anwendungs-Repository baut und deployt bei Push. Diese Trennung hält den Auswirkungsbereich einer fehlerhaften Änderung klein und ermöglicht es, verschiedenen Teams unterschiedliche Zugriffsrechte zu erteilen.
taskboard-app/ # build, push, kubectl deploy
api/Dockerfile
k8s/deployment.yaml
.github/workflows/deploy.yml
taskboard-infra/ # terraform plan/apply
main.tf
modules/
.github/workflows/terraform.yml
2. GitHub Actions für IONOS CLOUD
Ein GitHub Actions Workflow für den Anwendungsfluss hat drei logische Stufen in einem einzelnen Job: Build und Test, docker login und push, dann Deployment auf Managed Kubernetes. Die IONOS CLOUD spezifischen Teile sind der Registry Login (tokenbasiert) und die Abholung der kubeconfig.
2.1 Speichern von IONOS CLOUD Secrets
Tokens gehören niemals in das Repository. Speichern Sie das Container Registry Token und die kubeconfig als Repository- oder Umgebungs-Secrets. Das Container Registry Token Passwort wird nur einmal bei der Erstellung angezeigt, daher sofort erfassen und in CI speichern. Ein Registry Token kann dauerhaft oder temporär mit einem expiryDate sein, und bei Ablauf wird das Token gelöscht und nicht deaktiviert, was bedeutet, dass ein abgelaufenes Token in CI den docker login vollständig scheitern lässt, anstatt stillschweigend zu degradieren.
| Secret Name | Inhalte | Verwendet von |
|---|---|---|
CR_USERNAME |
Container Registry Token Name | docker login |
CR_PASSWORD |
Container Registry Token Passwort (einmalig angezeigt) | docker login |
KUBECONFIG |
base64-kodierte kubeconfig aus Terraform Output | kubectl |
IONOS_TOKEN |
Cloud API Bearer Token | Terraform / ionosctl |
2.2 Der Deployment Workflow
# .github/workflows/deploy.yml
name: deploy-taskboard
on:
push:
branches: [main]
env:
REGISTRY: taskboard.cr.de-fra.ionos.com
IMAGE_NAME: taskboard-api
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set image tag
run: echo "TAG=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
- name: Run tests
run: |
cd api
pip install -r requirements.txt
pytest
- name: Log in to IONOS CLOUD Container Registry
run: echo "${{ secrets.CR_PASSWORD }}" | docker login "$REGISTRY" \
-u "${{ secrets.CR_USERNAME }}" --password-stdin
- name: Build and push image
run: |
docker build -t "$REGISTRY/$IMAGE_NAME:$TAG" ./api
docker push "$REGISTRY/$IMAGE_NAME:$TAG"
- name: Configure kubectl
run: |
mkdir -p "$HOME/.kube"
echo "${{ secrets.KUBECONFIG }}" | base64 -d > "$HOME/.kube/config"
- name: Deploy to Managed Kubernetes
run: |
kubectl set image deployment/taskboard-api \
api="$REGISTRY/$IMAGE_NAME:$TAG"
kubectl rollout status deployment/taskboard-api --timeout=180s
kubectl set image aktualisiert nur das Feld „image" im vorhandenen Deployment, was einen rollenden Update auslöst, ohne das gesamte Manifest erneut anzuwenden. Der Schritt kubectl rollout status blockiert, bis der Rollout abgeschlossen ist oder das Timeout ausgelöst wird. Dies ist der korrekte Weg, um ein fehlgeschlagenes Deployment als fehlgeschlagene Pipeline anzuzeigen. Die kubeconfig selbst stammt aus dem Managed Kubernetes-Cluster: Sie wird entweder aus den Cluster-Einstellungen heruntergeladen oder, in einer automatisierten Pipeline, aus der Terraform-Ausgabe gelesen (dies wird in Einheit 3.2 behandelt) und der base64-kodierte Wert wird als Secret KUBECONFIG gespeichert.
3. GitLab CI für IONOS CLOUD
GitLab CI drückt denselben Ablauf als diskrete Stufen in .gitlab-ci.yml aus. Die IONOS CLOUD-spezifischen Aspekte sind identisch: tokenbasiertes Docker-Login zum Registry und ein kubeconfig für den Cluster. GitLab stellt einen Docker-in-Docker-Dienst zum Erstellen von Images innerhalb der Pipeline bereit.
3.1 Pipeline-Stufen
# .gitlab-ci.yml
stages: [test, build, deploy]
variables:
REGISTRY: taskboard.cr.de-fra.ionos.com
IMAGE_NAME: taskboard-api
test:
stage: test
image: python:3.12
script:
- cd api && pip install -r requirements.txt && pytest
build:
stage: build
image: docker:24
services: [docker:24-dind]
script:
- export TAG=$CI_COMMIT_SHORT_SHA
- echo "$CR_PASSWORD" | docker login "$REGISTRY" -u "$CR_USERNAME" --password-stdin
- docker build -t "$REGISTRY/$IMAGE_NAME:$TAG" ./api
- docker push "$REGISTRY/$IMAGE_NAME:$TAG"
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- echo "$KUBECONFIG_B64" | base64 -d > /tmp/kubeconfig
- export KUBECONFIG=/tmp/kubeconfig
- kubectl set image deployment/taskboard-api api="$REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA"
- kubectl rollout status deployment/taskboard-api --timeout=180s
only: [main]
Speichern Sie CR_USERNAME, CR_PASSWORD und KUBECONFIG_B64 als maskierte, geschützte CI/CD-Variablen in den GitLab-Projekteinstellungen. Geschützte Variablen werden nur Pipelines zur Verfügung gestellt, die auf geschützten Branches ausgeführt werden. Dadurch werden Produktionszugangsdaten aus Feature-Branch-Pipelines ferngehalten. CI_COMMIT_SHORT_SHA ist das GitLab-Äquivalent zum git-SHA-Tag und bietet dieselbe Garantie für ein unveränderliches Tag wie im GitHub Actions-Beispiel.
4. Terraform in CI/CD
Änderungen an der Infrastruktur verdienen eine Überprüfung, bevor sie IONOS CLOUD-Ressourcen betreffen, da terraform apply abrechenbare Ressourcen erstellt und diese auch zerstören kann. Das Standardmuster führt terraform plan bei jedem Pull Request aus und postet den Plan als PR-Kommentar. Anschließend wird terraform apply erst nach dem Merge auf main ausgeführt. So erhalten die Reviewer die genaue Differenz, und niemand kann ungeprüfte Änderungen anwenden.
4.1 Plan bei PR, Apply bei Merge
# .github/workflows/terraform.yml
name: terraform
on:
pull_request:
branches: [main]
push:
branches: [main]
env:
IONOS_TOKEN: ${{ secrets.IONOS_TOKEN }}
jobs:
plan:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform plan -no-color -out=tfplan
- run: terraform show -no-color tfplan > plan.txt
- uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const plan = fs.readFileSync('plan.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '```\n' + plan.slice(0, 60000) + '\n```'
});
apply:
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform apply -auto-approve
Der IONOS CLOUD Terraform Provider authentifiziert sich über die Umgebungsvariable IONOS_TOKEN, sodass das Übergeben des Bearer-Tokens als Umgebungsvariable alles ist, was der Provider-Block benötigt. Der Provider fragt die asynchronen Operationen von IONOS CLOUD intern ab, sodass terraform apply blockiert, bis jede Ressource ihren bereitgestellten Zustand erreicht hat, bevor er fortfährt. Das bedeutet, dass die Pipeline keine eigenen Readiness-Loops für Terraform-verwaltete Ressourcen benötigt.
4.2 Remote State für CI/CD
Lokaler State funktioniert in CI/CD nicht, da jeder Runner mit einem sauberen Checkout startet. Verwenden Sie das S3-kompatible IONOS CLOUD Object Storage Backend, damit jeder Pipeline-Lauf denselben State liest und schreibt und State-Locking verhindert, dass zwei parallele Applies ihn beschädigen.
terraform {
backend "s3" {
bucket = "taskboard-tfstate"
key = "infra/terraform.tfstate"
region = "de"
endpoints = { s3 = "https://s3-eu-central-1.ionoscloud.com" }
skip_credentials_validation = true
skip_region_validation = true
skip_requesting_account_id = true
}
}
Object Storage verwendet die Authentifizierung mit Access Key und Secret Key, nicht Bearer-Tokens, daher sind die Backend-Anmeldedaten von IONOS_TOKEN getrennt. Stellen Sie sie der Pipeline als Secrets AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY bereit, die das S3-Backend automatisch liest.
5. Deployment-Strategien und Rollback
Die Standard-Deployment-Strategie von Kubernetes ist RollingUpdate, die Pods schrittweise ersetzt, damit der Service während eines Deploys verfügbar bleibt. Für Workloads, die nicht zwei Versionen gleichzeitig ausführen können, verwenden Sie Recreate, die alle alten Pods beendet, bevor neue gestartet werden, was zu einer kurzen Unterbrechung führt.
5.1 Konfiguration der Strategie
apiVersion: apps/v1
kind: Deployment
metadata:
name: taskboard-api
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels: { app: taskboard-api }
template:
metadata:
labels: { app: taskboard-api }
spec:
imagePullSecrets:
- name: cr-pull-secret
containers:
- name: api
image: taskboard.cr.de-fra.ionos.com/taskboard-api:abc1234
readinessProbe:
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 5
maxUnavailable: 0 stellt sicher, dass während des Rollouts keine Kapazität verloren geht, und readinessProbe stellt sicher, dass der Traffic nur Pods erreicht, die einen gesunden Status melden. Der Eintrag imagePullSecrets verweist auf das Token der Container Registry, da der Cluster Bilder mit denselben tokenbasierten Zugangsdaten abruft, die Ihre Pipeline zum Hochladen verwendet hat. Canary- und Blue-Green-Releases sind mit parallelen Deployments und Traffic Shifting möglich oder mit einem GitOps-Tool wie ArgoCD, das in Einheit 5.3 als Muster behandelt wird und nicht hier.
5.2 Zurückrollen
Wenn ein Deployment fehlschlägt, rollen Sie die Anwendung mit kubectl rollout undo zurück. Dieser Befehl stellt das Deployment auf seine vorherige Revision wieder her, ohne etwas neu zu bauen.
# Inspect revision history
kubectl rollout history deployment/taskboard-api
# Roll back to the immediately previous revision
kubectl rollout undo deployment/taskboard-api
# Roll back to a specific revision
kubectl rollout undo deployment/taskboard-api --to-revision=4
Da jedes Bild mit seinem git-SHA markiert ist, können Sie auch deterministisch mit kubectl set image auf ein bekanntes, einwandfreies Tag zurückrollen. Bei der Infrastruktur bedeutet Rollback, den fehlerhaften Commit zurückzusetzen und terraform apply erneut auszuführen, wodurch die aktiven Ressourcen in den committeden Zustand zurückversetzt werden. Falls der Zustand selbst beschädigt ist, stellen Sie ihn aus einer versionierten Kopie im Object Storage-Backend wieder her.
6. Aufbau einer Terraform-Modulbibliothek
Sobald die Infrastruktur von TaskBoard funktioniert, extrahieren Sie die wiederkehrenden Muster in Module, damit der nächste Dienst nicht bei Null beginnt. Ein Modul fasst verwandte Ressourcen hinter Eingabevariablen zusammen und stellt Ausgaben bereit, wodurch ein ausführlicher Stack in wenige Zeilen Aufrufcode umgewandelt wird.
6.1 Modulstruktur
# modules/k8s-service/variables.tf
variable "name" { type = string }
variable "node_count" { type = number, default = 2 }
variable "k8s_version" { type = string, default = "1.34" }
# modules/k8s-service/main.tf
resource "ionoscloud_k8s_cluster" "this" {
name = var.name
k8s_version = var.k8s_version
}
resource "ionoscloud_k8s_node_pool" "this" {
name = "${var.name}-pool"
k8s_cluster_id = ionoscloud_k8s_cluster.this.id
node_count = var.node_count
# ... cores, ram, availability_zone, etc.
}
# modules/k8s-service/outputs.tf
output "cluster_id" { value = ionoscloud_k8s_cluster.this.id }
Die unterstützten Kubernetes-Versionen sind 1.34, 1.33, 1.32 und 1.31. Daher sollte eine bekannte, funktionierende Version in den Modulstandardwerten festgelegt und Aufrufenden ermöglicht werden, diese zu überschreiben. Node-Pools können Servertypen mit Dedicated Core oder vCPU nutzen. Ein Node-Pool hat ein hartes Maximum von 100 Nodes und ein empfohlenes Maximum von 20. Prüfen Sie daher node_count gegen diese Grenzen, anstatt einen Tippfehler zu tolerieren, der einen überdimensionierten Pool provisioniert.
6.2 Verwenden des Moduls
module "taskboard" {
source = "./modules/k8s-service"
name = "taskboard-prod"
node_count = 3
}
output "taskboard_cluster" {
value = module.taskboard.cluster_id
}
Versionieren Sie Ihr Modul-Repository mit Git-Tags und verweisen Sie auf ein bestimmtes Tag in source, damit eine nachgelagerte Änderung am Modul einen vorhandenen Stack nicht stillschweigend verändert. So verwandelt ein Team eine funktionierende Bereitstellung in eine wiederverwendbare Bibliothek.
Schnellreferenz für die API
Wichtige Endpunkte, die von CI/CD-Pipelines auf IONOS CLOUD verwendet werden:
| Methode | Endpunkt | Beschreibung |
|---|---|---|
POST |
/containerregistries/registries/{id}/tokens |
Erstellen eines Registry-Tokens für CI |
GET |
/k8s/{clusterId}/kubeconfig |
Abrufen der kubeconfig für Deployment |
GET |
/k8s/{clusterId}/nodepools |
Auflisten der Node-Pools eines Clusters |
GET |
/requests/{requestId}/status |
Abfragen der asynchronen Operation bis DONE |
DELETE |
/containerregistries/registries/{id}/repositories/{name} |
Löschen eines Repositories (Name URL-codiert) |
Basis-URL: https://api.ionos.com/cloudapi/v6
Authentifizierung: Authorization: Bearer <token>
Code Lab
Ziel: Erstellen einer GitHub Actions Pipeline, die TaskBoard bei jedem Push auf main baut, hochlädt und auf Managed Kubernetes deployt.
Voraussetzungen:
- IONOS CLOUD Konto mit API Token (
IONOS_TOKEN) - Eine bestehende Container Registry und ein Managed Kubernetes Cluster (aus den Einheiten 3.1 und 3.2)
- Ein GitHub Repository für die TaskBoard Anwendung
docker,kubectlundionosctllokal installiert
Schritt 1: Erstellen eines Registry Tokens für CI
ionosctl container-registry token create \
--registry-id "$REGISTRY_ID" --name ci-deploy
Erwartete Ausgabe:
TokenId Name Status ExpiryDate
a1b2c3d4 ci-deploy enabled -
Password: <shown once - copy it now>
Schritt 2: Secrets in GitHub speichern
gh secret set CR_USERNAME --body "ci-deploy"
gh secret set CR_PASSWORD --body "<password from step 1>"
gh secret set KUBECONFIG --body "$(ionosctl k8s kubeconfig get \
--cluster-id "$CLUSTER_ID" | base64 -w0)"
Erwartete Ausgabe:
✓ Set secret CR_USERNAME
✓ Set secret CR_PASSWORD
✓ Set secret KUBECONFIG
Schritt 3: Workflow-Datei hinzufügen
Committe .github/workflows/deploy.yml aus Abschnitt 2.2 in das Repository.
Erwartete Ausgabe:
[main 9f3c1ab] add deploy workflow
1 file changed, 38 insertions(+)
Schritt 4: Pipeline auslösen
git commit --allow-empty -m "trigger deploy"
git push origin main
Erwartete Ausgabe:
To github.com:you/taskboard-app.git
8d2e1f0..9f3c1ab main -> main
Schritt 5: Ausführung beobachten
gh run watch
Erwartete Ausgabe:
✓ build-and-deploy succeeded
✓ Build and push image
✓ Deploy to Managed Kubernetes
Schritt 6: Rollout auf dem Cluster überprüfen
kubectl get deployment taskboard-api -o wide
Erwartete Ausgabe:
NAME READY IMAGE
taskboard-api 3/3 taskboard.cr.de-fra.ionos.com/taskboard-api:9f3c1ab
Prüfliste:
- [ ] Das Image mit dem git-SHA-Tag existiert in der Container Registry
- [ ] Das Deployment-Image entspricht dem gepushten Tag
- [ ]
kubectl rollout statusmeldete Erfolg in der Pipeline - [ ] Ein zweiter Push erzeugt ein neues SHA-Tag und ein sauberes Rolling Update
Aufräumarbeiten:
gh secret delete CR_USERNAME CR_PASSWORD KUBECONFIG
ionosctl container-registry token delete --registry-id "$REGISTRY_ID" --token-id "$TOKEN_ID"
Häufige Fehler
Fehler von Entwicklerinnen und Entwicklern, die bei der Nutzung von CI/CD auf IONOS CLOUD vermieden werden sollten:
-
Das Registry-Hostname hartkodieren, bevor das Registry den Zustand „Running“ erreicht hat
- Problem: Die Pipeline schlägt bei docker login mit einem DNS-Auflösungsfehler für einen leeren Hostnamen fehl.
- Ursache: Der Registry-Hostname wird erst zugewiesen, nachdem das Registry den Zustand „Running“ erreicht hat. Ein neu bereitgestelltes Registry hat daher noch keinen Hostnamen.
- Lösung: Den Hostnamen aus der Terraform-Ausgabe lesen, statt ihn hart zu kodieren, und den Push-Job daran koppeln, dass das Registry bereit ist:
output "registry_hostname" { value = ionoscloud_container_registry.this.hostname } -
Erwartung, dass ein Kubernetes LoadBalancer Service ein echter externer Load Balancer ist
- Problem: Die Durchsatzrate erreicht ein Plateau und die Quell-IP jeder Anfrage wird als clusterinterne Adresse angezeigt, wodurch Ratenbegrenzungen und Audit-Protokolle beeinträchtigt werden.
- Ursache: Ein LoadBalancer Service auf Managed Kubernetes provisioniert keinen externen LB. IONOS CLOUD reserviert eine statische öffentliche IP und weist sie einem Worker-Node als sekundäre IP zu. kube-proxy NATet den Traffic zum Pod, wodurch der Durchsatz an der öffentlichen Obergrenze dieses einzelnen Nodes begrenzt wird und die Quell-IP verloren geht.
- Lösung: Setzen Sie
externalTrafficPolicy: Local, um die Quell-IP zu erhalten, und setzen Sie vor den Service einen separat provisionierten Managed ALB oder verteilen Sie den Traffic über mehrere LB-IPs, um den Durchsatz eines einzelnen Nodes zu überschreiten:
spec: type: LoadBalancer externalTrafficPolicy: Local -
Ausführen von Terraform mit lokalem State in CI/CD
- Problem: Jeder Pipeline-Lauf beginnt mit leerem State, daher versucht
terraform apply, Ressourcen neu zu erstellen, die bereits existieren, und meldet Fehler bei doppelten Namen. - Ursache: CI-Runner checken einen sauberen Arbeitsbereich ohne State-Datei aus, und es ist kein gemeinsamer Backend konfiguriert.
- Lösung: Konfigurieren Sie das S3-kompatible Object Storage-Backend, damit alle Läufe denselben State teilen, und stellen Sie Access Key und Secret Key als Pipeline-Secrets bereit:
export AWS_ACCESS_KEY_ID="$IONOS_S3_KEY" export AWS_SECRET_ACCESS_KEY="$IONOS_S3_SECRET" terraform init - Problem: Jeder Pipeline-Lauf beginnt mit leerem State, daher versucht
Zusammenfassung
Sie können den gesamten Build-Test-Deploy-Zyklus nun aus einer einzelnen git push steuern. Die Anwendungspipeline baut einen Container, kennzeichnet ihn mit dem git SHA, meldet sich mit einem tokenbasierten docker login bei der IONOS CLOUD Container Registry an, schiebt das Image hoch und rollt es mit einem readiness-gesteuerten kubectl set image und kubectl rollout status in Managed Kubernetes aus. Die Infrastrukturpipeline hält Terraform ehrlich, indem sie bei Pull Requests plant und erst bei Merge anwendet, gestützt durch einen gemeinsamen Zustand in Object Storage. Wenn etwas schiefgeht, bringen kubectl rollout undo und ein zurückgenommener Terraform-Commit Sie in einen bekannten, funktionierenden Zustand zurück, und Ihre extrahierte Modulbibliothek bedeutet, dass der nächste Dienst diese Muster wiederverwendet, statt sie neu zu erfinden.
Wichtige Punkte:
- Trennen Sie den Anwendungsfluss (
build -> test -> push -> deploy) vom Infrastrukturfluss (plan -> apply); teilen Sie niemals einen Job zwischen ihnen - Kennzeichnen Sie jedes Image mit dem unveränderlichen git SHA, niemals mit
:latest, damit die laufende Revision immer nachverfolgbar ist und Rollbacks deterministisch sind - Container Registry Tokens werden einmalig bei der Erstellung angezeigt und bei Ablauf gelöscht; speichern Sie sie als CI-Geheimnisse und ziehen Sie Images mit denselben tokenbasierten Zugangsdaten
- Führen Sie
terraform planbei PRs undterraform applybei Merge aus, mit gemeinsamem S3-kompatiblem Zustand in Object Storage undIONOS_TOKENals Geheimnis - Rollen Sie Anwendungen mit
kubectl rollout undozurück und Infrastruktur, indem Sie den Commit zurücknehmen und erneut anwenden
Wichtige Begriffe:
- Unveränderliches Tag: Ein Container-Image-Tag, das aus dem git SHA abgeleitet wird und sich nie ändert, wodurch jeder laufende Pod mit dem exakten Commit verknüpft wird, der ihn gebaut hat.
- Rolling Update: Die Standard-Kubernetes-Deployment-Strategie, die Pods inkrementell ersetzt, damit der Dienst während eines Deploys verfügbar bleibt.
- Plan bei PR: Das Terraform-CI-Muster, bei dem
terraform planbei Pull Requests ausgeführt und der Diff zur Überprüfung gepostet wird, bevor einapplyerfolgt. - Remote State Backend: Ein gemeinsamer Terraform-Zustandspeicher (S3-kompatibles Object Storage auf IONOS CLOUD), der es jedem CI-Lauf ermöglicht, denselben Zustand mit Sperren zu lesen und zu schreiben.
- imagePullSecret: Ein Kubernetes-Secret, das Container Registry Token-Zugangsdaten enthält, damit der Cluster private Images ziehen kann.
Nächste Schritte
Weiter lernen: Einheit 3.4: Wissensprüfung - Container und CI/CD
Verwandte Themen: