26 Container-Images und Registries

Container-Images bilden die fundamentale Ausführungseinheit für Anwendungsdeployment in OpenShift und kapseln Anwendungscode, Runtime-Umgebung und Abhängigkeiten in portable, unveränderliche Artefakte. Container Registries fungieren als zentrale Repositories für Image-Distribution und Versionsverwaltung, wobei sie kritische Infrastrukturkomponenten für Container-Orchestrierungsplattformen darstellen.

26.1 Container-Images verstehen

Container-Images implementieren ein geschichtetes Dateisystem-Modell, bei dem jede Schicht differenzielle Änderungen zur vorhergehenden Schicht repräsentiert. Diese Union File System-Architektur ermöglicht effiziente Storage-Nutzung durch Schichtwiederverwendung und optimiert Netzwerktransfers durch inkrementelle Updates.

26.1.1 Image-Schichten verstehen

# Image-Schichten inspizieren
podman inspect nginx:1.20 | grep -A 10 "RootFS"

# Beispiel-Output:
# "RootFS": {
#     "Type": "layers",
#     "Layers": [
#         "sha256:...",  # Base Layer (Ubuntu/Alpine)
#         "sha256:...",  # Nginx Installation
#         "sha256:...",  # Configuration
#         "sha256:...",  # Final Layer
#     ]
# }

Das Open Container Initiative (OCI) Image Format standardisiert Image-Struktur und Metadaten für plattformübergreifende Kompatibilität. Diese Standardisierung gewährleistet Portabilität zwischen verschiedenen Container-Runtimes und Cloud-Providern ohne Vendor Lock-in.

26.1.2 Image-Manifest-Struktur

Image Manifests definieren Metadaten-Strukturen für Multi-Architektur-Images und ermöglichen automatische Plattformauswahl durch Container-Runtimes:

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
  "manifests": [
    {
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "size": 1234,
      "digest": "sha256:...",
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "size": 1234,
      "digest": "sha256:...",
      "platform": {
        "architecture": "arm64",
        "os": "linux"
      }
    }
  ]
}

26.2 Registry-Architekturen

Container Registries dienen als zentrale Repositories für Image-Distribution und unterstützen verschiedene Deployment-Modelle je nach Sicherheits- und Compliance-Anforderungen.

26.2.1 Registry-Typen im Vergleich

Registry-Typ Vorteile Nachteile Verwendung
Public Registry Kostenlos, große Image-Auswahl Internet-Abhängigkeit, limitierte Kontrolle Open-Source-Images, Entwicklung
Private Registry Vollständige Kontrolle, Sicherheit Wartungsaufwand, Kosten Proprietäre Apps, Enterprise
Managed Registry Professional Support, Features Kosten, Vendor Lock-in Produktionsumgebungen

26.2.2 Public Registries

Public Registries wie Docker Hub und Quay.io bieten zentrale Repositories für Open-Source-Images mit globaler Verfügbarkeit und CDN-Integration. Diese öffentlichen Dienste reduzieren Infrastrukturaufwand für Standard-Images, erfordern jedoch Netzwerkkonnektivität und Vertrauen in externe Anbieter.

Bekannte Public Registries: - Docker Hub: registry-1.docker.io (Standard Docker Registry) - Red Hat Quay.io: quay.io (Enterprise-Features, Security-Scanning) - Google Container Registry: gcr.io - Amazon ECR Public: public.ecr.aws

26.2.3 Private Registries

Private Registries ermöglichen organisationsinterne Image-Distribution mit granularer Zugriffskontrolle und Compliance-Governance:

# Private Registry deployment (Harbor Beispiel)
oc new-project harbor-system

# Harbor mit Persistent Storage deployen
oc apply -f https://raw.githubusercontent.com/goharbor/harbor-helm/main/harbor-openshift.yaml

# Registry-Access konfigurieren
oc create secret docker-registry harbor-credentials \
  --docker-server=harbor.company.com \
  --docker-username=admin \
  --docker-password=password \
  --docker-email=admin@company.com

26.2.4 OpenShift Integrated Registry

OpenShift bietet eine integrierte Registry für Cluster-interne Image-Verwaltung:

# Integrated Registry Status prüfen
oc get pods -n openshift-image-registry

# Registry-Route erstellen (falls nicht vorhanden)
oc patch configs.imageregistry.operator.openshift.io/cluster \
  --type merge -p '{"spec":{"defaultRoute":true}}'

# Registry-URL abrufen
oc get route default-route -n openshift-image-registry

26.3 Image-Build-Strategien in OpenShift

OpenShift unterstützt verschiedene Build-Strategien für unterschiedliche Anwendungsanforderungen und Entwicklungs-Workflows.

26.3.1 Source-to-Image (S2I) Builds

Source-to-Image (S2I) Builds automatisieren Image-Erstellung aus Anwendungsquellcode durch Builder-Images mit sprachspezifischen Runtime-Umgebungen:

apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
  name: nodejs-app
spec:
  source:
    type: Git
    git:
      uri: https://github.com/company/nodejs-app.git
      ref: main
  strategy:
    type: Source
    sourceStrategy:
      from:
        kind: ImageStreamTag
        name: nodejs:16
        namespace: openshift
  output:
    to:
      kind: ImageStreamTag
      name: nodejs-app:latest

S2I Builder Images: - nodejs:16 für Node.js-Anwendungen - python:3.9 für Python-Anwendungen - openjdk:11 für Java-Anwendungen - ruby:2.7 für Ruby-Anwendungen

26.3.2 Docker Strategy Builds

Docker Strategy Builds ermöglichen traditionelle Dockerfile-basierte Image-Erstellung:

apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
  name: webapp-docker
spec:
  source:
    type: Git
    git:
      uri: https://github.com/company/webapp.git
    contextDir: /docker  # Dockerfile-Verzeichnis
  strategy:
    type: Docker
    dockerStrategy:
      from:
        kind: ImageStreamTag
        name: nodejs:16
      dockerfile: |
        FROM registry.access.redhat.com/ubi8/nodejs-16
        COPY package*.json ./
        RUN npm install
        COPY . .
        EXPOSE 8080
        CMD ["npm", "start"]
  output:
    to:
      kind: ImageStreamTag
      name: webapp:latest

26.3.3 Custom Strategy Builds

Custom Strategy Builds bieten maximale Flexibilität für spezialisierte Build-Requirements:

apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
  name: custom-build
spec:
  strategy:
    type: Custom
    customStrategy:
      from:
        kind: ImageStreamTag
        name: custom-builder:latest
      env:
      - name: BUILD_ARGS
        value: "--optimize --target=production"

26.3.4 Pipeline Strategy Builds

Pipeline Strategy Builds integrieren mit Tekton für sophisticated CI/CD-Workflows:

apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
  name: pipeline-build
spec:
  strategy:
    type: JenkinsPipeline
    jenkinsPipelineStrategy:
      jenkinsfile: |
        pipeline {
          agent any
          stages {
            stage('Build') {
              steps {
                script {
                  openshift.withCluster() {
                    openshift.withProject() {
                      def build = openshift.startBuild("webapp")
                      build.logs('-f')
                    }
                  }
                }
              }
            }
          }
        }

26.4 Image Streams: OpenShift-spezifische Abstraktion

Image Streams abstrahieren externe Registry-Images durch interne References und ermöglichen Tag-Tracking ohne direkte Registry-Abhängigkeiten.

26.4.1 Image Stream-Definition

apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  name: webapp
spec:
  lookupPolicy:
    local: true  # Ermöglicht lokale Image-Referenzen
  tags:
  - name: latest
    from:
      kind: DockerImage
      name: registry.company.com/webapp:v1.2.0
    importPolicy:
      scheduled: true  # Automatische Updates prüfen
  - name: stable
    from:
      kind: DockerImage
      name: registry.company.com/webapp:v1.1.0

26.4.2 Image Stream-Verwendung

# Image Stream Status anzeigen
oc describe imagestream webapp

# Verfügbare Tags anzeigen
oc get imagestream webapp -o json | jq .spec.tags[].name

# Image Stream-Import auslösen
oc import-image webapp:latest --confirm

# Image-SHA abrufen
oc get istag webapp:latest -o jsonpath='{.image.dockerImageReference}'

26.5 Security und Image-Scanning

Security ist ein kritischer Aspekt bei Container-Images, da Vulnerabilities in Base Images alle darauf aufbauenden Anwendungen betreffen können.

26.5.1 Base Image-Security

Base Image-Security bildet die Grundlage für sichere Container-Images. Minimale Base Images reduzieren Attack Surface und Update-Overhead:

Empfohlene Base Images: - Red Hat UBI (Universal Base Images): registry.access.redhat.com/ubi8/ubi-minimal - Alpine Linux: alpine:3.16 (sehr minimal, musl libc) - Distroless Images: gcr.io/distroless/java (keine Shell, Package Manager) - Scratch: Leeres Image für statische Binaries

# UBI Minimal als sichere Basis
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6

# Nur notwendige Pakages installieren
RUN microdnf install -y nodejs npm && \
    microdnf clean all

# Non-root User erstellen
RUN adduser -r -u 1001 appuser
USER 1001

# Anwendung kopieren
COPY --chown=1001:1001 package*.json ./
RUN npm ci --only=production

COPY --chown=1001:1001 . .
EXPOSE 8080
CMD ["node", "server.js"]

26.5.2 Vulnerability Scanning

OpenShift integriert Vulnerability-Scanning für automatische Sicherheitsbewertung:

# Image-Security-Scanning-Ergebnisse anzeigen
oc get images.image.openshift.io -o json | \
  jq '.items[] | select(.metadata.annotations."openshift.io/image.managed" == "true") | .metadata.name'

# Vulnerability-Details für spezifisches Image
oc describe image sha256:abc123...

# Scanning-Policy konfigurieren
oc patch imagestreamtag webapp:latest -p '{
  "metadata": {
    "annotations": {
      "openshift.io/image.vulnerabilities.scan": "true"
    }
  }
}'

26.5.3 Image Signing und Content Trust

Image Signing implementiert kryptographische Verifikation für Image-Integrität:

# Image signieren (mit cosign)
cosign sign --key cosign.key registry.company.com/webapp:v1.0.0

# Signatur verifizieren
cosign verify --key cosign.pub registry.company.com/webapp:v1.0.0

# OpenShift Policy für signierte Images
oc apply -f - <<EOF
apiVersion: config.openshift.io/v1
kind: Image
metadata:
  name: cluster
spec:
  registrySources:
    allowedRegistries:
    - registry.company.com
    - quay.io
EOF

26.6 Multi-Platform-Images

Multi-Architecture Images unterstützen verschiedene Prozessorarchitekturen (x86_64, ARM64, s390x) durch Platform-spezifische Image-Varianten.

26.6.1 Multi-Arch Build mit Buildah

# Multi-Platform-Build erstellen
buildah bud --platform linux/amd64,linux/arm64,linux/s390x -t webapp:multi .

# Platform-spezifisches Image bauen
buildah bud --platform linux/arm64 -t webapp:arm64 .

# Manifest-Liste erstellen
buildah manifest create webapp:latest
buildah manifest add webapp:latest webapp:amd64
buildah manifest add webapp:latest webapp:arm64
buildah manifest push webapp:latest registry.company.com/webapp:latest

26.6.2 Platform-spezifische Optimierungen

# Multi-Stage Build mit Platform-Optimierungen
FROM --platform=$BUILDPLATFORM golang:1.19 AS builder
ARG BUILDPLATFORM
ARG TARGETPLATFORM

WORKDIR /app
COPY go.* ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
    go build -o webapp .

# Minimales Runtime-Image
FROM scratch
COPY --from=builder /app/webapp /webapp
EXPOSE 8080
ENTRYPOINT ["/webapp"]

26.7 Performance-Optimierung

26.7.1 Layer Caching-Strategien

Layer Caching-Strategien optimieren Build-Performance durch Wiederverwendung unveränderter Image-Schichten:

# Schlechtes Beispiel (Cache-busting)
COPY . /app
RUN npm install

# Gutes Beispiel (Dependencies zuerst)
COPY package*.json /app/
RUN npm ci --only=production
COPY . /app

26.7.2 Multi-Stage Builds

Multi-Stage Builds ermöglichen Build-Optimierung durch separate Build- und Runtime-Umgebungen:

# Build-Stage
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Production-Stage (minimal)
FROM node:16-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --from=builder /app/dist ./dist

USER 1000
EXPOSE 3000
CMD ["node", "dist/server.js"]

26.7.3 Image-Size-Optimierung

# Image-Größe analysieren
podman images webapp:latest

# Layer-Größen detailliert anzeigen
dive webapp:latest

# Nicht verwendete Images bereinigen
podman image prune -a

# Multi-Stage Build-Cache bereinigen
podman builder prune

26.8 Registry-Integration und Authentication

26.8.1 Pull Secrets konfigurieren

Pull Secrets konfigurieren Authentifizierung für private Registries:

# Docker Registry Secret erstellen
oc create secret docker-registry private-registry \
  --docker-server=registry.company.com \
  --docker-username=serviceaccount \
  --docker-password=token123 \
  --docker-email=devops@company.com

# Secret an Service Account binden
oc secrets link default private-registry --for=pull

# Secret an Deployment binden
oc patch deployment webapp -p '{
  "spec": {
    "template": {
      "spec": {
        "imagePullSecrets": [{"name": "private-registry"}]
      }
    }
  }
}'

26.8.2 Registry-Authentication per ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata:
  name: builder
imagePullSecrets:
- name: private-registry
secrets:
- name: private-registry

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  template:
    spec:
      serviceAccountName: builder  # Verwendet automatisch imagePullSecrets
      containers:
      - name: webapp
        image: registry.company.com/webapp:latest

26.9 Registry Mirroring und Air-Gapped-Umgebungen

Registry Mirroring ermöglicht lokale Image-Replikation für Disaster Recovery und Netzwerk-Performance-Optimierung.

26.9.1 Mirror Registry Setup

# Mirror Registry für Air-Gapped-Installation
mkdir -p $HOME/mirror-registry
cd $HOME/mirror-registry

# Mirror Registry installieren
./mirror-registry install \
  --quayHostname mirror.company.com \
  --quayRoot $HOME/mirror-registry

# OpenShift Images spiegeln
oc adm release mirror \
  --from=quay.io/openshift-release-dev/ocp-release:4.12.0-x86_64 \
  --to=mirror.company.com/openshift4 \
  --to-release-image=mirror.company.com/openshift4:4.12.0

26.9.2 Image Content Source Policy

apiVersion: operator.openshift.io/v1alpha1
kind: ImageContentSourcePolicy
metadata:
  name: mirror-registry
spec:
  repositoryDigestMirrors:
  - mirrors:
    - mirror.company.com/openshift4
    source: quay.io/openshift-release-dev/ocp-release
  - mirrors:
    - mirror.company.com/rhel8
    source: registry.access.redhat.com/rhel8

26.10 Image Governance und Policies

26.10.1 Admission Control für Images

Image Policy Webhooks implementieren Admission Control für Image-Deployments:

apiVersion: config.openshift.io/v1
kind: Image
metadata:
  name: cluster
spec:
  registrySources:
    allowedRegistries:
    - registry.company.com
    - quay.io
    - registry.access.redhat.com
    blockedRegistries:
    - docker.io  # Docker Hub blockieren
  additionalTrustedCA:
    name: registry-ca-config

26.10.2 Image Stream Import-Policies

apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  name: webapp
spec:
  tags:
  - name: latest
    from:
      kind: DockerImage
      name: registry.company.com/webapp:latest
    importPolicy:
      scheduled: true      # Automatische Updates
      insecure: false      # Nur HTTPS
    referencePolicy:
      type: Local          # Images lokal cachen

26.10.3 Image Pruning

Automatische Image-Bereinigung für Storage-Optimierung:

# Image-Pruning manuell ausführen
oc adm prune images --confirm

# Pruning-Konfiguration anzeigen
oc get imagepruners.imageregistry.operator.openshift.io/cluster -o yaml

# Pruning-Schedule konfigurieren
oc patch imagepruners.imageregistry.operator.openshift.io/cluster -p '{
  "spec": {
    "schedule": "0 0 * * *",  # Täglich um Mitternacht
    "keepYoungerThan": "24h", # Images jünger als 24h behalten
    "keepTagRevisions": 5     # 5 neueste Tag-Revisionen behalten
  }
}'

26.11 Troubleshooting häufiger Image-Probleme

26.11.1 Image Pull-Probleme

# Pod-Events bei Image-Pull-Problemen prüfen
oc describe pod failing-pod | grep -A 10 Events

# Häufige Fehler:
# - ImagePullBackOff: Authentication, Registry nicht erreichbar
# - ErrImagePull: Image nicht gefunden, falsche Tag
# - InvalidImageName: Syntax-Fehler im Image-Namen

26.11.2 Registry-Connectivity testen

# Registry-Erreichbarkeit testen
curl -I https://registry.company.com/v2/

# Authentication testen
podman login registry.company.com

# Image-Pull manuell testen
podman pull registry.company.com/webapp:latest

26.11.3 Build-Probleme diagnostizieren

# Build-Logs anzeigen
oc logs build/webapp-1 -f

# Build-Konfiguration validieren
oc describe buildconfig webapp

# Build-Pod-Events prüfen
oc get events --field-selector involvedObject.name=webapp-1-build

26.11.4 Image-Inspection und Debugging

# Image-Details inspizieren
skopeo inspect docker://registry.company.com/webapp:latest

# Image-Layers analysieren
skopeo inspect --raw docker://registry.company.com/webapp:latest | jq .

# Container-Filesystem untersuchen
oc debug deployment/webapp

26.12 Performance-Monitoring

26.12.1 Image-Pull-Performance

# Image-Pull-Zeiten messen
time podman pull registry.company.com/webapp:latest

# Registry-Pull-Through-Cache-Hits prüfen
oc get metrics -n openshift-image-registry

26.12.2 Storage-Usage überwachen

# Registry-Storage-Verbrauch
oc exec -n openshift-image-registry deployment/image-registry -- \
  du -sh /registry

# Image-Storage pro Projekt
for project in $(oc get projects -o name | cut -d'/' -f2); do
  echo "=== $project ==="
  oc get images -o json | jq -r --arg ns "$project" '
    .items[] | 
    select(.dockerImageMetadata.Config.Labels."io.openshift.build.namespace" == $ns) |
    .dockerImageMetadata.Size'
done