Zum Inhalt

🐳 Der Polycrate Container

Container-Konzept

Ein Großteil der Magie von Polycrate passiert innerhalb eines Docker-Containers, der mit jeder Ausführung einer Action auf dem System gestartet wird, auf dem Polycrate ausgeführt wird.

Der Container basiert auf einem von ayedo entwickelten und öffentlich verfügbaren Docker-Image (cargo.ayedo.cloud/library/polycrate), das einen Großteil der best-practice Toolchain für den Einsatz von Infrastructure as Code und cloud-nativen Entwicklungsmethoden beinhaltet.

Der Container gibt Ihnen Zugang zu einer state-of-the-art DevOps runtime. Polycrate exportiert einen Snapshot des Workspaces als YAML-Datei und stellt diese Datei innerhalb des Containers zur Verfügung, sodass die gesamte Workspace-Konfiguration problemlos von den Tools innerhalb des Containers eingelesen werden kann.

Container Lifecycle

sequenceDiagram
    participant User
    participant CLI as Polycrate CLI
    participant Docker
    participant Container
    participant Tools as Ansible/kubectl/Terraform

    User->>CLI: polycrate run myblock install
    CLI->>CLI: Erstelle Snapshot
    CLI->>CLI: Generiere Transaction-ID

    alt Custom Dockerfile.poly existiert?
        CLI->>Docker: Build Custom Image
        Docker->>Docker: FROM polycrate:latest + Custom layers
        Docker-->>CLI: Custom Image ready
    end

    CLI->>Docker: docker run polycrate
    Docker->>Container: Start Container
    CLI->>Container: Mount Workspace → /workspace
    CLI->>Container: Mount SSH Keys
    CLI->>Container: Injiziere Environment Variables
    CLI->>Container: Injiziere Snapshot (.snapshot.yml)

    Container->>Container: Setze Working Directory
    Container->>Tools: Führe Playbook/Script aus
    Tools->>Tools: Lese .snapshot.yml
    Tools->>Tools: Greife auf /workspace zu

    alt Action erfolgreich
        Tools-->>Container: Exit 0
        Container-->>Docker: Success
        Docker-->>CLI: Container beendet (Exit 0)
        CLI->>CLI: Schreibe Artifacts
        CLI-->>User: Success
    else Action fehlgeschlagen
        Tools-->>Container: Exit 1
        Container-->>Docker: Failure
        Docker-->>CLI: Container beendet (Exit 1)
        CLI-->>User: Failure mit Error-Output
    end

    CLI->>Docker: Cleanup Container
    Docker->>Docker: Remove Container

    style CLI fill:#e1f5ff
    style Container fill:#fff4e1
    style Tools fill:#e1ffe1

Was ist im Container enthalten?

Das Polycrate Base-Image enthält eine umfassende DevOps-Toolchain:

Infrastructure as Code Tools

  • Ansible - Configuration Management und Orchestrierung
  • Terraform - Cloud Infrastructure Provisioning
  • kubectl - Kubernetes CLI
  • Helm - Kubernetes Package Manager

Cloud Provider CLIs

  • aws-cli - AWS Command Line Interface
  • az - Azure CLI
  • gcloud - Google Cloud SDK
  • hcloud - Hetzner Cloud CLI

Utilities

  • git - Version Control
  • jq / yq - JSON/YAML Processing
  • curl / wget - HTTP Clients
  • ssh / scp - SSH Tools
  • python3 - Scripting und Ansible
  • bash / zsh - Shell Environment

Python Libraries

  • Boto3 (AWS SDK)
  • Azure SDK
  • Google Cloud Client
  • Kubernetes Python Client
  • Ansible Collections

Container-Umgebung

Mounts

Wenn der Container startet, werden folgende Pfade gemountet:

graph LR
    Host[Host-System] --> WS[Workspace-Root]
    Host --> SSH[SSH-Keys]
    Host --> Docker[Docker Socket optional]

    WS -->|mount| CWS[Container: /workspace]
    SSH -->|mount| CSSH[Container: ~/.ssh/]
    Docker -->|mount| CDocker[Container: /var/run/docker.sock]

    style Host fill:#e1f5ff
    style CWS fill:#e1ffe1
    style CSSH fill:#e1ffe1
    style CDocker fill:#fff4e1

Host → Container Mappings: - $WORKSPACE_ROOT/workspace (read/write) - $WORKSPACE_ROOT/id_rsa~/.ssh/id_rsa (read-only) - /var/run/docker.sock/var/run/docker.sock (optional, für Docker-in-Docker)

Environment Variables

Der Container erhält automatisch folgende Environment Variables:

POLYCRATE_WORKSPACE_NAME="my-workspace"
POLYCRATE_BLOCK_NAME="my-block"
POLYCRATE_ACTION_NAME="install"
POLYCRATE_TRANSACTION_ID="550e8400-e29b-41d4-a716-446655440000"
POLYCRATE_SNAPSHOT_FILE="/workspace/.snapshot.yml"

Working Directory

Das Working Directory wird automatisch auf den Block-Pfad gesetzt:

# Bei lokalem Block
WORKDIR=/workspace/blocks/my-block

# Bei geertem Block (from: parent-block)
WORKDIR=/workspace/blocks/parent-block

Siehe Vererbung für Details zum Working Directory bei geerbten Blocks.

Dockerfile.poly

Polycrate sucht standardmäßig nach einem Dockerfile im Workspace (standardmäßig erwartet Polycrate eine Datei namens Dockerfile.poly; der Dateiname kann mit Hilfe des Flags --dockerfile $FILENAME angepasst werden). Wenn ein Dockerfile existiert, wird Polycrate ein Image auf Basis des Dockerfiles bauen und den Container auf Basis dieses Images starten statt des Standard-Images.

Mit Hilfe dieses Custom-Images können Anpassungen am Workspace, z.B. das Installieren von Packages oder Libraries im Polycrate-Container, persistiert werden.

Per Konvention sollte das Dockerfile.poly auf dem offiziellen Polycrate Image basieren, um existente Funktionalität nicht zu brechen:

FROM cargo.ayedo.cloud/library/polycrate:latest

RUN pip install hcloud==1.16.0

Custom Dockerfile.poly Beispiele

Beispiel 1: Python Packages installieren

FROM cargo.ayedo.cloud/library/polycrate:latest

# Python Packages für Custom Ansible Modules
RUN pip install \
    hcloud==1.16.0 \
    proxmoxer==2.0.1 \
    requests==2.31.0

Beispiel 2: Node.js Tools hinzufügen

FROM cargo.ayedo.cloud/library/polycrate:latest

# Node.js und NPM installieren
RUN apk add --no-cache nodejs npm

# Global NPM Packages
RUN npm install -g \
    cdktf-cli \
    serverless

Beispiel 3: Custom CLIs und Tools

FROM cargo.ayedo.cloud/library/polycrate:latest

# Tailscale CLI
RUN wget https://pkgs.tailscale.com/stable/tailscale_1.56.1_amd64.tgz && \
    tar xzf tailscale_1.56.1_amd64.tgz && \
    mv tailscale_1.56.1_amd64/tailscale /usr/local/bin/ && \
    rm -rf tailscale_*

# Velero (Kubernetes Backup Tool)
RUN wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.0/velero-v1.12.0-linux-amd64.tar.gz && \
    tar xzf velero-v1.12.0-linux-amd64.tar.gz && \
    mv velero-v1.12.0-linux-amd64/velero /usr/local/bin/ && \
    rm -rf velero-*

Beispiel 4: Ansible Collections hinzufügen

FROM cargo.ayedo.cloud/library/polycrate:latest

# Custom Ansible Collections
RUN ansible-galaxy collection install \
    community.hashi_vault:4.0.0 \
    community.vmware:3.9.0 \
    netbox.netbox:3.13.0

Beispiel 5: Multi-Cloud Setup

FROM cargo.ayedo.cloud/library/polycrate:latest

# Oracle Cloud CLI
RUN pip install oci-cli

# DigitalOcean CLI
RUN wget -O /usr/local/bin/doctl https://github.com/digitalocean/doctl/releases/download/v1.100.0/doctl-1.100.0-linux-amd64 && \
    chmod +x /usr/local/bin/doctl

# Linode CLI
RUN pip install linode-cli

Image Building

Wenn ein Dockerfile.poly im Workspace existiert:

# Polycrate buildet das Image automatisch vor jeder Action
polycrate run myblock install

# Das entspricht intern:
docker build -f Dockerfile.poly -t polycrate-workspace:latest .
docker run polycrate-workspace:latest ...

Das Image wird nur neu gebaut, wenn sich das Dockerfile.poly geändert hat.

Container Debugging

Container-Logs anzeigen

Polycrate zeigt standardmäßig die gesamte Container-Ausgabe an:

polycrate run myblock install
# Zeigt stdout/stderr vom Container

Interaktive Shell im Container

Für Debugging können Sie eine interaktive Shell im Polycrate-Container starten:

# Mit Standard-Image
docker run -it --rm \
  -v $(pwd):/workspace \
  cargo.ayedo.cloud/library/polycrate:latest \
  /bin/bash

# Mit Custom Dockerfile.poly
docker build -f Dockerfile.poly -t polycrate-workspace:latest .
docker run -it --rm \
  -v $(pwd):/workspace \
  polycrate-workspace:latest \
  /bin/bash

Snapshot inspizieren

Im Container können Sie den Snapshot direkt inspizieren:

# Im Container
cat /workspace/.snapshot.yml
yq eval '.block.config' /workspace/.snapshot.yml

Container-Konfiguration

Container-Flags in workspace.poly

# workspace.poly
name: my-workspace

config:
  container:
    image: cargo.ayedo.cloud/library/polycrate:latest
    dockerfile: Dockerfile.poly

    # Zusätzliche Docker Run Flags
    docker_flags:
      - "--privileged"  # Für Docker-in-Docker
      - "--network=host"  # Host-Netzwerk verwenden

    # Environment Variables
    env:
      MY_CUSTOM_VAR: "value"
      API_KEY: "secret-key"

Docker Socket Mount für Docker-in-Docker

Um Docker-Befehle innerhalb des Containers auszuführen:

config:
  container:
    docker_flags:
      - "-v /var/run/docker.sock:/var/run/docker.sock"

Beispiel-Verwendung:

# Block mit Docker-in-Docker
actions:
  - name: build-and-push
    script:
      - docker build -t myapp:latest .
      - docker push myapp:latest

Best Practices

1. Pinne Image-Versionen

# ✅ Gut: Spezifische Version
FROM cargo.ayedo.cloud/library/polycrate:1.2.3

# ❌ Schlecht: Latest (kann brechen)
FROM cargo.ayedo.cloud/library/polycrate:latest

2. Minimiere Layer

# ✅ Gut: Kombinierte RUN statements
FROM cargo.ayedo.cloud/library/polycrate:latest
RUN apk add --no-cache curl wget && \
    pip install boto3 requests && \
    rm -rf /var/cache/apk/*

# ❌ Schlecht: Viele separate RUN statements
FROM cargo.ayedo.cloud/library/polycrate:latest
RUN apk add --no-cache curl
RUN apk add --no-cache wget
RUN pip install boto3
RUN pip install requests

3. Cleanup in derselben Layer

FROM cargo.ayedo.cloud/library/polycrate:latest

RUN wget https://example.com/tool.tar.gz && \
    tar xzf tool.tar.gz && \
    mv tool /usr/local/bin/ && \
    rm -rf tool*  # Cleanup im selben Layer

4. Versioniere dein Dockerfile.poly

# Im Workspace
git add Dockerfile.poly
git commit -m "Add custom Python packages to container"
git push

5. Teste Custom Images lokal

# Image bauen
docker build -f Dockerfile.poly -t test-polycrate .

# Interaktiv testen
docker run -it --rm test-polycrate /bin/bash

# Tools testen
docker run --rm test-polycrate ansible --version
docker run --rm test-polycrate terraform --version

Troubleshooting

Image Build schlägt fehl

# Prüfen Sie das Dockerfile
cat Dockerfile.poly

# Manuell builden für bessere Fehler-Ausgabe
docker build -f Dockerfile.poly -t polycrate-workspace:latest .

Package Installation schlägt fehl

# APK Cache aktualisieren
FROM cargo.ayedo.cloud/library/polycrate:latest
RUN apk update && apk add --no-cache my-package

Container startet nicht

# Container-Logs prüfen
docker ps -a
docker logs <container-id>

# Image inspizieren
docker images | grep polycrate
docker inspect cargo.ayedo.cloud/library/polycrate:latest

Permission-Probleme mit Mounts

Wenn Sie Permission-Probleme mit gemounteten Verzeichnissen haben:

config:
  container:
    docker_flags:
      - "--user $(id -u):$(id -g)"  # Als aktueller User ausführen

Zusammenhang mit anderen Konzepten

  • Snapshot: Wird in den Container als .snapshot.yml injiziert
  • Actions: Werden im Container ausgeführt
  • Workspaces: Werden in den Container gemountet
  • Transactions: Container-Ausführung ist Teil der Transaction
  • Integrationen: Alle Tools laufen im Container

Container-Vorteile

Der Container-basierte Ansatz garantiert: - Reproduzierbarkeit: Gleiche Umgebung auf jedem System - Isolation: Keine Konflikte mit Host-System - Portabilität: Läuft überall wo Docker läuft - Versionierung: Dockerfile.poly im Git versioniert