Zum Inhalt

Vererbung

Was ist Block-Vererbung?

Blocks können von anderen Blocks erben, was die Wiederverwendung und Anpassung von bestehenden Blocks ermöglicht. Ein Block, der von einem anderen erbt, übernimmt dessen:

  • Konfiguration (config)
  • Actions (können überschrieben werden)
  • Ansible-Inventory (falls vorhanden)
  • Kubeconfig (falls vorhanden)
  • Working Directory (wird auf Elternblock gesetzt)

Blocks, die auf anderen Blocks basieren, werden als dynamische Blocks bezeichnet.

Vererbungs-Hierarchie

classDiagram
    class BaseBlock {
        +name: base
        +kind: generic
        +actions: [init, cleanup]
        +config: base_settings
    }

    class DatabaseBase {
        +name: database-base
        +from: base
        +kind: k8sapp
        +type: db
        +actions: [install, backup, restore]
        +config: db_defaults
    }

    class PostgresBase {
        +name: postgres-base
        +from: database-base
        +flavor: postgresql
        +implementation: cnpg
        +actions: [install, backup, restore, upgrade]
        +config: postgres_defaults
    }

    class MyPostgres {
        +name: my-postgres
        +from: postgres-base
        +config: my_overrides
        +namespace: production
    }

    BaseBlock <|-- DatabaseBase : erbt von
    DatabaseBase <|-- PostgresBase : erbt von
    PostgresBase <|-- MyPostgres : erbt von

    note for MyPostgres "Erbt alle Actions und Config\nvon der gesamten Hierarchie.\nÜberschreibt nur namespace."

In diesem Beispiel: 1. base definiert grundlegende Actions und Konfiguration 2. database-base erbt von base und fügt Datenbank-spezifische Features hinzu 3. postgres-base erbt von database-base und spezialisiert auf PostgreSQL 4. my-postgres erbt von postgres-base und überschreibt nur die Namespace-Konfiguration

Vererbung definieren

Im block.poly

name: my-postgres
from: postgres-base
kind: k8sapp

config:
  namespace: production
  app:
    persistence:
      size: 50Gi  # Überschreibt Default von postgres-base

Im workspace.poly

blocks:
  - name: harbor
    from: cargo.ayedo.cloud/ayedo/k8s/harbor
    config:
      namespace: harbor-prod

Merge-Verhalten

Beim Zusammenführen (Merge) der Konfigurationen gilt:

graph LR
    Parent[Elternblock-Config] --> Merge[Deep Merge]
    Child[Kindblock-Config] --> Merge
    Merge --> Result[Resultierende Config]

    style Child fill:#ffe1e1
    style Result fill:#e1ffe1

Wichtig: Kind-Werte überschreiben Eltern-Werte!

Beispiel: Config-Merge

Elternblock (postgres-base/block.poly):

name: postgres-base
config:
  namespace: default
  app:
    persistence:
      size: 10Gi
      storageClass: standard
    replicas: 1

Kindblock (my-postgres/block.poly):

name: my-postgres
from: postgres-base
config:
  namespace: production
  app:
    persistence:
      size: 50Gi

Resultierende Config:

name: my-postgres
from: postgres-base
config:
  namespace: production  # überschrieben
  app:
    persistence:
      size: 50Gi  # überschrieben
      storageClass: standard  # geerbt
    replicas: 1  # geerbt

Actions vererben und überschreiben

Actions werden ebenfalls vererbt, können aber überschrieben werden:

Elternblock (postgres-base/block.poly):

actions:
  - name: install
    playbook: playbooks/install.yml

  - name: backup
    playbook: playbooks/backup.yml

Kindblock (my-postgres/block.poly):

from: postgres-base

actions:
  - name: install
    playbook: playbooks/custom-install.yml  # Überschreibt Eltern-Action

  - name: migrate
    playbook: playbooks/migrate.yml  # Neue Action

Resultat: Der Kindblock hat drei Actions: - install (überschrieben mit custom-install.yml) - backup (geerbt von Elternblock) - migrate (neu hinzugefügt)

Inventory und Kubeconfig vererben

Blocks können Inventory und Kubeconfig von anderen Blocks erben:

name: my-app
from: base-app

kubeconfig:
  from: my-cluster  # Erbt Kubeconfig von Block "my-cluster"

inventory:
  from: infrastructure  # Erbt Inventory von Block "infrastructure"

Dies ist besonders nützlich, wenn mehrere Blocks dasselbe Ziel-Cluster oder dieselbe Infrastruktur nutzen.

Vererbung von Registry-Blocks

Blocks können auch von Registry-URLs erben:

name: my-harbor
from: cargo.ayedo.cloud/ayedo/k8s/harbor:1.2.0

config:
  namespace: harbor-production

Polycrate pulled den Block automatisch von der Registry und verwendet ihn als Elternblock.

Best Practices

1. Template-Blocks erstellen

Erstellen Sie wiederverwendbare Template-Blocks für häufige Patterns:

name: postgres-template
kind: k8sapp
template: true  # Markiert als Template
type: db
flavor: postgresql

config:
  chart:
    name: postgresql
    repo:
      name: bitnami
      url: https://charts.bitnami.com/bitnami

  # Sinnvolle Defaults
  persistence:
    enabled: true
    size: 10Gi

  monitoring:
    enabled: true

actions:
  - name: install
    playbook: playbooks/install.yml

  - name: backup
    playbook: playbooks/backup.yml

2. Mehrere Vererbungsebenen nutzen

Organisieren Sie Ihre Blocks hierarchisch:

base-block (generic)
  ├── k8s-base (k8sapp basics)
  │   ├── database-k8s (database on k8s)
  │   │   ├── postgres-base (postgres specifics)
  │   │   │   ├── my-postgres-dev
  │   │   │   └── my-postgres-prod
  │   │   └── mysql-base
  │   └── app-k8s (apps on k8s)
  └── linux-base (linuxapp basics)

3. Sinnvolle Overrides

Überschreiben Sie nur das Nötigste:

# ✅ Gut: Nur spezifische Werte überschreiben
name: my-postgres-prod
from: postgres-base
config:
  namespace: production
  app:
    persistence:
      size: 100Gi

# ❌ Schlecht: Gesamte Config wiederholen
name: my-postgres-prod
from: postgres-base
config:
  namespace: production
  chart:
    name: postgresql  # Unnötig, wird geerbt
    version: 12.0.0   # Unnötig, wird geerbt
  # ... alles wiederholt

4. Dokumentation

Dokumentieren Sie die Vererbungshierarchie in README.md:

# my-postgres

Erbt von: `postgres-base``database-base``base`

## Überschriebene Werte:
- `namespace`: production
- `persistence.size`: 100Gi

## Geerbte Features:
- Backup/Restore Actions
- Monitoring-Integration
- HA-Konfiguration

Working Directory

Bei der Ausführung einer Action wird die Working Directory auf die des Elternblocks gesetzt. Das bedeutet, dass Playbooks und Scripts relativ zum Elternblock-Verzeichnis ausgeführt werden.