# Einheit 12: Virtualisierung & Container Technologien

## Ziele und Kompetenzen

* Vorteile von Virtualisierung und Containern **verstehen**
* &#x20;Containerisierung kennen lernen und eigene Container erstellen und starten **können**

## Motivation

**Die Idee hinter Containern**

Es gibt verschiedene Möglichkeiten umfangreiche Anwendungen zu installieren. Wir betrachten hier einige Möglichkeiten eine solche Anwendung zu installieren.

**Intuitives Vorgehen**

* Alle Dienste, Server-Komponenten und z-B- Datenbanken werden auf einer Maschine installieren
* Vorteile:
  * einfache Installation
  * einfache Kommunikation unter den Diensten
  * zunächst einfache Verwaltung und Wartung, da nur ein System verwaltet wird
* Nachteile:
  * Über die Zeit immer schwerer wartbar, da Änderungen am System nur noch schwer nachvollziehbar bzw. reproduzierbar sind

**Fortgeschrittenes Modell**

* Alle Dienste, Server-Komponenten und Datenbanken werden auf unterschiedlichen Servern installiert
* Hier benötigt man unter Umständen sehr viel Hardware, die am Ende des Tages nicht ausgelastet wird aber in Anschaffung und Unterhalt teuer ist.
* **Lösung:** Alle Dienste, Server-Komponenten und Datenbanken werden in **virtuellen Maschinen** (VM) installiert.
* Konkret würde dies z.B. bedeuten:
  * eine virtuelle Maschine für die Datenbank
  * eine virtuelle Maschine für das Backend
  * eine virtuelle Maschine für den Web Server
  * eine virtuelle Maschine für das Monitoring
* Vorteile:
  * Die VMs sind voneinander unabhängig
  * Ein Problem in einer virtuellen Maschine beeinflusst nicht die anderen Maschinen
  * Von den VMs lassen sich Backups erstellen und bei Bedarf wiedr einspielen&#x20;
* Nachteile:
  * Es müssen (sehr) viele (virtuelle) Maschinen gewartet und überwacht werden (Betriebssystem-Updates, Software-Update)
  * Erhöhter Ressourcenverbrauch, da virtuelle Maschinen exklusiv Hardware in Anspruch nehme

***

**Wie funktioniert eine virtuelle Maschine?**

* Eine virtuelle Maschine simuliert eine vollständige Hardware, auf der ein vollwertiges Betriebssystem installiert wird
* Einer solche virtuelle Maschine werden dedizierte Ressourcen des Host-Systems zugewiesen
  * CPU bzw. Kerne
  * Hauptspeicher
  * Festplattenplatz
* **Probleme**:
  * Die Ressourcen stehen weder dem Host-System, noch den anderen virtuellen Maschinen zur Verfügung
  * Die virtuelle Maschine bringt ihren ganz eigenen Hardware Abstraction Layer und simuliert die ganze Hardware

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FDcRZpcdi5kT061MxLQGK%2Fdevops.02.vms.png?alt=media&#x26;token=8338adef-449f-401c-a09d-a7e0690f3c42" alt=""><figcaption></figcaption></figure>

**Container Modell**

* Dienste, Server-Komponenten und Datenbanken werden in kleinen, isolierten Einheiten (aka Containern) betrieben

z.B.

* Container für Front-End
* Je ein Container pro Service
* Je ein Container pro Datenbank

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FQ1UpqZmLPe1Tdmz4quN7%2Fdevops.02.containers.png?alt=media&#x26;token=13080af9-53e5-49ea-9db2-6edc2630460a" alt=""><figcaption></figcaption></figure>

**Vorteile**

* Leichtgewichtig
* Unabhängig
* Konfigurierbar

**Nachteile**

* Verwaltung von sehr vielen Container erfordert eine Lösung (Stichwort Kubernetes)

***

## Container Grundlagen

**Wie funktionieren Container?**

* Private Sichten (Container) bilden isolierte User-Space-Instanzen für verschiedene Anwendungen
* Hardware-Virtualisierung, Isolation und API (Betriebssystem-Kernel, vgl. Betriebssysteme aus SEB2) werden kontrolliert
* Keine Virtualisierung des Betriebssystems, sondern eine Art der »User-Space-Virtualisierung« auf Basis von Kernel Features.

**Was ist ein Container von Julia Evans**

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FBm6XRxHKI5ZtP2okQ7xI%2Fdevops.02.julia_evans_container_zine.jpg?alt=media&#x26;token=6001852b-1a46-499d-8e75-0b713cc5460e" alt=""><figcaption><p>(© by Julia Evans, Zine used with pending permissions)</p></figcaption></figure>

**Beispiel einer Software in Containern**

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FBMBmv4o7p0UYuXPJ3fND%2Fdevops.02.example_arch.de.png?alt=media&#x26;token=d651f8c9-f611-4be1-8200-3afe3c24fa32" alt=""><figcaption></figcaption></figure>

**Automatisierung mit Containern**

* Mit Container-Technologie lässt sich sehr viel (alles) automatisieren
* Stichwort: GitLab CI/CD (später mehr dazu)
* Stichwort: Infrastructure as Code (IaS)
* Werkzeuge: Ansible, Salt, Puppet, Vagrant, GitLab CI/CD, GitHub Actions..

**Container können...**

* Unabhängig voneinander gewartet und aktualisiert werden
* Können in unterschiedlichen Versionen betrieben werden
* Beeinflussen sich nicht gegenseitig

**Container 101**

* Container enthalten eine Software und alle Abhängigkeiten
* Gestartet wird ein Container aus einem Abbild (engl. image)
* Container verhalten sich auf allen Maschinen gleich (Entwickler-Maschine, Server, Cloud-Anbieter, ...)
* Für die Software sieht der Container aus wie eine eigene Maschine
* Die Software weiß nicht, dass sie in einem Container steckt
* Wird ein Container gelöscht, werden keine Konfigurationsreste auf dem Host / dem Betriebssystem hinterlassen

> Daumenregel: Ein Dienst pro Container

## Möglichkeiten mit Containern

**Beispiel Microservices**

Alles auf einer Maschine oder jeder Dienst in einem eigenen Container?

* Container können über verschiedene Maschinen verteilt werden

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FNKhk0i5H5HLdIAonxyfG%2Fdevops.02.microservice_example_arch.de.png?alt=media&#x26;token=a699ec2d-0212-44be-a371-0f5e9f438602" alt=""><figcaption></figcaption></figure>

***

**Container und Netzwerke**

Container können über eigene Netzwerke miteinander kommunizieren

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FOMSfq6KSox8VWIgH0AWF%2Fdevops.02.network.de.png?alt=media&#x26;token=57b0f44f-ffe0-429a-b45a-48260ec53e14" alt=""><figcaption></figcaption></figure>

**Nutzung von Standard-Ports in Containern**

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FK92FQtkDGommdScJt1lJ%2Fdevops.02.ports.de.png?alt=media&#x26;token=802f6b8d-9677-4365-92cb-b8c997411ded" alt=""><figcaption></figcaption></figure>

***

**Reverse Proxy**

Ein Reverse Proxy löst dabei so manche Probleme einzelner Maschinen...

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FAUreJKwXdLYj5JMPGXck%2Fdevops.02.reverseproxy.de.png?alt=media&#x26;token=00128bb1-5da7-4b63-ac67-4e81d0bed2a7" alt=""><figcaption></figcaption></figure>

***

## Container Umgebungen

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2Fqc1g4i3oG9QLSstdibBw%2Fdevops.02.image_vs_container.png?alt=media&#x26;token=6c112522-c944-4593-8a61-c22ebd35424d" alt=""><figcaption></figcaption></figure>

## Docker Compose

Um mehrere Container zu orchestrieren kann `Compose`genutzt werden:

```bash
version: '3'
services:  my_db:
    image: postgres:9-alpine
    environment:
      POSTGRES_DB: mydb
      POSTGRES_PASSWORD: topsecret
      POSTGRES_USER: user1
volumes:
  - db-data:/var/lib/postgresql/data
restart: always
networks:
  - my_network
```

* Eine Konfigurationsdatei: `docker-compose.yml`
* Container werden mit `docker-compose up` gestartet
* Container werden mit `docker-compose down` gestoppt

**Vorsicht bei fertigen Images**

* Am Beispiel des *postgres*-Images
* Was steckt in dem Image?
* Wirklich nur die Datenbank?
* Vielleicht ein BitCoin Miner?
* Vielleicht ein SpamBot?
* Vielleicht ein Skript das alles DB-Einträge an jemanden übermittelt?
* Beim offiziellen Image weniger kritisch

<figure><img src="https://468234129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F26UMH8aq11ryvyyIwN0H%2Fuploads%2FKaNOSO2aHBz4uElsVnOL%2Fdevops.02.dockerhub.png?alt=media&#x26;token=5c578b19-f759-449d-8ecd-7736fdbedbd6" alt=""><figcaption></figcaption></figure>

## Image erstellen

Wie bekommt man Software in einen Container?

* Docker installieren (Linux, Windows, macOS)
  * Variante 2: Eigenes Image »bauen«, Container starten

```bash
FROM alpine
RUN apk --no-cache add inotify-tools jq openssl util-linux bash
COPY dumpcerts.sh /dumpcerts.sh
RUN chmod +x /dumpcerts.sh
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
```

* In einem File, z.B. `Dockerfile`

## Aufgabe

1. Docker installieren
   1. Docker Desktop (Windows, Mac, Linux): <https://www.docker.com/products/docker-desktop/>
   2. Install Docker Engines: <https://docs.docker.com/engine/install/>
2. Erstellen Sie ein [`Dockerfile`](https://docs.docker.com/engine/reference/builder/) auf Basis dessen Sie ein Image erstellen werden.
3. Installieren Sie in Ihrem Image [nginx](https://www.nginx.com/) als Webserver. Hinweis: Nutzen Sie hierfür **nicht** das *nginx* Image.
4. Erstellen Sie eine Default-Seite (`index.html`), die von Ihrem Webserver standardmäßig angezeigt wird.
5. Die `index.html` Datei soll auf Ihrem Host System vorliegen und via [`Volume`](http://nginx.org/en/docs/beginners_guide.html) oder [`Bind Mount`](https://docs.docker.com/storage/bind-mounts/) innerhalb des Containers bereitgestellt werden.
6. Stellen Sie sicher, dass *nginx* mit dem Starten des Containers startet.
7. Routen Sie den Port 8080 auf den Port 80 Ihres Containers und öffnen Sie die Datei vom Browser Ihres Hostsystems via (`http://localhost:8080/index.html`)
8. Ändern Sie die Datei auf dem Host-System und laden Sie die Datei neu im Browser.
9. Erstellen Sie eine README.TXT und notieren Sie die Zeile wie der Container über die Kommandozeile gebaut und gestartet werden kann.&#x20;

### Bewertungskriterien

* Das Image wird auf Basis des bereitgestellten `Dockerfile` und der README.TXT erstellt und der Container gestartet.
* Die bereitgestellte `index.html` wird via `http://localhost:8080` abgefragt.
* Im Anschluss wird die `index.html` auf dem Host-System verändert und neu im Browser geladen, die Änderungen sollen sich hierbei widerspiegeln.

Referenzen

\[1] c't wissen Docker DOCKER – Komplexe Software einfach einrichten, Heise Medien GmbH, 2019

\[2] Offizielle Docker Dokumentation: <https://docs.docker.com/>
