Auf dieser Seite wird beschrieben, wie Sie kleinere Docker-Images erstellen.
Kleinere Container erstellen
Beim Containerisieren einer Anwendung werden manchmal Dateien, die zur Laufzeit nicht benötigt werden, z. B. Abhängigkeiten bei der Build-Erstellung oder Zwischendateien, versehentlich in das Container-Image aufgenommen. Diese nicht benötigten Dateien erhöhen potenziell die Größe des Container-Images und verursachen dann zusätzlichen Zeitaufwand und zusätzliche Kosten, wenn das Image zwischen der Docker-Registry und der Containerlaufzeit verschoben wird.
Zur Reduzierung der Größe des Container-Images trennen Sie die Erstellung der Anwendung mit den dafür verwendeten Tools von der Zusammenstellung des Laufzeitcontainers.
Cloud Build bietet eine Reihe von Docker-Containern mit gängigen Entwicklertools wie Git, Docker und der Google Cloud CLI. Mit diesen Tools können Sie eine Build-Konfigurationsdatei für das Erstellen der Anwendung in einem Schritt und für das Zusammenstellen der endgültigen Laufzeitumgebung in einem weiteren Schritt definieren.
Wenn Sie beispielsweise eine Java-Anwendung erstellen, für die Dateien wie Quellcode, Anwendungsbibliotheken, Build-Systeme, Build-System und das JDK haben Sie vielleicht ein Dockerfile, das wie das Folgendes:
FROM java:8
COPY . workdir/
WORKDIR workdir
RUN GRADLE_USER_HOME=cache ./gradlew buildDeb -x test
RUN dpkg -i ./gate-web/build/distributions/*.deb
CMD ["/opt/gate/bin/gate"]
Im obigen Beispiel lädt Gradle, das zum Erstellen des Pakets verwendet wird, eine große Anzahl von Bibliotheken zur Verwendung herunter. Diese Bibliotheken sind für das Erstellen des Pakets erforderlich, werden jedoch zur Laufzeit nicht benötigt. Alle Laufzeitabhängigkeiten sind im Paket gebündelt.
Mit jedem Befehl im Dockerfile
wird eine neue Ebene im Container erstellt. Wenn in diesem Layer Daten generiert und nicht im selben Befehl gelöscht werden, kann dieser Speicherplatz nicht wiederverwendet werden. In diesem Fall lädt Gradle zum Ausführen des Builds Hunderte von Megabyte an Bibliotheken in das Verzeichnis cache
herunter, die dann nicht gelöscht werden.
Eine effizientere Methode zur Ausführung des Builds ist die Verwendung von Cloud Build, um die Anwendung getrennt von ihrer Laufzeitebene zu erstellen.
Im folgenden Beispiel wird der Schritt zum Erstellen der Java-Anwendung von dem Schritt zum Zusammenstellen des Laufzeitcontainers getrennt:
YAML
-
Anwendung erstellen: Fügen Sie
cloudbuild.yaml
einen Schritt zum Erstellen der Anwendung hinzu.Mit dem folgenden Code wird ein Schritt zum Erstellen des Images
java:8
hinzugefügt. Dieses Image enthält den Java-Code.steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test']
- Laufzeitcontainer zusammenstellen: Fügen Sie in
cloudbuild.yaml
einen Schritt zum Zusammenstellen des Laufzeitcontainers hinzu.Mit dem folgenden Code wird ein Schritt namens
gcr.io/cloud-builders/docker
hinzugefügt. Damit wird der Laufzeitcontainer zusammengestellt. Dieser definiert den Laufzeitcontainer in einer eigenen Datei namensDockerfile.slim
.Im Beispiel wird die Alpine Linux-Basisebene
openjdk:8u111-jre-alpine
verwendet, die außergewöhnlich klein ist. Außerdem enthält es die JRE anstelle des umfangreicheren JDK, das zum Erstellen der Anwendung erforderlich war.cloudbuild.yaml steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest', '-f', 'Dockerfile.slim', '.' ] Dockerfile.slim FROM openjdk:8-jre-alpine COPY ./gate-web/build/install/gate /opt/gate CMD ["/opt/gate/bin/gate"]
- Docker-Images erstellen: Fügen Sie
cloudbuild.yaml
einen Schritt zum Erstellen der Images hinzu.steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest', '-f', 'Dockerfile.slim', '.'] images: - 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA' - 'gcr.io/$PROJECT_ID/$REPO_NAME:latest'
JSON
-
Anwendung erstellen: Fügen Sie
cloudbuild.json
einen Schritt zum Erstellen der Anwendung hinzu.Mit dem folgenden Code wird ein Schritt namens
java:8
zum Erstellen des Java-Codes hinzugefügt.{ "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, }
-
Laufzeitcontainer zusammenstellen: Fügen Sie in
cloudbuild.json
einen Schritt zum Zusammenstellen des Laufzeitcontainers hinzu.Mit dem folgenden Code wird ein Schritt namens
gcr.io/cloud-builders/docker
hinzugefügt. Damit wird der Laufzeitcontainer zusammengestellt. Dieser definiert den Laufzeitcontainer in einer eigenen Datei namensDockerfile.slim
.Im Beispiel wird die Alpine Linux-Basisebene
openjdk:8u111-jre-alpine
verwendet, die außergewöhnlich klein ist. Außerdem enthält es die JRE anstelle des umfangreicheren JDK, das zum Erstellen der Anwendung erforderlich war.cloudbuild.json: { "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:latest", "-f", "Dockerfile.slim", "." ] } ], } Dockerfile.slim: FROM openjdk:8u111-jre-alpine COPY ./gate-web/build/install/gate /opt/gate CMD ["/opt/gate/bin/gate"]
- Docker-Images erstellen: Fügen Sie
cloudbuild.json
einen Schritt zum Erstellen der Images hinzu.{ "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:latest", "-f", "Dockerfile.slim", "." ] } ], "images": [ "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "gcr.io/$PROJECT_ID/$REPO_NAME:latest" ] }