README.md 9.35 KB
Newer Older
Nane Kratzke's avatar
Nane Kratzke committed
1
# Lab 06: Kubernetes
Nane Kratzke's avatar
Nane Kratzke committed
2

3
In diesem Lab lernen Sie,
Nane Kratzke's avatar
Nane Kratzke committed
4

5
6
7
- wie Sie containerisierte Workloads automatisiert mittels einer Deployment Pipeline in Kubernetes deployen und skalieren können. 
- Sie lernen auch komplexere Deployment-Pipelines kennen, die Dienste in unterschiedlichen Ausbaustufen automatisiert ausbringen können.
- Sie erhalten ferner einen ersten Einblick in horizontale Skalierungstechniken und Self-Healing Fähigkeiten der Kubernetes-Plattform (z.B. durch Konzepte wie Deployment-Controller).
Nane Kratzke's avatar
Nane Kratzke committed
8

9
Hierzu entwickeln wir im Rahmen dieses Labs einen sehr einfachen Web-Dienst, der prüft, ob es sich bei einer gegebenen Zahl, um eine Primzahl handelt oder nicht. Das Gesamt-Deployment nutzt dabei folgende Kubernetes-Konzepte.
Nane Kratzke's avatar
Nane Kratzke committed
10

Nane Kratzke's avatar
Nane Kratzke committed
11
- Der Primzahl-Dienst kann über einen [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)-Controller von außen erreicht werden.
12
- Der Primzahl-Dienst wird Cluster-intern als [Service](https://kubernetes.io/docs/concepts/services-networking/service/) exponiert.
Nane Kratzke's avatar
Nane Kratzke committed
13
14
- Dieser Service fasst über ein [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) ausgebrachte Pods unter einer Netzwerkadresse zusammen. Über das Deployment kann die Primzahllast horizontal skaliert werden.
- Die Pods selber prüfen die Primzahlen. Zahlen, die in vorhergehenden Aufrufen bereits als Primzahlen verworfen wurden, können in einem In-Memory Key-Value Cache ([Redis](https://redis.io)) gespeichert werden, um wiederholte Prüfungen zu vermeiden und die Primzahlprüfung zu beschleunigen.
15
16
- Der Redis Cache wird als Deployment mit vorgelagertem Service ausgebracht, so dass die Primzahl-prüfenden Pods nur den Service Namen, nicht aber die IP-Adresse des Redis-Pods kennen müssen (DNS-basiertes Service Discovery).
- Durch ein Persistent Volume Claim ([PVC](https://kubernetes.io/docs/concepts/storage/persistent-volumes)) kann der Redis Pod ein Volume mounten um den Cache Zustand zu persistieren. So kann der Cache auch über Redis Restarts seinen Zustand erhalten (Resilience, Isolated Persistency).
Nane Kratzke's avatar
Nane Kratzke committed
17
  
Nane Kratzke's avatar
Nane Kratzke committed
18
```
Nane Kratzke's avatar
Nane Kratzke committed
19
20
|----------------- Übung 01 -----------------|----------- Übung 02 ----------|

Nane Kratzke's avatar
Nane Kratzke committed
21
22
23
24
25
26
                                ---------
                             /- Prime Pod -\
                             |  ---------  |
                             |- Prime Pod -|
-------     -------------    |  ---------  |     -------------      ---------
Ingress --- Prime Service ---|- Prime Pod -|---  Redis Service ---  Redis Pod
Nane Kratzke's avatar
Nane Kratzke committed
27
28
29
30
-------     -------------    |  ---------  |     -------------      ---------     ---
                             |-    ...    -|                            |          |
                             |  ---------  |                        ---------      |
                             \- Prime Pod -/                        Redis PVC      |
31
                                ---------                           ---------     Übung 03
Nane Kratzke's avatar
Nane Kratzke committed
32
33
34
35
                                                                        |          |
                                                                    ---------      |
                                                                     Volume        |
                                                                    ---------     ---
Nane Kratzke's avatar
Nane Kratzke committed
36
37
38
39
40
```


## Inhalt

Nane Kratzke's avatar
Nane Kratzke committed
41
- [Lab 06: Kubernetes](#lab-06-kubernetes)
Nane Kratzke's avatar
Nane Kratzke committed
42
43
  - [Inhalt](#inhalt)
  - [Vorbereitung](#vorbereitung)
Nane Kratzke's avatar
Nane Kratzke committed
44
  - [Übung 01: Deployment eines Prime Service](#übung-01-deployment-eines-prime-service)
45
46
  - [Übung 02: Ergänzung eines In-Memory Caches](#übung-02-ergänzung-eines-in-memory-caches)
  - [Übung 03: Erweiterung zu einem persistentem Cache](#übung-03-erweiterung-zu-einem-persistentem-cache)
Nane Kratzke's avatar
Nane Kratzke committed
47
48
  - [Übung 04: Skalierung und Chaos Engineering](#übung-04-skalierung-und-chaos-engineering)
  - [Übung 05: Deployment des Prime Service in GKE](#übung-05-deployment-des-prime-service-in-gke)
Nane Kratzke's avatar
Nane Kratzke committed
49
50
51

## Vorbereitung

52
53
54
55
56
57
58
59
- [Forken](https://git.mylab.th-luebeck.de/cloud-native/lab-k8s/-/forks/new) Sie bitte dieses GitLab-Repository in Ihren GitLab-Namensraum.
- Installieren Sie anschließend bitte lokal auf Ihrem Rechner die Kubernetes-IDE [Lens](https://k8slens.dev/).
- Laden Sie sich Ihre `kubeconfig` Datei im [Moodle-Kurs](https://lernraum.th-luebeck.de/course/view.php?id=3156) herunter.
- Starten Sie Lens und fügen Sie der IDE die kubeconfig Datei hinzu, um auf Ihren Cluster zugreifen zu können. Sie sollten dann Ihren Namespace in dem für Sie bereitgestellten K8S-Cluster sehen.
- Hinterlegen Sie in Ihrem geforkten GitLab-Repository nun die `kubeconfig`-Datei als CI-Environment-Variable mittels `Einstellungen -> CI/CI -> Variables (Aufklappen) -> ADD VARIABLE` (setzen Sie hierfür folgende Werte)
  - Key: `KUBECONFIG` (Exakt so eingeben)
  - Value: Inhalt der kubeconfig (z.B. mittels Copy-Paste aus Editor)
  - Typ: `File` (Auswählen, WICHTIG!!!)
Nane Kratzke's avatar
Nane Kratzke committed
60
61
62

## Übung 01: Deployment eines Prime Service

63
Im Verzeichen `prime` finden Sie den Python Source Code zu diesem Lab. Bitte sehen Sie sich diesen an und versuchen diesen zu verstehen.
Nane Kratzke's avatar
Nane Kratzke committed
64

65
66
67
68
69
70
71
72
73
74
- Die Funktionen `lookup()` und `cache()` stellen die Verbindung zum Redis-Cache her. Steht kein Redis-Cache zur Verfügung, funktionieren die Funktionen dennoch, liefern dann aber natürlich keine Treffer aus dem Cache. Die Performance sinkt dadurch natürlich, der Service ist aber weiter nutzbar (Resilience).
- Mittels der Library [Flask](https://palletsprojects.com/p/flask/) wird eine Mini-REST-API aufgesetzt, die im wesentlichen nur eine URL registriert `/prime/<number>`. Über diese Route lässt sich prüfen, ob eine gegebene Zahl eine Primzahl ist (z.B. `/prime/1234`).

Studieren Sie nun bitte die Deployment-Pipeline in der `.gitlab-ci.yml`-Datei. Diese besteht aus vier Stages:

  - `prepare`: Hier werden Vorbereitungen getroffen (z.B. werden die Registry Credentials hinterlegt oder Volumes per Persistent Volume Claim angefordert, falls ein persistenter Cache deployed werden soll).
  - `build`: Hier wird der Prime Container gebaut und in die Registry gepushed.
  - `deploy`: Hier werden die Kubernetes Ressourcen deployed (aktualisiert).
  - `terminate`: Hier wird das Deployment terminiert (alle Ressourcen gelöscht, inkl. des Volumes!).

Nane Kratzke's avatar
Nane Kratzke committed
75
Insbesondere die `deploy` Stage kann über die folgenden  Umgebungsvariablen gesteuert werden:
76
77

```yaml
Nane Kratzke's avatar
Nane Kratzke committed
78
79
80
  PRIME: "yes"             # Prime Service soll ausgebracht werden ("yes" oder "no")
  CACHE: "no"              # one of "no", "in-memory", "persistent"
  TERMINATE: "no"          # Das Deployment soll terminiert werden ("yes" oder "no").
81
82
83
84
85
86
87
88
89
90
91
92
93
```

Sehen Sie sich nun die Manifeste in folgenden Verzeichnissen an und versuchen Sie diese bitte nachzuvollziehen:

- `deploy/prime`: Sie finden hier ein Deployment, um mehrere Prime Pods zu deployen (`prime-deployment.yaml`). Ferner eine Service Definition, um diese Pods unter einem DNS-Namen im Cluster ansprechen zu können (`prime-service.yaml`) und zu guter letzt eine Ingress Definition, die diesen Service Cluster-extern mittels HTTPS exponiert. Dieser Dreiklang `Deployment -> Service -> Ingress` ist ein recht typisches Pattern in Kubernetes.
- `deploy/storage`: Sie finden hier ein Persistent Volume Claim, mit dem ein Volume angefordert wird, welches von dem Pod des Redis Deployments gemountet werden kann (persistenter Cache).
- `deploy/redis`: Sie finden hier ein Manifest das sowohl ein Deployment eines Redis Containers und einem davor liegenden Service definiert. Anders als in `deploy/prime` definieren wir hier alles in einem Manifest (um zu zeigen, dass dies auch geht). Der Redis Dienst ist allerdings so definiert, dass kein Volume als persistente Speicherasset gemountet wird. Diese Variante vergisst als den Cache-Zustand bei einem Restart.
- `deploy/persistent-redis`: Diese Redis-Variante ist so definiert, dass das mittels `deploy/storage` angeforderte Volume als persistente Speicherasset vom Redis Pod gemountet wird. Diese Cacheing Variante vergisst also den Cache-Zustand bei einem Restart nicht!

**Schritte:**

Arbeiten Sie bitte mit der WebIDE von GitLab. Committen Sie dabei bitte immer in den Master-Branch!

Nane Kratzke's avatar
Nane Kratzke committed
94
95
96
97
98
99
1. Um die Basis-Version des Prime-Service auszubringen (ohne Caching) setzen Sie bitte die `PRIME` Variable in der `.gitlab-ci.yml`-Datei auf `"yes"`.
2. Committen Sie dann in den Master-Branch. Dies sollte die Deployment-Pipeline triggern. Sie können den Verlauf des Deployments sowohl in GitLab als auch die deployten Kubernetes Ressourcen in Lens ansehen (der Pipeline Lauf kann ein bis zwei Minuten dauern).
3. Geben Sie in der Konsole von Lens nach erfolgreicher Pipeline folgendes ein:
   ```bash
   kubectl get all
   ```
100
101
102
103

## Übung 02: Ergänzung eines In-Memory Caches

## Übung 03: Erweiterung zu einem persistentem Cache
Nane Kratzke's avatar
Nane Kratzke committed
104
105
106
107
108
109
110
111

## Übung 04: Skalierung und Chaos Engineering



## Übung 05: Deployment des Prime Service in GKE

In diesem Schritt passen wir das in den Übungen 1 bis 3 entwickelte Deployment so an, dass es in [GKE](https://cloud.google.com/kubernetes-engine) (Google Kubernetes Engine, also einem Public Cloud Service Provider) automatisiert ausgebracht werden kann. Dies soll Ihnen zeigen, dass Kubernetes grundsätzlich eine recht standardisierte Plattform ist, die sowohl Self-Hosted in einer Private Cloud als Plain-Vanilla Kubernetes oder als Managed-Service in einer Public Cloud nutzbar ist. Tatsächlich bieten mittlerweile fast alle großen Public Cloud Service Provider Kubernetes-basierte Dienste an. Kubernetes hat es so eine Art de-facto Standard etabliert und die ehemals sehr heterogene PaaS Landschaft bis zu einem gewissen Grad vereinheitlicht.
Nane Kratzke's avatar
Nane Kratzke committed
112