README.md 20.1 KB
Newer Older
Nane Kratzke's avatar
Nane Kratzke committed
1
2
# Lab 05: Containerization

Nane Kratzke's avatar
Nane Kratzke committed
3
4
In diesem Lab lernen Sie die Tool-Chain kennen, um Applikationen als standardisierte Deployment Units (Container-Images) bereitstellen zu können. Container Images sind wesentlich leichtgewichtiger als VM-Images, die Sie in vorherigen Labs bereits kennengelernt haben.

Nane Kratzke's avatar
Nane Kratzke committed
5
Container Images können Sie sowohl lokal auf einem Entwicklungsrechner (z.B. Ihrem Laptop) als auch im Rahmen von Deployment Pipelines (d.h. in Remote Building Environments wie bspw. Gitlab CI/CD) erzeugen. Die Standardisierung von Deployment Units in Form von Containern ist ein zentrales Merkmal der Entwicklung Cloud-nativer Anwendungen. Die hier vorgestellten Prinzipien lassen Sie daher problemlos in weiteren Cloud-nativen Projekten nutzen.
Nane Kratzke's avatar
Nane Kratzke committed
6

Nane Kratzke's avatar
Nane Kratzke committed
7
## Inhalt
Nane Kratzke's avatar
Nane Kratzke committed
8
9
- [Lab 05: Containerization](#lab-05-containerization)
  - [Inhalt](#inhalt)
Nane Kratzke's avatar
Nane Kratzke committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  - [Vorbereitung](#vorbereitung)
  - [Übung 01: Erstellung von einem Image](#übung-01-erstellung-von-einem-image)
    - [Aufgabe 01.1 HTTP-Service mittels eines NGINX-Basisimages](#aufgabe-011-http-service-mittels-eines-nginx-basisimages)
    - [Aufgabe 01.2: HTTP-Service mittels eines generellen Basis-Images bauen](#aufgabe-012-http-service-mittels-eines-generellen-basis-images-bauen)
  - [Übung 02: Image-Shrinking](#übung-02-image-shrinking)
    - [Aufgabe 02.1: Unnötige Dateien löschen](#aufgabe-021-unnötige-dateien-löschen)
    - [Aufgabe 02.2: Image-Layer einsparen](#aufgabe-022-image-layer-einsparen)
    - [Aufgabe 02.3: Kleinere Basis-Images nutzen](#aufgabe-023-kleinere-basis-images-nutzen)
  - [Übung 03: Images in Registries bereitstellen](#übung-03-images-in-registries-bereitstellen)
  - [Übung 04: Deployment-Pipeline zum Bau und Test eines Images](#übung-04-deployment-pipeline-zum-bau-und-test-eines-images)
  - [Links](#links)
  - [Was sollten Sie mitnehmen](#was-sollten-sie-mitnehmen)

## Vorbereitung
Nane Kratzke's avatar
Nane Kratzke committed
24

Nane Kratzke's avatar
Nane Kratzke committed
25
- [Installieren](https://docs.docker.com/engine/install/) Sie gem. den verlinkten Anweisungen Docker für Ihr System:
Nane Kratzke's avatar
Nane Kratzke committed
26
27
28
29
30
31
32
33
34
35
36
    - [Mac](https://www.docker.com/products/docker-desktop)
    - [Windows](https://www.docker.com/products/docker-desktop)
    - [Linux](https://docs.docker.com/engine/install/)
- Prüfen Sie in Ihrer Konsole, ob die Installation erfolgreich war:
  ```
  docker --version
  ```
  Sie sollten eine Ausgabe mit der Versionsnummer und build id bekommen, z.B.:
  ```
  Docker version 19.03.8, build afacb8b
  ```
Nane Kratzke's avatar
Nane Kratzke committed
37
38
39
40
41
 - Klonen Sie sich bitte ferner als Vorbereitung dieses Repository mittels:
   ```
   git clone https://git.mylab.th-luebeck.de/cloud-native/lab-containerization.git
   cd lab-containerization
   ```
Nane Kratzke's avatar
Nane Kratzke committed
42

Nane Kratzke's avatar
Nane Kratzke committed
43
## Übung 01: Erstellung von einem Image
Nane Kratzke's avatar
Nane Kratzke committed
44

Nane Kratzke's avatar
Nane Kratzke committed
45
Sie werden in diesem Teil sehen, wie man Images baut. Häufig benötigt man Images für spezfische Dienste, wie bspw. Datenbanken, Webserver, usw. Hierfür bieten die Hersteller meist vorkonfigurierte Images an, die man nur noch mit einer kleinen Konfiguration (z.B. Access Credentials, Dateipfade, etc.) auf die spezifischen Bedürfnisse anpassen muss. Es lohnt sich hierzu öffentliche Image Repositories wie [Dockerhub](https://hub.docker.com) zu durchsuchen. Man kann aber auch Images auf Basis einer Standard Linux-Distribution aufsetzen. Sie werden beides am Beispiel eines kleinen Webservers sehen.
Nane Kratzke's avatar
Nane Kratzke committed
46

Nane Kratzke's avatar
Nane Kratzke committed
47
### Aufgabe 01.1 HTTP-Service mittels eines NGINX-Basisimages
Nane Kratzke's avatar
Nane Kratzke committed
48
49

1. Öffnen Sie nun bitte die Datei `Dockerfile.nginx` (diese ist recht übersichtlich, versuchen Sie diese zu verstehen und nachzuvollziehen)
Nane Kratzke's avatar
Nane Kratzke committed
50
2. Erzeugen Sie aus dieser nun das für Docker erforderliche Dockerfile mittels `cp Dockerfile.nginx Dockerfile`.
Nane Kratzke's avatar
Nane Kratzke committed
51
52
53
54
55
56
57
58
59
3. Bauen Sie nun ein Container-Image mittels `docker build -t web:nginx .` (vergessen Sie nicht die Punkt am Ende, der gibt das Current Directory an und ist wichtig!).
4. Prüfen Sie mittels `docker image list web*`, ob Ihr Image gebaut wurde. Sie sollten eine Ausgabe wie folgt (o. ähnl.) erhalten.
   ```
   REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
   web                 nginx               ca0547d1d208        seconds ago         133MB
   ```
5. Starten Sie dieses Image nun bitte mittels `docker run -p 8080:80 web:nginx` (Sie binden dadurch Ihren lokalen Port 8080 an den Port 80 des Containers).
6. Prüfen Sie, ob Ihre Website ausgeliefert wird, in dem Sie [http://localhost:8080](http://localhost:8080) aufrufen. Sie sollten dann folgende Webpage sehen.
![screenshot](index.html.png)
Nane Kratzke's avatar
Nane Kratzke committed
60
7. Beenden Sie den HTTP-Service in dem Sie in Ihrer Konsole CTRL-C drücken (Sie senden damit das SIGTERM Signal an den NGINX Server-Prozess und der Container wird terminiert).
Nane Kratzke's avatar
Nane Kratzke committed
61

Nane Kratzke's avatar
Nane Kratzke committed
62
Das war ja erstaunlich einfach.
Nane Kratzke's avatar
Nane Kratzke committed
63

Nane Kratzke's avatar
Nane Kratzke committed
64
### Aufgabe 01.2: HTTP-Service mittels eines generellen Basis-Images bauen
Nane Kratzke's avatar
Nane Kratzke committed
65

Nane Kratzke's avatar
Nane Kratzke committed
66
67
68
In Fällen von weit verbreiteten Diensten und Produkten wie NGINX, Apache, Redis, Memcached, CouchDB, MySQL, usw. finden sich häufig solche Basisimages der entsprechenden Projekte. Diese kann man meist sehr schnell und unkompliziert aufsetzen und nutzen. Sie verlieren aber häufig auch etwas Kontrolle und Konfigurationsmöglichkeiten.

In Fällen spezifischerer Produkte oder selbst geschriebener Software sind Sie sogar ggf. gezwungen selber ein Image zu erstellen und die entsprechende Software darauf zu installieren. Man geht in diesen Fällen üblicherweise von einem Distributions Basis-Image aus (wie bspw. dem Ubuntu 18.04 LTS Image).
Nane Kratzke's avatar
Nane Kratzke committed
69
70
71
72

Wir wollen nun denselben Service mit einem anderen Image bauen, um diesen generelleren Ansatz zu demonstrieren.

1. `cp Dockerfile.ubuntu Dockerfile`
Nane Kratzke's avatar
Nane Kratzke committed
73
2. Öffen Sie das `Dockerfile` in einem Editor und versuchen Sie es zu verstehen. Sie sehen, es ist etwas länger, als das vorherige Image, aber Sie sollten die Wirkungsweise mittels der Kommentare gut nachvollziehen können.
Nane Kratzke's avatar
Nane Kratzke committed
74
75
76
77
78
79
80
81
3. Bauen Sie nun das Image zu diesem Ubuntu-basierten `Dockerfile` mittels `docker build -t web:ubuntu .`.
4. Prüfen Sie wieder mittels `docker image list web*`, ob Ihr Image gebaut wurde. Sie sollten eine Ausgabe wie folgt (o. ähnl.) erhalten.
   ```
   REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
   web                 ubuntu              8032bb56c82d        seconds ago         154MB
   web                 nginx               ca0547d1d208        minutes ago         133MB
   ```
5. Starten Sie dieses Image nun bitte mittels `docker run -p 8080:80 web:ubuntu`.
Nane Kratzke's avatar
Nane Kratzke committed
82
6. Prüfen Sie, ob Ihre Website ausgeliefert wird, in dem Sie [http://localhost:8080](http://localhost:8080) aufrufen. Sie sollten wieder dieselbe Webpage sehen, wie bereits im vorherigen Teil.
Nane Kratzke's avatar
Nane Kratzke committed
83

Nane Kratzke's avatar
Nane Kratzke committed
84
## Übung 02: Image-Shrinking
Nane Kratzke's avatar
Nane Kratzke committed
85

Nane Kratzke's avatar
Nane Kratzke committed
86
Sie haben in Übung 02 einen einfachen Webserver samt Inhalt als Docker-Image erzeugt.
Nane Kratzke's avatar
Nane Kratzke committed
87
88

- Einmal haben Sie auf dem von NGINX selbst bereitgestellten Image nur Ihren Inhalt (`web`-Verzeichnis) hinzugefügt.
Nane Kratzke's avatar
Nane Kratzke committed
89
- Im zweiten Fall haben Sie auf Basis eines Ubuntu 18.04 LTS Basis Images auch den Webserver NGINX installiert, den Inhalt hinzugefügt und den Entrypoint für den Container konfiguriert. Das war zwar etwas aufwändiger, Sie hatten aber dadurch letztlich mehr Kontrolle über die Konfiguration.
Nane Kratzke's avatar
Nane Kratzke committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

Sie sehen also, dass bereitgestellte Community-Images häufig komfortabler sind. Doch wie sieht es mit dem Größenbedarf der resultierenden Images aus?

Geben Sie dazu bitte folgendes in Ihrer Shell ein.

```
docker image list web*
```

Dies sollte folgende (o. ähnl.) Ausgabe erzeugen:

```
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
web                 ubuntu              8032bb56c82d        57 minutes ago       154MB
web                 nginx               ca0547d1d208        14 hours ago         133MB
```

Nane Kratzke's avatar
Nane Kratzke committed
107
Sie sehen, Ihr selbst gebautes Ubuntu Image ist etwas größer. Das ist nicht wirklich erstaunlich, denn die NGINX Macher wissen vermutlich besser als Sie und ich, wie man eine NGINX-Basisinstallation effizient konfiguriert. Doch Images lassen sich auch "shrinken". Sie sollten sich dazu ins Bewusstsein rufen, dass Container Overlay-Dateisysteme nutzen, und jede Anweisungszeile eines Dockerfiles ein Image-Layer (mit Platzbedarf) erzeugt. Man kann sich das zu Nutze machen und Images auf mehrere Arten "kleiner" machen:
Nane Kratzke's avatar
Nane Kratzke committed
108
109
110
111
112
113
114

1. Indem man für den Betrieb unnötige Dateien nicht in den Layer mit aufnimmt.
2. Indem man unnötige Image-Layer einspart.
3. Und indem man kleinere Basis-Images nutzt.

Die folgenden Aufgaben dienen dazu, Ihnen zu zeigen, was für Effekte diese drei Möglichkeiten auf die resultierenden Imagegrößen haben.

Nane Kratzke's avatar
Nane Kratzke committed
115
### Aufgabe 02.1: Unnötige Dateien löschen
Nane Kratzke's avatar
Nane Kratzke committed
116
117
118

Wir gehen von unserem `web:ubuntu` Image aus.

Nane Kratzke's avatar
Nane Kratzke committed
119
1. `cp Dockerfile.ubuntu Dockerfile` (Nutzen Sie ggf. `copy` für cmd Shell auf Windows)
Nane Kratzke's avatar
Nane Kratzke committed
120
121
122
123
124
125
2. Löschen Sie nun unnötige Package Manager Dateien mittels `apt-get clean` und `rm -rf /var/lib/apt/lists/*` in dem Sie die im Dockerfile dafür vorgesehenen Zeilen einkommentieren.
3. Bauen Sie nun ein neues Package mittels `docker build -t web:ubuntu-cleaned .`
4. Lassen Sie sich nun die Größen aller drei Packages mittels `docker image list web*` anzeigen.

Sie sehen, dass dadurch Ihr Image bereits etwas kleiner geworden ist, aber noch größer als das NGINX-Image ist.

Nane Kratzke's avatar
Nane Kratzke committed
126
### Aufgabe 02.2: Image-Layer einsparen
Nane Kratzke's avatar
Nane Kratzke committed
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

In Linux/UNIX Shells kann man, um zwei Kommandos nacheinander auszuführen, entweder dies

```
cat /file/exists
echo "success"
```

oder dies

```
cat /file/exists && echo "success"
```

schreiben. "Success" wird im zweiten Fall sogar nur dann ausgegeben, wenn das erste Kommando `cat /file/exists` mit einem Exit-Code von 0 (also erfolgreich) beendet werden konnte. Das entspricht exakt der Ausführungsweise sequentiell aufeinander folgender `RUN`-Anweisungen. Mittels des `&&` Operators lassen sich also
mehrere Shell-Kommandos in einer `RUN`-Anweisung eines Dockerfiles unterbringen. Anstatt mehrere `RUN`-Anweisungen (also mehrere Image-Layers) benötigt man so nur eine `RUN`-Anweisung (und erzeugt nur einen Image-Layer).

Dieses __RUN-Chaining__ genannte Prinzip werden wir anwenden und sehen welchen Effekt dies auf Image-Größen haben kann.

Nane Kratzke's avatar
Nane Kratzke committed
146
1. `cp Dockerfile.ubuntu Dockerfile` (Nutzen Sie ggf. `copy` für cmd Shell auf Windows)
Nane Kratzke's avatar
Nane Kratzke committed
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
2. Kommentieren Sie nun alle `RUN`-Anweisungen im Dockerfile aus.
3. Kommentieren Sie nun bitte die einzelne `RUN`-Anweisung unter dem `Image Shrinking Effect`-Kommentar ein.
4. Bauen Sie nun ein neues Package mittels `docker build -t web:ubuntu-shrinked .`
5. Lassen Sie sich nun die Größen aller vier Packages mittels `docker image list web*` anzeigen.

Sie sollten etwa folgende (o. ähnl.) Ausgabe erhalten:

```
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
web                 ubuntu-shrinked     f5f33804dcf2        38 minutes ago       117MB
web                 ubuntu-cleaned      4f345b6cac34        48 minutes ago       147MB
web                 ubuntu              8032bb56c82d        57 minutes ago       154MB
web                 nginx               ca0547d1d208        14 hours ago         133MB
```

Nane Kratzke's avatar
Nane Kratzke committed
162
### Aufgabe 02.3: Kleinere Basis-Images nutzen
Nane Kratzke's avatar
Nane Kratzke committed
163
164
165
166
167
168
169
170
171
172
173
174
175

Alle Images haben bislang Größen, die deutlich die 100 MB sprengen. Das ist zwar kleiner als viele VM-Images, aber immer noch recht groß, um ein paar HTML-Seiten von wenigen KBs auszuliefern.

Aus diesem Grund gibt es Linux-Distributionen (Basis-Images), die deutlich kleiner sind, als die Standard-Distributionen. Diese beinhalten nur das absolut Wesentliche (quasi die POSIX-Schnittstelle) eines Linux-Betriebssystems. Hier gibt es mehrere Distributionen, die häufig verwendet werden. Bspw.:

- [Alpine Linux](https://alpinelinux.org)
- [Atomic](https://www.projectatomic.io)
- [Busybox](https://busybox.net)
- [RancherOS](https://rancher.com/rancher-os)
- [Photon](https://vmware.github.io/photon)

Wir werden die Übung 02 nun mit dem Alpine Linux Basis-Image wiederholen und sehen, wie sich diese Distribution auf die Image-Größen auswirkt.

Nane Kratzke's avatar
Nane Kratzke committed
176
177
1. `cp Dockerfile.alpine Dockerfile` (Nutzen Sie ggf. `copy` für cmd Shell auf Windows)
2. `docker build -t web:alpine .`
Nane Kratzke's avatar
Nane Kratzke committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
3. Kommentieren Sie dann folgende Zeile im Dockerfile ein: `RUN rm -rf /var/cache/apk/*`
4. `docker build -t web:alpine-cleaned .`
5. Kommentieren Sie nun alle `RUN` Commands im Dockerfile aus.
6. Kommenteren Sie dann das `RUN`-Chaining im Dockerfile ein.
7. `docker build -t web:alpine-shrinked .`
8. Lassen Sie sich nun mittels `docker image list web*` alle Image-Größen im Überblick anzeigen.

Sie sollten nun folgende (o. ähnl.) Ausgabe erhalten:

```
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
web                 alpine-shrinked     647de3450afe        2 seconds ago        ??.??MB
web                 alpine-cleaned      9a30127f52b1        About a minute ago   ??.??MB
web                 alpine              b9f1decf5a22        2 minutes ago        ??.??MB
web                 ubuntu-shrinked     f5f33804dcf2        38 minutes ago       117MB
web                 ubuntu-cleaned      4f345b6cac34        48 minutes ago       147MB
web                 ubuntu              8032bb56c82d        57 minutes ago       154MB
web                 nginx               ca0547d1d208        14 hours ago         133MB
```

__Beantworten Sie nun die Frage, um wieviel Prozent der Image-Wechsel das resultierende Container-Image reduziert hat?__

Sie können auch gerne prüfen, dass die Images alle laufen, indem Sie diese jeweils mit den folgenden Kommandos starten

```
docker run -p 8080:80 web:alpine
docker run -p 8080:80 web:alpine-cleaned
docker run -p 8080:80 web:alpine-shrinked
```

Nane Kratzke's avatar
Nane Kratzke committed
208
und danach [http://localhost:8080](http://localhost:8080) aufrufen. Der erbrachte Dienst ist in allen Fällen derselbe.
Nane Kratzke's avatar
Nane Kratzke committed
209

Nane Kratzke's avatar
Nane Kratzke committed
210
## Übung 03: Images in Registries bereitstellen
Nane Kratzke's avatar
Nane Kratzke committed
211

Nane Kratzke's avatar
Typos    
Nane Kratzke committed
212
Bislang haben Sie Images lokal auf Ihrem Host erzeugt. Das ist für lokale Entwicklungszwecke meist vollkommen ausreichend. Aber Sie haben auch bereits gesehen, dass Images in Public oder Private Registries bereitgestellt werden können. Die bereits in diesem Lab von Ihnen genutzten NGINX, Ubuntu und Alpine Images sind bspw. aus dem öffentlichen [Dockerhub](https://hub.docker.com) bezogen worden (ohne das Sie dies vermutlich recht zur Kenntnis genommen haben).
Nane Kratzke's avatar
Nane Kratzke committed
213
214
215
216
217
218
219

In der normalen Entwicklung stellt man Images normalerweise in Privaten Registries zur Verfügung, damit nicht alle Zugriff auf diese haben. Hierzu können Image Registries private gehostet werden. Bspw. kann dies mit dem [THL Gitlab Service](https://git.mylab.th-luebeck.de) in jedem Projekt gemacht werden.

Dies wollen wir nun demonstrieren:

__Hinweis:__ Dieser Teil kann auch mit dem Public [Gitlab.com](https://gitlab.com) Service analog nachvollzogen werden, falls Sie sich dort registriert haben.

Nane Kratzke's avatar
Typos    
Nane Kratzke committed
220
1. Loggen Sie sich hierzu in den [THL Gitlab Service](https://git.mylab.th-luebeck.de) ein.
Nane Kratzke's avatar
Nane Kratzke committed
221
222
223
2. Legen Sie in der Weboberfläche mittels "Neues Projekt" ein Test Repository namens `image-test` mit der Visibility `private` an.
3. Klicken Sie in diesem Repository auf "Packages & Registries -> Container Registry". Sie sollten dann eine (noch) leere Registry sehen.
   ![Registry](registry.png)
Nane Kratzke's avatar
Typos    
Nane Kratzke committed
224
225
226
227
228
4. Ihnen sind ferner ein paar Kommandos vorgegeben, um sich mit der Registry von Docker aus zu verbinden (diese lassen sich aus der Web-Oberfläche kopieren).
5. Loggen Sie sich mittels Ihrer Konsole hierzu in die Registry ein (geben Sie Ihre Zugangsdaten ein).
6. Arbeiten Sie nun mit dem NGINX-Image `cp Dockerfile.nginx Dockerfile`.
7. Bauen Sie nun dieses Image für Ihre Registry mittels `docker build -t git.mylab.th-luebeck.de:4181/<max>.<mustermann>/image-test/web:nginx .`.
8. Pushen Sie das Image anschließend in diese Registry mittels `docker push git.mylab.th-luebeck.de:4181/<max>.<mustermann>/image-test/web:nginx`. Ersetzen Sie dabei `<max>.<mustermann>` mit Ihrem Namen (oder kopieren Sie diesen aus der GitLab-Web-Oberfläche). Der Upload kann ggf. etwas länger dauern.
Nane Kratzke's avatar
Nane Kratzke committed
229
230
231
9. Navigieren Sie erneut zu Ihrer Registry. Sie sollten Ihr Image dort nun sehen.
   ![Registry-filled](registry-filled.png)
10. Mittels `docker pull git.mylab.th-luebeck.de:4181/<max>.<mustermann>/image-test/web:nginx` können Sie es von der Registry herunterladen.
Nane Kratzke's avatar
Nane Kratzke committed
232
11. Unterschiedliche Versionen von Images können Sie mit Tags kennzeichnen. (Nutzen Sie ggf. `copy` für cmd Shell auf Windows)
Nane Kratzke's avatar
Nane Kratzke committed
233
234
    ```
    cp Dockerfile.alpine Dockerfile
Nane Kratzke's avatar
Typos    
Nane Kratzke committed
235
236
    docker build -t git.mylab.th-luebeck.de:4181/<max>.<mustermann>/image-test/web:alpine .
    docker push git.mylab.th-luebeck.de:4181/<max>.<mustermann>/image-test/web:alpine
Nane Kratzke's avatar
Nane Kratzke committed
237
238
239
    ```
    würde das Alpine-basierte Image erzeugen.
    ![registry-tag](registry-tags.png)
Nane Kratzke's avatar
Typos    
Nane Kratzke committed
240
    Dieses könnten Sie mittels `docker pull git.mylab.th-luebeck.de:4181/<max>.<mustermann>/image-test/web:alpine` auf Ihren lokalen Host herunterladen.
Nane Kratzke's avatar
Nane Kratzke committed
241
242
243
    Gebräuchlich ist dies, um unterschiedliche Versionen von Images mittels Versionsnummern wie `image:0.1.0` zu kennzeichnen.

Mittels dieser Tool-Chain lassen sich also Images in Registries zentral bereitstellen und für Deployments nutzen.
Nane Kratzke's avatar
Nane Kratzke committed
244

Nane Kratzke's avatar
Nane Kratzke committed
245
## Übung 04: Deployment-Pipeline zum Bau und Test eines Images
Nane Kratzke's avatar
Nane Kratzke committed
246
247
248

Dieser Teil soll Ihnen zeigen, wie Sie mittels einer Deployment Pipeline Images automatisiert bauen können. Gitlab Deployment Pipelines haben Sie ja bereits in einem vorherigen Lab kennengelernt.

Nane Kratzke's avatar
Nane Kratzke committed
249
1. Arbeiten Sie hierzu mit dem NGINX-Image: `cp Dockerfile.nginx Dockerfile` (Nutzen Sie ggf. `copy` für cmd Shell auf Windows)
Nane Kratzke's avatar
Nane Kratzke committed
250
251
252
253
254
255
256
257
258
259
260
261
262
263
2. Öffnen Sie die `.gitlab-ci.yml` Datei in einem Editor und versuchen Sie diese nachzuvollziehen.
   - Dort sind zwei Stages `test` und `build` mit jeweils einem Job definiert.
   - In der `test`-Stage wird Ihr Container Image gebaut, gestartet und anschließend mittels `curl` abgerufen. Die herunter geladene Datei wird mit der `web/index.html` verglichen. Sind diese identisch ist der Container richtig konfiguriert.
   - In der `build`-Stage wird das Container-Image für die Registry gebaut, entsprechend getagged und in die Registry gepushed. Gitlab CI blendet hierfür über mehrere Umgebungsvariablen wie `$CI_REGISTRY_USER`, `$CI_REGISTRY_PASSWORD` (Access Credentials), `$CI_REGISTRY` (URL der Registry) und `$CI_REGISTRY_NAME` (Repository) die erforderlichen Daten für Docker ein.
3. Kopieren Sie hierzu
   - den `web`-Ordner samt Inhalt,
   - das `Dockerfile`,
   - und die `.gitlab-ci.yml`
   
   in Ihr `image-test` Repository (z.B. mittels der WebIDE in Gitlab).
4. Committen Sie dann diese Änderungen (z.B. mittels der WebIDE in Gitlab). Dadurch wird die Pipeline automatisch angestoßen. Öffnen Sie dann in GitLab über __CI/CD -> Pipelines__ die Pipeline und verfolgen Sie deren Fortschritt. Die Pipeline sollte erfolgreich durchlaufen.
5. Öffnen Sie dann in GitLab über __Packages & Registries -> Container Registry__ die Registry Ihres Projekts. Dort sollten Sie nun auch einen `automatic` Tag sehen. Dieses Image wird nun immer dann aktualisiert, wenn Sie einen neuen Commit in das Repo pushen und die `test`-Stage erfolgreich bestanden wird.

Auf diese Art und Weise können Sie nun auch automatisiert im Rahmen von Deployment Pipelines Images bauen und bereitstellen.
Nane Kratzke's avatar
Nane Kratzke committed
264

Nane Kratzke's avatar
Nane Kratzke committed
265
## Links
Nane Kratzke's avatar
Nane Kratzke committed
266

Nane Kratzke's avatar
Nane Kratzke committed
267
- [Docker Playground](https://labs.play-with-docker.com/) (Online Lab, Registration erforderlich)
Nane Kratzke's avatar
Nane Kratzke committed
268
269
270
- [Docker Get Started](https://docs.docker.com/get-started/)
- [Docker Tutorials and Community Trainings](https://www.docker.com/play-with-docker)
- [Best Practices for Writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
Nane Kratzke's avatar
Nane Kratzke committed
271
- [Building Docker images with GitLab CI/CD](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html)
Nane Kratzke's avatar
Nane Kratzke committed
272

Nane Kratzke's avatar
Nane Kratzke committed
273
## Was sollten Sie mitnehmen
Nane Kratzke's avatar
Nane Kratzke committed
274

Nane Kratzke's avatar
Nane Kratzke committed
275
1. Mittels der den meisten Distributionen beiliegenden Package Managern ist es über `RUN`-Commands möglich in Basis-Images beliebige Software komfortabel und "non-interactive" zu installieren.
Nane Kratzke's avatar
Nane Kratzke committed
276
277
278
279
1. Eigener Code, Content oder Konfigurationen können mittels `ADD`-Commands dem Container-Image hinzugefügt werden (und danach mittels `RUN`-Commands auch kompiliert und installiert werden).
2. Sie können Server-Dienste mittels TCP-Ports nach außen `EXPOSE`n.
3. Über `ENTRYPOINT` können Sie hierzu den Prozess starten, der durch den Container bereitgestellt werden soll (vermeiden Sie dabei Prozesse als Daemons zu starten).
4. Image-Größen lassen sich mittels **RUN-Chaining** und der Wahl kleiner Basis-Images signifikant reduzieren.
Nane Kratzke's avatar
Nane Kratzke committed
280
5. Mittels `docker login` kann man sich auf entfernten Image-Registries einloggen um dann mittels `docker push` und `docker pull` Images auf privaten Registries hochladen bzw. herunterladen zu können.
Nane Kratzke's avatar
Nane Kratzke committed
281
6. Mittels GitLab Deployment Pipelines können Sie Images automatisiert testen und erstellen.