Tworzenie kontenerów przy użyciu Dockerfiles

1. Omówienie

Docker to otwarta platforma do tworzenia, przesyłania i uruchamiania aplikacji. Docker pozwala oddzielić aplikacje od infrastruktury i traktować infrastrukturę jak aplikację zarządzaną. Docker pomaga szybciej wysyłać kod, testować go i wdrażać oraz skrócić cykl między pisaniem i uruchamianiem kodu.

W tym celu Docker łączy funkcje konteneryzacji jądra z przepływami pracy i narzędziami, które ułatwiają wdrażanie aplikacji i zarządzanie nimi.

Kontenerów Dockera można używać bezpośrednio w Kubernetes, co ułatwia ich uruchamianie w Kubernetes Engine. Po zapoznaniu się z podstawami Dockera zdobędziesz umiejętności potrzebne do tego, by zacząć tworzyć aplikacje Kubernetes i skonteneryzowane.

Czego się nauczysz

Z tego modułu nauczysz się:

  • Tworzenie pliku Dockerfile dla przykładowej aplikacji
  • Tworzenie obrazu
  • Uruchamianie obrazu jako kontenera lokalnie
  • Zmień działanie kontenera
  • Przesyłanie obrazu do Artifact Registry

Wymagania wstępne

To jest moduł dla początkujących. Zakładamy, że nie masz żadnego lub prawie żadnego doświadczenia w korzystaniu z Dockera i kontenerów. Znajomość Cloud Shell i wiersza poleceń jest sugerowana, ale nie jest konieczna.

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub wykorzystaj już istniejący. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Nazwa projektu jest wyświetlaną nazwą uczestników tego projektu. To ciąg znaków, który nie jest używany przez interfejsy API Google i w każdej chwili możesz go zaktualizować.
  • Identyfikator projektu musi być unikalny we wszystkich projektach Google Cloud i nie można go zmienić (nie można go zmienić po ustawieniu). Cloud Console automatycznie wygeneruje unikalny ciąg znaków. zwykle nieważne, co ona jest. W większości ćwiczeń w Codelabs musisz odwoływać się do identyfikatora projektu (który zwykle nazywa się PROJECT_ID), więc jeśli Ci się nie podoba, wygeneruj kolejny losowy projekt lub wypróbuj swój własny identyfikator i sprawdź, czy jest dostępny. Potem urządzenie jest „zawieszone”. po utworzeniu projektu.
  • Występuje trzecia wartość – numer projektu – używany przez niektóre interfejsy API. Więcej informacji o wszystkich 3 wartościach znajdziesz w dokumentacji.
  1. Następnie musisz włączyć płatności w konsoli Cloud, aby móc korzystać z zasobów i interfejsów API Cloud. Ukończenie tego ćwiczenia z programowania nie powinno kosztować zbyt wiele. Aby wyłączyć zasoby, aby nie naliczać opłat po zakończeniu tego samouczka, wykonaj czynności „wyczyść” znajdziesz na końcu tego ćwiczenia. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.

2. Przykładowa aplikacja

Udostępniliśmy przykładową aplikację, aby ułatwić ten moduł. W tej sekcji pobierzesz kod źródłowy i skompilujesz aplikację w jej natywnym formacie, zanim przejdziesz do procesu konteneryzacji.

Kod źródłowy

Kod źródłowy tego modułu jest dostępny w repozytorium GoogleCloudPlatform/container-developer-workshop wraz z przykładową dokumentacją aplikacji.

Skonfiguruj git

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

Klonowanie przykładowego repozytorium Cloud Source Repositories

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

Wyniki

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'

Kompilowanie przykładowej aplikacji

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

Wyniki

[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] ------------------------------------------------------------------------

Uruchamianie przykładowej aplikacji

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

Wyniki

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

Wyświetl podgląd działającej aplikacji

  • Kliknij przycisk podglądu Cloud Shell w przeglądarce
  • Kliknij Podgląd na porcie 8080

Gdy skończysz

  • Naciśnij Ctrl + C w Cloud Shell, aby zatrzymać uruchomioną aplikację

3. Dockerfile

Konteneryzowanie aplikacji za pomocą pliku Dockerfile

Jedną z metod umieszczania aplikacji w kontenerze jest użycie pliku Dockerfile. Dockerfile jest podobny do skryptu, który instruuje demona, jak złożyć obraz kontenera. Więcej informacji znajdziesz w dokumentacji referencyjnej Dockerfile).

Utwórz pusty plik Dockerfile w repozytorium przykładowej aplikacji.

touch ${HOME}/sample-app/Dockerfile

Otwórz plik Dockerfile w wybranym edytorze.

vi ${HOME}/sample-app/Dockerfile

Wybierz obraz początkowy

Użycie metody Dockerfile do utworzenia kontenera wymaga bezpośredniej wiedzy o aplikacji. Pierwszym krokiem do utworzenia pliku Dockerfile jest wybór obrazu, który posłuży za podstawę Twojego obrazu.Powinien to być obraz nadrzędny lub podstawowy utrzymywany i opublikowany przez zaufane źródło, zwykle Twoją firmę.

Instrukcja FROM inicjuje nowy etap kompilacji i ustawia obraz podstawowy dla kolejnych poleceń sekwencyjnych. Dlatego instrukcja FROM jest zwykle pierwszą instrukcją w pliku Dockerfile i może być poprzedzona tylko opcjonalną instrukcją ARG obsługującą zmienne.

Składnia: FROM <image>[:<tag> | @<digest>] [AS <name>]

Format obrazu to <image>:<tag> lub <image>@<digest>. Jeśli nie określisz tagu lub skrótu, domyślnie zostanie użyty tag :latest. Format pliku <image> zależy od rejestru używanego do przechowywania obrazu. W Artifact Registry format <image> to <region>-docker.pkg.dev/<project ID>/<repository name>/<image name>:<image tag>.

W tym module używamy publicznego obrazu openjdk:11.0-jdk, dodaj poniższy wiersz do swojego pliku Dockerfile

FROM openjdk:11.0-jdk

Ustaw katalog roboczy

Instrukcja WORKDIR ustawia katalog roboczy dla wszystkich instrukcji sekwencyjnych, które występują w pliku Dockerfile. Więcej informacji znajdziesz w sekcji WORKDIR w dokumentacji referencyjnej Dockerfile

Składnia: WORKDIR <path>

Na potrzeby tego modułu używamy katalogu /app jako katalogu WORKDIR, dodaj poniższy wiersz na dole pliku Dockerfile.

WORKDIR /app

Skopiuj pliki aplikacji

Instrukcja COPY kopiuje katalogi lub pliki z lokalizacji <source> do ścieżki <destination> systemu plików obrazu. Można określić wiele zasobów <source> i wszystkie są zależne od kontekstu kompilacji. Kontekst kompilacji zostanie dokładnie omówiony w sekcji Kompilacja. Więcej informacji znajdziesz w sekcji Kopiuj w dokumentacji Dockerfile.

Składnia: COPY <source>... <destination>

W tym module skopiujemy wszystkie pliki z repozytorium do systemu plików obrazów. Dodajemy następujący wiersz na dole pliku Dockerfile.

COPY . /app

Kompilowanie aplikacji

Instrukcja RUN wykonuje polecenia w nowej warstwie obrazu nałożonego na bieżący obraz i zatwierdza wyniki. Powtórny zatwierdzony obraz zostanie użyty w kolejnych krokach w pliku Dockerfile. Więcej informacji znajdziesz w sekcji Uruchamianie w dokumentacji Dockerfile.

Składnia: RUN <command>

W tym module użyjemy narzędzia Maven, aby skompilować aplikację do pliku JAR. Do pliku Dockerfile dodaj poniższy wiersz.

RUN ./mvnw compile assembly:single

Uruchom aplikację

Instrukcja CMD zawiera domyślne polecenie dla uruchomionego kontenera. W pliku Dockerfile może być tylko 1 instrukcja CMD. Jeśli określisz ich więcej, obowiązywać będzie tylko ostatni z nich. Dostępne są bardziej zaawansowane funkcje, które są dostępne zarówno w instrukcjach dotyczących CMD, jak i ENTRYPOINT, ale nie zostały one omówione w tym module. Więcej informacji znajdziesz w sekcji CMD” w dokumentacji Dockerfile

Składnia: CMD ["executable","param1","param2"]

Na potrzeby tego modułu uruchamiamy skompilowany przez nas plik JAR. Dodaj poniższy wiersz na końcu pliku Dockerfile.

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

Końcowy plik Dockerfile

Ostatni plik Dockerfile zostanie

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"]

Zatwierdzanie pliku Dockerfile lokalnie

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

4. Kompilacja

Teraz utworzymy obraz na podstawie pliku Dockerfile za pomocą polecenia docker build. To polecenie instruuje demona Dockera, aby skompilował obraz zgodnie z instrukcjami z pliku Dockerfile. Więcej informacji znajdziesz w dokumentacji referencyjnej kompilacji Dockera.

Tworzenie obrazu

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

Wyniki

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. Uruchom

Po skompilowaniu obrazu kontenera możemy uruchomić aplikację i sprawdzić, czy działa ona zgodnie z oczekiwaniami – wystarczy użyć polecenia dockera. Spowoduje to uruchomienie kontenera na pierwszym planie wiersza poleceń w celu testowania lub debugowania. Więcej informacji znajdziesz w dokumentacji referencyjnej dotyczącej uruchomienia Dockera.

Uruchom kontener przy użyciu obrazu

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

Wyniki

Listening at http://localhost:8080

Podgląd aplikacji działającej w kontenerze

  • Kliknij przycisk podglądu Cloud Shell w przeglądarce
  • Kliknij Podgląd na porcie 8080
  • Naciśnij Ctrl + C w Cloud Shell, aby zatrzymać kontenery

Zmiana działania kontenera

Podczas wykonywania Docker Run używana jest domyślna konfiguracja w pliku Dockerfile. Aby zmodyfikować to działanie, można dodać dodatkowe instrukcje i parametry.

Włącz logowanie TRACE

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

Podgląd aplikacji działającej w kontenerze

  • Kliknij przycisk podglądu Cloud Shell w przeglądarce
  • Kliknij Podgląd na porcie 8080
  • Przejdź na kartę Cloud Shell i sprawdź, czy dodatkowe logowanie
  • Naciśnij Ctrl + C w Cloud Shell, aby zatrzymać kontener

Zmień port

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}

Podgląd aplikacji działającej w kontenerze

  • Kliknij przycisk podglądu Cloud Shell w przeglądarce
  • Kliknij Zmień port
  • Wpisz kod 8081
  • Kliknij Zmień i wyświetl podgląd.
  • Naciśnij Ctrl + C w Cloud Shell, aby zatrzymać kontener

6. Push

Gdy upewnisz się, że obraz kontenera działa prawidłowo i chcemy udostępnić ten kontener do uruchamiania w innych środowiskach lub przez innych użytkowników, trzeba będzie przenieść obraz do wspólnego repozytorium. Powinno to nastąpić w ramach automatycznego potoku kompilacji, ale w naszym środowisku testowym mamy już skonfigurowane repozytorium i możemy przekazać obraz ręcznie.

Wypchnij zatwierdzenie Dockerfile do repozytorium przykładowej aplikacji

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

Tagowanie obrazu na potrzeby Artifact Registry

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

Konfigurowanie danych logowania w Artifact Registry

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

Gdy pojawi się prośba Do you want to continue (Y/n)?, odpowiedz y i naciśnij Enter

Przesyłanie obrazu do Artifact Registry

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

Wyniki

 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. Gratulacje!

Gratulacje. Udało Ci się ukończyć ćwiczenia z programowania.

Co zostało omówione

  • Utworzono plik Dockerfile dla przykładowej aplikacji
  • Utwórz obraz
  • Uruchomiono obraz jako kontener lokalnie.
  • Zmieniono działanie kontenera
  • Obraz został przekazany do Artifact Registry