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

Was ist im Container enthalten?

Das Polycrate Base-Image (cargo.ayedo.cloud/library/polycrate) basiert auf python:3.11-slim (Debian) und enthält eine umfassende DevOps-Toolchain.

Kubernetes & Container Tools

Tool Version Beschreibung
kubectl 1.32.1 Kubernetes CLI
helm 3.18.4 Kubernetes Package Manager (+ helm-diff Plugin)
kustomize 5.8.0 Kubernetes Konfiguration
cilium 0.18.5 Cilium CNI CLI
argocd 3.0.6 Argo CD CLI für GitOps
velero 1.16.1 Kubernetes Backup & Migration
docker latest Docker CLI (from docker:dind)
skopeo system Container Image Management

Backup & Encryption Tools

Tool Version Beschreibung
restic 0.18.1 Backup Tool
kopia 0.22.2 Backup Tool (Velero Backend)
age 1.2.1 Moderne Verschlüsselung

Configuration Management

Tool Beschreibung
Ansible Configuration Management und Orchestrierung
ansible-core Ansible Core Engine

Utilities

Tool Beschreibung
git Version Control
jq JSON Processing
yq (v4.45.1) YAML Processing
curl / wget HTTP Clients
openssh-client SSH/SCP Tools
sshpass SSH Password Authentication
rsync File Synchronization
envsubst Environment Variable Substitution
htpasswd HTTP Basic Auth Password Generator

Database Clients

Tool Beschreibung
mariadb-client MySQL/MariaDB CLI
postgresql-client PostgreSQL CLI (psql)

Netzwerk-Tools

Tool Beschreibung
dnsutils DNS Tools (dig, nslookup)
telnet Telnet Client

Python Libraries

Library Beschreibung
kubernetes Kubernetes Python Client
openshift OpenShift Python Client
hcloud Hetzner Cloud Python SDK
pynetbox NetBox API Client
pyvmomi VMware vSphere API Client
docker-compose Docker Compose Python Library
cryptography Cryptographic Primitives
passlib Password Hashing

Ansible Collections

Collection Beschreibung
community.general Allgemeine Module
community.docker Docker Module
community.vmware VMware Module
netbox.netbox NetBox Module

Ansible Roles

Role Beschreibung
geerlingguy.docker Docker Installation
geerlingguy.ntp NTP Konfiguration

Cloud Provider CLIs

Cloud Provider CLIs (AWS, Azure, GCloud) sind nicht im Base-Image enthalten. Installieren Sie diese bei Bedarf über ein Dockerfile.poly:

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

# AWS CLI
RUN pip install awscli

# Azure CLI
RUN pip install azure-cli

# Google Cloud SDK
RUN curl https://sdk.cloud.google.com | bash

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]

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