6.1 Einführung in die Optimierung von Images
Docker-Images sind zwar kompakt, aber sie nehmen trotzdem Platz ein. Daher ist die Verringerung ihrer Größe eine wichtige Aufgabe, die dazu beiträgt, die Leistung zu verbessern, das Laden und Bereitstellen von Containern zu beschleunigen und die Speicherkosten zu senken. Man kann ein Image optimieren, indem man das Dockerfile verbessert, da es auf verschiedene Weisen organisiert werden kann. In dieser Vorlesung schauen wir uns einige Strategien und Best Practices an, um optimierte und leichtgewichtige Docker-Images zu erstellen.
Warum ist es wichtig, die Größe von Docker-Images zu reduzieren?
- Bereitstellungsgeschwindigkeit: Kleinere Images werden schneller aus dem Docker-Registry geladen und in Containern bereitgestellt, was besonders in automatisierten CI/CD-Systemen wichtig ist.
- Effiziente Ressourcennutzung: Leichtgewichtige Images nehmen weniger Platz auf der Festplatte ein, sparen Netzwerkressourcen beim Übertragen und gewährleisten eine effizientere Nutzung von Rechenressourcen.
- Sicherheit: Kleinere Images enthalten in der Regel weniger unnötige Komponenten, was das Risiko potenzieller Schwachstellen reduziert.
- Einfachere Updates: Das Aktualisieren von leichtgewichtigen Images geht schneller und benötigt weniger Ressourcen, was den Support-Prozess beschleunigt.
6.2 Strategien zur Reduzierung der Docker-Image-Größe
1. Verwendung von minimalen Basisimages
Die Wahl des Basisimages beeinflusst direkt die Größe des finalen Docker-Images. Die Verwendung minimaler Basisimages, wie z. B. alpine
, ermöglicht eine signifikante Reduzierung der Image-Größe.
Beispiel:
Austausch des Images ubuntu
durch alpine
:
# FROM ubuntu:20.04
FROM alpine:3.12
alpine
ist eine leichtgewichtige Linux-Distribution, die etwa 5 MB belegt, während ein ubuntu
-Image hunderte Megabyte belegen kann.
2. Minimierung der Layer-Anzahl
Jede Anweisung im Dockerfile fügt einen neuen Layer zum Image hinzu. Das Zusammenfassen mehrerer Befehle in einer RUN
-Anweisung reduziert die Anzahl der Layer, was zur Verringerung der Gesamtgröße des Images beiträgt.
Beispiel:
Vor der Optimierung:
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
RUN rm -rf /var/lib/apt/lists/*
Nach der Optimierung:
RUN apt-get update && apt-get install -y curl git && rm -rf /var/lib/apt/lists/*
Das Löschen des Paket-Cache (rm -rf /var/lib/apt/lists/*)
reduziert zusätzlich die Image-Größe, indem temporäre Dateien entfernt werden, die während der Installation erstellt wurden.
3. Entfernen temporärer Dateien
Das Entfernen temporärer Dateien und unnötiger Daten nach der Installation von Paketen hilft, das Image sauber und leicht zu halten.
Beispiel:
RUN apt-get update && apt-get install -y curl git && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
4. Verwendung von .dockerignore
Die Datei .dockerignore
hilft dabei, unnötige Dateien und Verzeichnisse aus dem Build-Kontext auszuschließen, wodurch die Image-Größe verringert und der Build-Prozess beschleunigt wird.
Beispiel .dockerignore
:
node_modules
dist
*.log
Dockerfile*
.dockerignore
5. Multi-Stage Builds
Multi-Stage Builds ermöglichen die Verwendung mehrerer Zwischen-Images, um ein finales, leichtes Image zu erstellen, das nur die notwendigen Dateien und Abhängigkeiten enthält.
Beispiel:
# Build-Stufe
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Finale Stufe
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
In diesem Beispiel erstellt die erste Stufe den Build der Anwendung, und die finale Stufe verwendet nur die Build-Ergebnisse, wodurch die Größe des finalen Images reduziert wird.
6. Optimierung der Paketinstallation
Die Installation nur notwendiger Pakete und die Verwendung von Paketmanager-Optionen für eine minimale Installation tragen zur Reduzierung der Image-Größe bei.
Beispiel:
Verwendung der Option --no-install-recommends
für apt-get
:
RUN apt-get update && apt-get install -y --no-install-recommends curl git && \
rm -rf /var/lib/apt/lists/*
7. Komprimierung und Minimierung von Daten
Die Verwendung von Tools zur Komprimierung und Minimierung von Daten hilft, die Image-Größe zu reduzieren.
Beispiel:
Komprimierung von Textdateien und Logdateien:
RUN gzip /path/to/large/file.log
8. Entfernen ungenutzter Bibliotheken und Abhängigkeiten
Das Entfernen ungenutzter Bibliotheken und Abhängigkeiten nach der Installation der notwendigen Pakete hilft, das Image leicht zu halten.
Beispiel:
Für Python-Anwendungen:
RUN pip install --no-cache-dir -r requirements.txt
6.3 Beispiele für optimierte Dockerfiles
Beispiel 1: Optimiertes Dockerfile für Node.js
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
Dieses Beispiel nutzt Multi-Stage-Builds. Zuerst wird die Anwendung in einem Zwischenstadium gebaut, und nur die Build-Ergebnisse werden in das finale Image basierend auf Nginx kopiert.
Beispiel 2: Optimiertes Dockerfile für Python
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
In diesem Beispiel wird ein leichtgewichtiges Basis-Image python:3.9-slim
verwendet. Die Installation der Abhängigkeiten ist in einem separaten Schritt ausgelagert, was es erlaubt, den Docker-Cache zu nutzen, wenn sich die Datei requirements.txt
nicht geändert hat.
GO TO FULL VERSION