Container mit Dockerfiles entwickeln

1. Übersicht

Docker ist eine offene Plattform zum Entwickeln, Versenden und Ausführen von Anwendungen. Damit können Sie Anwendungen von Ihrer Infrastruktur trennen und diese wie eine verwaltete Anwendung behandeln. Außerdem lässt sich Code schneller versenden, testen und implementieren sowie der Zyklus zwischen dem Schreiben und Ausführen von Code verkürzen.

Zu diesem Zweck kombiniert Docker Funktionen zur Kernel-Containerisierung mit Workflows und Tools, die Ihnen beim Verwalten und Bereitstellen von Anwendungen helfen.

Docker-Container können direkt in Kubernetes verwendet und somit auch ganz einfach in der Kubernetes Engine ausgeführt werden. Sobald Sie die Grundlagen von Docker kennen, können Sie Kubernetes- und containerisierte Anwendungen entwickeln.

Lerninhalte

In diesem Lab lernen Sie Folgendes:

  • Dockerfile für eine Beispielanwendung erstellen
  • Image erstellen
  • Image lokal als Container ausführen
  • Containerverhalten ändern
  • Image in Artifact Registry hochladen

Vorbereitung

Dies ist ein Einführungs-Lab. Es werden keine oder nur wenige Vorkenntnisse zu Docker und Containern vorausgesetzt. Vorkenntnisse zu Cloud Shell und zur Befehlszeile sind empfehlenswert, aber nicht erforderlich.

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Er ist eine Zeichenfolge, die von Google APIs nicht verwendet wird, und Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID muss für alle Google Cloud-Projekte eindeutig sein und ist unveränderlich. Sie kann also nicht mehr geändert werden, nachdem sie festgelegt wurde. Die Cloud Console generiert automatisch eine eindeutige Zeichenfolge. In der Regel müssen Sie sich nicht darum kümmern, was sie ist. In den meisten Codelabs müssen Sie auf die Projekt-ID verweisen. Sie wird in der Regel als PROJECT_ID angegeben. Wenn sie Ihnen nicht gefällt, können Sie eine andere zufällige ID generieren oder eine eigene ID ausprobieren und prüfen, ob sie verfügbar ist. Nachdem das Projekt erstellt wurde, ist die ID festgelegt.
  • Es gibt einen dritten Wert, die Projektnummer , die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten finden Sie in der Dokumentation.
  1. Als Nächstes müssen Sie die Abrechnung aktivieren in der Cloud Console, um Cloud-Ressourcen/APIs verwenden zu können. Die Durchführung dieses Codelabs sollte nicht viel kosten, wenn überhaupt. Wenn Sie Ressourcen herunterfahren möchten, damit Ihnen nach Abschluss dieses Codelabs keine Kosten entstehen, folgen Sie der Anleitung zum Bereinigen am Ende des Codelabs. Neue Google Cloud-Nutzer können am kostenlosen Testprogramm im Wert von 300$ teilnehmen.

2. Beispiel-App

Für dieses Lab wurde eine Beispielanwendung bereitgestellt. In diesem Abschnitt rufen Sie den Quellcode ab und erstellen die Anwendung in ihrer ursprünglichen Form, bevor Sie mit der Containerisierung fortfahren.

Quellcode

Der Quellcode für dieses Lab ist im Repository GoogleCloudPlatform/container-developer-workshop zusammen mit der Dokumentation zur Beispielanwendung verfügbar.

Git konfigurieren

git config --global user.name ${USER}
git config --global user.email ${USER}@qwiklabs.net

Cloud Source Repository der Beispielanwendung klonen

gcloud source repos clone sample-app ${HOME}/sample-app &&
cd ${HOME}/sample-app &&
git checkout main

Ausgabe

Cloning into '/home/student_03_49720296e995/sample-app'...
remote: Finding sources: 100% (16/16)
remote: Total 16 (delta 0), reused 16 (delta 0)
Receiving objects: 100% (16/16), 47.23 KiB | 681.00 KiB/s, done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

Project [qwiklabs-gcp-02-4327c4e03d82] repository [sample-app] was cloned to [/home/student_03_49720296e995/sample-app].
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'

Beispielanwendung erstellen

cd ${HOME}/sample-app
./mvnw compile

Ausgabe

[INFO] Scanning for projects...
...
[INFO] Compiling 1 source file to /home/student_03_49720296e995/sample-app/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.080 s
[INFO] Finished at: 2022-02-23T17:14:30Z
[INFO] ------------------------------------------------------------------------

Beispielanwendung ausführen

cd ${HOME}/sample-app
./mvnw exec:java

Ausgabe

[INFO] Scanning for projects...
...
Listening at http://localhost:8080

Vorschau der ausgeführten Anwendung ansehen

  • Klicken Sie auf die Schaltfläche „Webvorschau“ in Cloud Shell.
  • Klicken Sie auf „Vorschau auf Port 8080“.

Nächster Schritt

  • Drücken Sie in Cloud Shell Strg + C, um die laufende Anwendung zu beenden.

3. Dockerfile

Anwendung mit einem Dockerfile containerisieren

Eine Methode zum Verpacken einer Anwendung in einen Container ist die Verwendung eines Dockerfiles. Das Dockerfile ähnelt einem Skript, das den Daemon anweist, wie das Container-Image zusammengestellt werden soll. Weitere Informationen finden Sie in der Dockerfile-Referenzdokumentation.

Erstellen Sie im Repository der Beispielanwendung ein leeres Dockerfile.

touch ${HOME}/sample-app/Dockerfile

Öffnen Sie das Dockerfile in einem Editor Ihrer Wahl.

vi ${HOME}/sample-app/Dockerfile

Start-Image auswählen

Wenn Sie einen Container mit der Dockerfile-Methode erstellen, sind direkte Kenntnisse der Anwendung erforderlich, um den Container zusammenzustellen. Der erste Schritt zum Erstellen eines Dockerfiles ist die Auswahl eines Images, das als Grundlage für Ihr Image verwendet wird.Dieses Image sollte ein übergeordnetes Image oder ein Basis-Image sein, das von einer vertrauenswürdigen Quelle, in der Regel Ihrem Unternehmen, verwaltet und veröffentlicht wird.

Die FROM-Anweisung initialisiert eine neue Build-Phase und legt das Basis-Image für nachfolgende sequenzielle Befehle fest. Daher ist die FROM Anweisung in der Regel die erste Anweisung in einem Dockerfile und kann nur von einer optionalen ARG Anweisung gefolgt werden, um Variablen zu unterstützen.

Syntax: FROM <image>[:<tag> | @<digest>] [AS <name>]

Das Format für ein Image ist <image>:<tag> oder <image>@<digest>. Wenn kein Tag oder Digest angegeben ist, wird standardmäßig das Tag :latest verwendet. Das Format von <image> variiert je nach Registry, in der das Image gespeichert ist. Für Artifact Registry ist das <image> Format <region>-docker.pkg.dev/<project ID>/<repository name>/<image name>:<image tag>.

Für dieses Lab verwenden wir das öffentliche Image openjdk:11.0-jdk. Fügen Sie Ihrem Dockerfile die folgende Zeile hinzu:

FROM openjdk:11.0-jdk

Arbeitsverzeichnis festlegen

Mit der WORKDIR-Anweisung wird das Arbeitsverzeichnis für alle nachfolgenden sequenziellen Anweisungen im Dockerfile festgelegt. Weitere Informationen finden Sie im Abschnitt WORKDIR der Dockerfile-Referenzdokumentation

Syntax: WORKDIR <path>

Für dieses Lab verwenden wir das Verzeichnis /app als WORKDIR. Fügen Sie Ihrem Dockerfile die folgende Zeile hinzu:

WORKDIR /app

Anwendungsdateien kopieren

Mit der COPY-Anweisung werden Verzeichnisse oder Dateien vom Speicherort <source> in den Pfad <destination> des Image-Dateisystems kopiert. Es können mehrere <source>-Ressourcen angegeben werden, die alle relativ zum Build-Kontext sind. Der Build-Kontext wird im Abschnitt „Build“ näher erläutert. Weitere Informationen finden Sie im Abschnitt COPY der Dockerfile-Referenzdokumentation

Syntax: COPY <source>... <destination>

Für dieses Lab kopieren wir alle Dateien im Repository in das Image-Dateisystem. Fügen Sie Ihrem Dockerfile die folgende Zeile hinzu:

COPY . /app

Anwendung kompilieren

Mit der RUN-Anweisung werden Befehle in einer neuen Image-Ebene über dem aktuellen Image ausgeführt und die Ergebnisse übernommen. Das resultierende übernommene Image wird für nachfolgende Schritte im Dockerfile verwendet. Weitere Informationen finden Sie im Abschnitt RUN der Dockerfile-Referenzdokumentation.

Syntax: RUN <command>

Für dieses Lab verwenden wir Maven, um die Anwendung in eine JAR-Datei zu kompilieren. Fügen Sie Ihrem Dockerfile die folgende Zeile hinzu:

RUN ./mvnw compile assembly:single

Anwendung starten

Die CMD-Anweisung gibt den Standardbefehl für einen laufenden Container an. In einem Dockerfile kann nur eine `CMD`-Anweisung vorhanden sein. Wenn mehrere `CMD`-Anweisungen angegeben sind, wird nur die letzte `CMD`-Anweisung ausgeführt. Es gibt erweiterte Funktionen, die sowohl die Anweisungen `CMD` als auch `ENTRYPOINT` verwenden, die in diesem Lab jedoch nicht behandelt werden. Weitere Informationen finden Sie im Abschnitt CMD der Dockerfile-Referenzdokumentation.

Syntax: CMD ["executable","param1","param2"]

Für dieses Lab führen wir die kompilierte JAR-Datei aus. Fügen Sie Ihrem Dockerfile die folgende Zeile hinzu:

CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

Finales Dockerfile

Das finale Dockerfile sieht so aus:

FROM openjdk:11.0-jdk
WORKDIR /app
COPY . /app
RUN ./mvnw compile assembly:single
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

Dockerfile lokal übernehmen

cd ${HOME}/sample-app
git add Dockerfile
git commit -m "Added Dockerfile"

4. Build

Jetzt erstellen wir das Image aus dem Dockerfile mit dem Befehl docker build. Dieser Befehl weist den Docker-Daemon an, das Image anhand der Anweisungen aus unserem Dockerfile zu erstellen. Weitere Informationen finden Sie in der Referenzdokumentation zu „docker build“.

Image erstellen

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker build --tag sample-app:${IMAGE_TAG} .

Ausgabe

Sending build context to Docker daemon  221.2kB
Step 1/4 : FROM openjdk:11.0-jdk
11.0-jdk: Pulling from library/openjdk
0c6b8ff8c37e: Pull complete
412caad352a3: Pull complete
e6d3e61f7a50: Pull complete
461bb1d8c517: Pull complete
e442ee9d8dd9: Pull complete
542c9fe4a7ba: Pull complete
41de18d1833d: Pull complete
Digest: sha256:d72b1b9e94e07278649d91c635e34737ae8f181c191b771bde6816f9bb4bd08a
Status: Downloaded newer image for openjdk:11.0-jdk
---> 2924126f1829
Step 2/4 : WORKDIR /app
---> Running in ea037abb273d
Removing intermediate container ea037abb273d
---> bd9b6d078082
Step 3/4 : COPY . /app
---> b9aec2b5de51
Step 4/4 : RUN ./mvnw compile jar:jar
---> Running in 3f5ff737b7fd
[INFO] Scanning for projects...
...
[INFO] Building jar: /app/target/sample-app-1.0.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.952 s
[INFO] Finished at: 2022-02-23T18:09:08Z
[INFO] ------------------------------------------------------------------------
Removing intermediate container 331443caebd3
---> 152f65cc441e
Step 5/5 : CMD ["java", "-jar", "/app/target/sample-app-1.0.0.jar"]
---> Running in 3d595a72231c
Removing intermediate container 3d595a72231c
---> 0e40d7548cab
Successfully built 0e40d7548cab
Successfully tagged sample-app:aaa8895

5. Ausführen

Nachdem unser Container-Image erfolgreich erstellt wurde, können wir unsere Anwendung mit dem Befehl „docker run“ ausführen und prüfen, ob sie sich wie erwartet verhält. Mit diesem Befehl wird unser Container im Vordergrund der Eingabeaufforderung zum Testen oder Debuggen gestartet. Weitere Informationen finden Sie in der Referenzdokumentation zu „docker run“.

Container mit dem Image ausführen

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG}

Ausgabe

Listening at http://localhost:8080

Vorschau der Anwendung ansehen, die in einem Container ausgeführt wird

  • Klicken Sie auf die Schaltfläche „Webvorschau“ in Cloud Shell.
  • Klicken Sie auf „Vorschau auf Port 8080“.
  • Drücken Sie in Cloud Shell Strg + C, um die Container zu beenden.

Containerverhalten ändern

Bei der Ausführung von „docker run“ wird die Standardkonfiguration im Dockerfile verwendet. Zusätzliche Anweisungen und Parameter können hinzugefügt werden, um dieses Verhalten zu ändern.

TRACE-Logging aktivieren

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG} \
  java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -jar /app/target/sample-app-1.0.0-jar-with-dependencies.jar

Vorschau der Anwendung ansehen, die in einem Container ausgeführt wird

  • Klicken Sie auf die Schaltfläche „Webvorschau“ in Cloud Shell.
  • Klicken Sie auf „Vorschau auf Port 8080“.
  • Wechseln Sie zum Cloud Shell-Tab und sehen Sie sich das zusätzliche Logging an.
  • Drücken Sie in Cloud Shell Strg + C, um den Container zu beenden.

Port ändern

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-e PORT=8081 \
-p 8081:8081 \
sample-app:${IMAGE_TAG}

Vorschau der Anwendung ansehen, die in einem Container ausgeführt wird

  • Klicken Sie auf die Schaltfläche „Webvorschau“ in Cloud Shell.
  • Klicken Sie auf „Port ändern“.
  • Geben Sie „8081“ ein.
  • Klicken Sie auf „Ändern und Vorschau“.
  • Drücken Sie in Cloud Shell Strg + C, um den Container zu beenden.

6. Push

Wenn wir sicher sind, dass das Container-Image ordnungsgemäß ausgeführt wird und wir diesen Container in anderen Umgebungen und/oder von anderen Nutzern ausführen lassen möchten, müssen wir das Image in ein freigegebenes Repository übertragen. Dies sollte im Rahmen einer automatisierten Build-Pipeline erfolgen. In unserer Testumgebung ist jedoch bereits ein Repository konfiguriert und wir können unser Image manuell übertragen.

Dockerfile-Commit in das Repository der Beispielanwendung übertragen

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
git push

Image für Artifact Registry taggen

docker tag sample-app:${IMAGE_TAG} \
    us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

Anmeldedaten für Artifact Registry konfigurieren

gcloud auth configure-docker us-central1-docker.pkg.dev

Antworten Sie bei der Aufforderung Do you want to continue (Y/n)? mit y und drücken Sie die Enter.

Image in Artifact Registry hochladen

docker push us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

Ausgabe

 The push refers to repository [us-central1-docker.pkg.dev/qwiklabs-gcp-04-b47ced695a3c/apps/sample-app]
  453b97f86449: Pushed
  e86791aa0382: Pushed
  d404c7ee0850: Pushed
  fe4f44af763d: Pushed
  7c072cee6a29: Pushed
  1e5fdc3d671c: Pushed
  613ab28cf833: Pushed
  bed676ceab7a: Pushed
  6398d5cccd2c: Pushed
  0b0f2f2f5279: Pushed
  aaa8895: digest: sha256:459de00f86f159cc63f98687f7c9563fd65a2eb9bcc71c23dda3351baf13607a size: 2424

7. Glückwunsch!

Sie haben das Codelab abgeschlossen.

Behandelte Themen

  • Dockerfile für eine Beispielanwendung erstellt
  • Image erstellt
  • Image lokal als Container ausgeführt
  • Containerverhalten geändert
  • Image in Artifact Registry hochgeladen