35C3 Vorspannmusik
Herald: Hallo, hallo! Okay, unser nächster
Speaker hier ist der Tobias von "Code for
Münster" und hat das Thema Kubernetes
Development oder so – und ich habe keine
Ahnung, was das ist und er konnte es mir so
schnell auch nicht wirklich verständlich
erklären, aber er wird das jetzt für
euch sicher ausführlich machen. Also ein
kleiner Applaus für Tobias bitte.
Applause
Tobias: Vielen Dank! Ja, also ich werde
jetzt in ein paar Minuten mal versuchen
Kubernetes so ein bisschen die
Architektur zu erklären und warum ich
glaube, dass das ein ganz gute Plattform
ist um eben in "Code-for-Labs" seine Apps zu
deployen und dann auch weiter maintainen
zu können. Wer von euch weiß ungefähr, was
Kubernetes ist? Ja top! Und kennt ihr auch
alle schon Docker und Container-
Technologie? Also grundsätzlich, wenn
irgendwelche fragen sind, haut die einfach
zwischendurch raus. Wir können hier auch
so ein bisschen, einfach so, Frage-und-Antwort
machen. Ansonsten fange ich einfach mal so
an. In Münster treffen wir uns regelmäßig,
seit drei Jahren mittlerweile, unter dem
Topic "Code for Münster" und ich glaube seit
zwei Jahren haben wir auch schon ein
Kubernetes-Cluster laufen. Ich selber mache
auch beruflich einiges damit, also auch
deswegen habe ich da eigentlich Spaß dran
und mittlerweile, bei uns in Münster, sind
glaube ich auch schon so drei Leute, die
theoretisch Kubernetes betreuen könnten
und grundsätzlich jeder der neu irgendwie
dazu kommt, kommt nicht darum, irgendwie
Docker kennen zu lernen, aber hat auch
durchaus viele Vorteile und ich hoffe die
kriege ich jetzt rüber gebracht. Wir können
mit dem spaßigsten Teil beginnen, da
versuche ich was zu zeichnen. Wenn das
jetzt irgendwie gar nicht klappt, dann habe ich
die Zeichnung von gestern aus dem Zug noch,
die ich Ihnen zeigen könnte. Grundsätzlich
zur Architektur von Kubernetes: Es gibt
da drei Grundprinzipien. Das eine ist das
alles, was man gegen die Kubernetes-API
schicken möchte, also alles was nachher im
Cluster laufen soll, das definiert man
vorher in einer Datei, in einem Manifest. Das ist
klassischerweise in YAML, kann auch JSON
sein, aber es ist einfach ein
strukturiertes Format. Ich kann mal kurz
ein Beispiel, glaube ich, auch zeigen. Hier,
das sind alle unsere Sachen, die wir bei
uns im Cluster laufen lassen und eine
Beispiel-App hier. Da haben wir halt einige
Dateien. Die wichtigste ist diese hier, das
sieht am Anfang ein bisschen wild aus,
im Endeffekt, wenn man Docker kennt und
Containerisierung, ist das die Zeile. Man
sagt dieses Image soll ausgeführt werden
und kann dazu noch ein paar Dinge angeben
und dann gibt es noch so weitere
Abstraktions-Geschichten, wie Service und
Ingress, erzähl ich gleich auch noch was
dazu.
Am Anfang mag das alles ein
bisschen viel sein, hat aber den Vorteil,
dass eben egal auf welchem Cloud-Provider
man läuft oder ob man selber Server
betreibt, man quasi nur diese Kubernetes-
Abstraktionsschicht braucht und man
sich gegenseitig aushelfen kann, gerade
speziell in diese "Code-For-Labs". Also
diese Manifeste kann die Kubernetes-API
verstehen. Das heißt, am Anfang haben wir
hier - ach so - unsere YAML-Dateien und dann
die Kubernetes-API, die läuft auf einem
Server. Das Ganze ist dann die Control
Plane von Kubernetes, quasi das ist das
Herzstück und alles was wir machen, über
die Kommandozeile oder Ähnliches, geht über
den API-Server. Der API-Server hat dann
noch eine Datenbank im Hintergrund, weil er
selbst einfach nicht viel macht. Der nimmt
einfach nur die Manifeste entgegen, legt die in
der Datenbank ab und verteilt die dann
eventuell an Controller, die es dann noch
gibt und davon kann's dann mehrere geben.
Also an sich, die Struktur, serverseitig, ist
relativ simpel. Dann hat man noch weitere
Server, die nennen wir einfach nur "Nodes",
und jeder von diesen Servern hat eine
Software laufen, nennt sich "Cubelet", und der
API-Server unterhält sich mit denen dann
in erster Linie und, ja, das ist im Grunde
die Grundstruktur. Auf all diesen Nodes
läuft dann Docker oder eine andere
Containerisierungsform und die Idee, das
Besondere jetzt oder ein weiterer
Architekturpunkt von Kubernetes ist, dass
er ständig vergleicht: Was möchten wir
eigentlich, dass auf dem Cluster läuft –
das sind eben unsere YAML Manifeste –
und über die Cubelets kann er eben erfragen:
Was läuft wirklich? Also sobald es eine
Differenz gibt, kann er hingehen und
versuchen, das irgendwie auszugleichen. Also
wenn irgendeine App abgestürzt ist oder zu
viel Speicher gebraucht hat oder ist
Netzwerkprobleme gab, dann kriegt er das
mit. Das ist eventuell
ein Unterschied gegenüber einem Setup, wo
man selber Docker-Container startet oder
über "Docker Compose" oder Ähnliches. Gibt's so
weit schon mal Fragen? Sonst ist das im
Grunde das Wichtigste, was so Kubernetes
angeht. Und es soll jetzt ja auch nicht
jeder in den Code-for-Labs komplett das
Bedienen von Kubernetes
beherrschen müssen. Das ist bei uns in
Münster auch nicht der Fall, aber trotzdem
hilft es, dass man mit mehreren Leuten
gemeinsam Dinge auf dem Cluster spielt
oder auf Servern laufen lässt. Diese YAML-
Manifeste kann man nämlich sehr gut
einfach alle in einem Git-Repo liegen
haben. Diese YAML-Manifeste schickt man
gegen die Kubernetes-API, indem man auf
der Kommandozeile "cubecontrol apply" ausführt,
kann man rekursiv machen über ganze
Verzeichnisse. Und hier bei uns in Münster
habt ihr eben schon gesehen, das sind quasi
die Verzeichnisse mit allen Apps, die wir
drauf laufen lassen haben und – halt alle
Änderungen, die am Server, einem Cluster,
geschehen sollen, laufen über dieses Repo.
Also das heißt: Die Leute stellen Pull-
Requests, wenn eine neue App rein soll oder
wenn irgendwelche Konfigurationen geändert
werden oder neue Versionen ausgerollt
werden soll – und andere können drüber
schauen, ob das okay ist und das Ganze dann
committen, mergen und dann kann man es
gegen den Cluster spielen. Das heißt, es
ist nicht so, dass irgendjemand mit SSH auf
Maschinen draufgeht und da dann
irgendwelche Details konfiguriert und man
hat nachher mehrere Server und
typischerweise weiß keiner so genau wie
wichtig welche Konfigurationseinstellung
ist oder irgendwelche Sicherheitspatches
jetzt schon drauf sind oder eben nicht. In
diesem Kubernetes-Setup können wir
theoretisch auch hingehen und den ganzen
Cluster wegschmeißen, neue Server
aufsetzen und alles gegen den Server
spielen und die Sachen kämen dann wieder
hoch. Abgesehen von dem Kram, den man in den
Datenbanken oder auf dem Filesystem hat, da
muss man sich dann eben um die Backups
kümmern, aber theoretisch ist es ein
relativ klar strukturierter Ansatz, also
man hat gut einsehbar, was auf dem Cluster
laufen soll und Kubernetes sorgt dann dafür,
dass es auch der Fall ist. Man hat einige
Abstraktionsmöglichkeiten, wenn es um die
Domainverwaltung geht oder Let's Encrypt,
zeig ich gleich kurz. Und man hat quasi
dann auch, wenn man sich dieses Repo
anschaut, dann so ein Audit Log. Also man
weiß, was passiert ist, wer wann was gemacht hat,
sodass man durchaus mit mehreren Leuten
gemeinsam so ein Cluster betreiben kann
und solange ein paar Leute Kubernetes
verstehen, können die halt aushelfen und es
ist nicht irgendwie eine Person, die nur Zugang
hat und an der dann alles hängt. Also ein
Beispiel ist die unsere "Traffics Shiny App".
Da kam einer zu uns, der gut R konnte, hatte
aber noch keine Idee von Docker und meinte,
bei ihnen an der Uni gehen sie auch
einfach per SSH auf die Maschinen und
starten da irgendwas und – Aber da
wir das halt gar nicht mehr machen, haben
wir ihm soweit Docker beigebracht – oder es
hat ihn auch interessiert und im Endeffekt,
wenn er an seiner App halt was Neues
gebastelt hat, dann kann er auf GitHub
hingehen und ein neues Release erzeugen, als
ein Beispiel für eine sehr einfache Pipeline.
Und das würde dann automatisch einen neuen
Build anstoßen, auf dem Docker-Hub. Und dann
läuft auf dem Cluster ein Tool von der
Firma "weaveworks", das einfach im Cluster
sitzt und die ganze Zeit auf dem Docker-Hub
schaut, ob neue Images da sind. Und
sobald er eine neue Version findet, würde
er die auf den Cluster schieben. Also, da
muss man jetzt auch nicht unbedingt den
Docker-Hub nehmen, man kann auch Quay
nehmen, anstatt GitHub auch GitLab. GitLab hat
selber für Kubernetes, glaube ich, ein paar
Tools und Integrationen. Aber theoretisch
können halt Leute, die auch eben gar keine
Lust haben an Server-Management, mit
relativ simplen Sachen ihre neue App basteln,
sagen neues Release und wenn sie ein
bisschen warten, ist die automatisch dann
auf dem Cluster in der neuen Version. Wenn
jetzt mehrere Leute gemeinsam auf dem
Cluster unterwegs sind, dann möchte man ja
trotzdem, auch wenn sie gegenseitig sich
freundlich gesinnt sind, ein bisschen
Isolation haben, sodass man ihnen die
– wenn eine App irgendwie Amok läuft,
dass das dann nicht alle anderen mit runter
reißt – und da bietet Kubernetes auch von
Haus aus eine Menge Sachen. Einmal kann man
nach Namespaces isolieren. Hier, das
wäre das Kommandozeilen-Tool "CubeControl".
Hier sieht man jetzt die Namespaces, die
laufen und die Apps kann man mehr oder
weniger gegeneinander über Namespaces
isolieren. Aber so könnte man neben meinem
Team oder eben auch einem Code-For-Lab in
die Namespace zuweisen und ihnen den
Zugriff auf anderen Namespaces verhindern.
Und was auch noch interessant ist: Man kann
dann nachher die Container, die man laufen
lässt, denen kann man jeweils zuweisen, wie
viel Speicher sie maximal benutzen dürfen
oder wie viel CPU und in Zukunft
wahrscheinlich auch noch ein paar mehr
Sachen. Das definiert man dann genauso in
den in den YAML-Manifesten. Deswegen sehen
die halt sehr komplex aus, weil man darüber
alles Mögliche nachher einrichten kann. Es
gibt dann – ja – also Kubernetes wird, alle
drei Monate gibt es ein neues Release und
da kommen eigentlich halt laufend neue
Features rein. Es wird von einer Foundation,
von der "Cloud Native Computing Foundation"
heißt sie glaube ich, soweit betreut und im
Hintergrund stehen halt alle möglichen
großen Firmen und auch viele kleine, von
RedHat, Microsoft, Amazon, Google
logischerweise und die gesamte Entwicklung
geschieht aber komplett offen, also man
kann alles auf GitHub – Kubernetes verfolgen
und es gibt so Special Interest Groups für
die verschiedenen Bereiche, eben auch bei
Netzwerk-Geschichten oder Rechte-
Geschichten, die machen auch teilweise
wöchentliche Treffen, wo man sich dann
irgendwie zuschalten kann über Hangout. Also das
ganze System ist halt sehr offen und die
Community ist sehr wichtig in dem ganzen
Entwicklungsprozess und laufend gibt es
halt weitere Features vor allem in Sachen
Sicherheit, ja, oder auch Dinge, die uns
das Leben einfacher machen. Zum Beispiel
gibt es eine Abstraktionsschicht, das nennt
sich Ingresses. Also wir haben unsere Apps
jetzt in Containern laufen auf dem
Cluster. Jetzt hätten wir gerne, dass wir
die von außen immer die Domain erreichen
können. Und da gibt es einfach ein Tool das
man installieren kann. Das nennt sich – das
ist im Endeffekt ein Proxy auf Basis von
NGINX, hier haben wir nur Text, wir können
mal kurz bei uns schauen, die werden auch
über die YAML-Manifeste
definiert und hier sehen wir jetzt die
verschiedenen Domains und die verweisen
jeweils dann quasi über einen
Zwischenschritt noch auf die Container, die
laufen. Das heißt, wir definieren, ich habe
glaube ich, wo hab ichs, wahrscheinlich hier –
Genau. Das sieht im Endeffekt so aus. Auch
wieder für diese "Traffics Shiny App", da
tragen wir ein: Das soll die Domain
sein, verweist auf Container, die unter dem
Namen laufen und außerdem hätten wir gerne
das automatisch Let's Encrypt eingerichtet
wird. Also derjenige, der diese App bastelt
und auf den Cluster schiebt, braucht sich
selbst darum auch nicht kümmern. Er muss
nur sagen, wie die Adresse heißen soll, dann
wird es angelegt, im Hintergrund "Let´s
Encrypt"-Zertifikate erzeugt – die werden
auch passend erneuert. Man muss es nur halt
einmal definieren, dass man das gerne haben
möchte und man muss noch ein Cert-
Manager im Cluster laufen lassen. Also im
Endeffekt: Dieser Ingres-Controller oder
die Cert-Manager, die laufen die ganze Zeit
im Hintergrund und gucken, ob eine neue
Ingress-Definition gegen die Kubernetes-
API geschickt wird. Und sobald sie das
sehen, konfigurieren sie NGINX neu, holen
sich die "Let's Encrypt"-Zertifikate, legen
die passend ab. Also alles Dinge, die man
sich im Detail anschauen kann, wenn man
möchte, aber eben nicht unbedingt muss.
Was natürlich auch ganz nett ist, wenn man
einmal Monitoring für den Cluster
eingerichtet hat – oder eben Logdateien, die
kann man alle zentral sich von all den
Containern holen, die über mehrere Server
verteilt laufen und dann zentral sich
anschauen. Also zu Monitoring wird oft
Prometheus im Hintergrund eingesetzt und
Graphana, und so kann man sich Dashboards
irgendwie basteln und jeweils dann auch für
eine bestimmte App oder für einen Namespace
filtern und den tatsächlichen CPU oder
Netzwerkverkehr sich anschauen. Also es
muss halt nur einmal gemacht werden und
auch wenn neue Apps eingerichtet werden
und hoch kommen, läuft automatisch alles
mit ins Monitoring oder Logging über
Elasticsearch und Kibana. Ja, und dann kann
man auf der Basis auch Alerts definieren
und die in seinen Slack-Channel (also Open-
Knowledge-Channel) theoretisch irgendwie
schicken lassen und dann könnten ein paar
Freiwillige sich darum kümmern, wenn sie
sehen, dass irgendwas im Argen liegt. Paar
Sachen gibt es auch bei uns immer noch zu
verbessern. Also einmal zur Zeit nutzen wir
den Standardweg zur Authentifizierung. Das
sind Zertifikate bei Kubernetes. Das kann
man eventuell auch eleganter lösen über
ein Keycloak-Setup und dann hauen wir
unsere Leute in eine GitHub-Gruppe und die
bekommen dann darüber Zugriff. Wir haben
auch schon laufen ein verteiltes
Dateisystem. Also alle unsere drei Server
laufen zur Zeit bei Scaleway, und die haben
halt irgendwie keinen Cloudspeicher.
Deswegen muss man sich halt selber darum
kümmern, dass man sein System am
besten verteilt laufen lässt, weil wir ja
auch ausfallsicher sein wollen, falls
mal ein Node irgendwie komplett abschmiert.
Und da gibt es auch verschiedene Sachen,
die fürs Kubernetes Umfeld gebastelt
werden. Zum Beispiel OpenEBS. Da
kann man dann einfach die dis definieren,
die bei den bei den Servern hängen und
sagt, wie stark die Replizierung sein soll.
Wir spielen ein bisschen rum. Also da gibt es
auch immer Versionsupdates und man muss
gucken, wie gut man das migriert kriegt. Ist
noch ein bisschen testweise, aber auch
theoretisch dann die Möglichkeit, dass man
einfach eine App starten lässt, der
Speicher OpenEBS zuweist und egal,
ob diese App nachher – auf welchem Server
die nachher startet, kriegt die Zugriff auf
ihre Daten. Das ist falsch, da muss
man ein Leerzeichen zwischen. So weit von
mir. Wir haben unser Setup bei
"Code for Münster" laufen. Ich selber kann auch
gerne noch mehr zu Kubernetes erzählen.
Also auch die nächsten ein, zwei Tage.
@webwurst ist das Kürzel auf Twitter, GitHub,
Gmail oder einfach googlen. Der Name ist nicht so
oft verwendet. Ja, also die Grundidee für
den Talk war ein bisschen, dass, wenn andere
Code-for-Labs irgendwie auch Lust haben... Am
meisten Sinn macht es wahrscheinlich, dass
man sich Server teilt. Also wir haben eben
drei Server, die jetzt jeweils – die
insgesamt ungefähr 100 Gigabyte RAM
haben. Das ist uns eigentlich zu viel, aber
kleinere sind irgendwie wieder teurer. Also
falls sich Leute zusammentun wollen oder
einfach nur neugierig sind auf Kubernetes
und wie man das sinnvoll einsetzt, haben
wir die Beispiele, helfen gerne aus – ja, und
würden gerne auch zusammenarbeit mit
anderen Code-for-Labs. Vielen Dank.
Applaus
Herald: Tobias – danke dir. So, wir haben noch
ein bisschen Zeit für Fragen. Also wenn
irgendwer eine Frage hat, dann könnt ihr
mal irgendein Zeichen geben. Dann komme ich
gerne mit dem Mikrofon zu euch.
Mensch 1: Ich hätte 'ne Frage, und zwar:
Ich hab das eben nicht ganz verstanden.
OpenEBS wolltet ihr als verteiltes Dateisystem
später einsetzen. Was nutzt ihr jetzt und
wieso habt ihr euch für OpenEBS entschieden?
Tobias: Wir hatten uns vorher mal Rook
angeschaut. Wir haben jetzt OpenEBS schon
laufen, aber ich nenne es noch
experimentell. Also version 0.7 läuft,
gerade 0.8 ist glaube ich raus. Warum? Ich
hatte mit denen auf der auf der KubeCon
in Kopenhagen gesprochen und das sind
irgendwie 200 Leute im Team, die viel Storage
schon gemacht haben, komplett Open Source
und ich glaube, die haben da ganz gute
ideen – auch wenn das relativ komplex ist,
was die da so schreiben zu ihrer
Architektur. Aber ja, das ist einfach der
Grund. Wir sind auch offen für anderes, wenn's
gute Erfahrungen gibt, wenn du welche hast...
Mensch1: Nee, also ich frage deshalb, weil
wir haben nämlich auch den Instanzen,
mit denen ich bisher Erfahrungen gesammelt
habe, war das immer das große Fragezeichen
am Ende: Was was benutzen wir als Persistant
Storage? Weil ich finde, da sind die
Hürden sehr hoch für einen Einstieg, sage ich
mal. – oder was auch immer man da
irgendwie als als Dateisystem benutzen kann...
Und deswegen war ich einfach
nur neugierig.
Tobias: Das stimmt.
Mensch1: Weil, die Entscheidung steht
uns auch noch bevor.
Tobias: Alternativ, wenn du eine verteilte
Datenbank hast, kannst du eben auch Local
Storage benutzen, aber – ja – musst du
halt irgendwie über die Datenbank
dann gehen. Ja.
Herald: Hier hinten war noch...
Mensch 2: Hallo. Ich wollte fragen: Wie lange
hat es dauert, euch das ganze Setup aufzusetzen
und seid ihr irgendwo darauf gestoßen,
wo ihr das nicht so umsetzen konntet, wie ihr
das umsetzen wolltet, beim Alarming oder
Monitoring oder so? Also irgendwas rein
hacken haben müssen?
Tobias: Das Ganze ist schwer zu sagen. Als
wir angefangen haben, hatten wir auch
relativ – ich glaube, da gab es noch nicht so
super viel fertiges Tooling. Ich glaub,
Prometheus und Graphana hatten wir selbst
gebastelt, dann mit Docker auch noch, und das
war so "learning by doing" auch ein bisschen.
Aber mittlerweile sehe ich jetzt eben
halt: Storage ist immer ein bisschen eine
Schwierigkeit oder verteilte Datenbanken,
aber grundsätzlich – der Aufbau von dem
System oder eben auch diese einfache
Pipeline mit Flux, das steht halt und
tut. Also, da haben wir keine großen Probleme
gerade. Auch im Monitoring ändert
sich halt laufend was. Also am spannendsten
ist jetzt der Prometheus Operator
eventuell und da gibt es dann Kube
Prometheus, und die generieren dir eine
ganze Menge Dashboards, und du hast auch
eine Art Programmiersprache dann für die
Dashboards, die du verwenden kannst. Ja, es gibt
ständig was Neues zu entdecken und
auszuprobieren.
Herald: Okay, hier war noch jemand...
Mensch 3: Vielleicht könnt ihr auch noch
probieren, die StorageOS. ich
habe mit den Leuten auch geredet auch in
Kopenhagen. Sieht auch interessant aus.
Und dann, Sie haben drei Server?
Tobias: Ja.
Mensch 3: So, das sind drei Master
und auch Node?
Tobias: Ja. Also wir haben den Master
halt nur auf einem laufen, aber
trotzdem nutzen wir den auch für normale –
Mensch 3: Nur ein Master?
Tobias: Ja, wir haben einen Master,
und wenn der down geht,
läuft ja der restliche Kram auch noch
weiter, bis wir ihn wieder hochziehen.
Das Ding ist, dass wir das eben auch
alles hobbymäßig machen und selber
finanzieren. Also für das Code-for... auch
nur einer. Funktioniert aber, wenn
ich den einfach neu starte, dann
warte ich fünf Minuten und dann hat sich
alles wieder gefunden. Ja, und die Apps auf
den anderen Nodes laufen halt eh weiter und
können weiter von außen erreichbar sein.
Mensch 3: Habt ihr schon mal gedacht, ein
Operator? Dann bräuchte man nicht
die Storage distribuieren, aber dann
alle sieben, dann wird zum Beispiel Postgres,
der wird realisiert und der Operator, der
handelt das.
Tobias: Ja, gucken wir uns auf jeden Fall
an, was es da gibt. Oft hat man eben nicht –
Elasticsearch tut es ganz gut, wenn man
das Ding in dreifach laufen lässt. Postgres
und MySQL kann man ganz gut hochziehen als
Operator über mehrere Nodes, aber
sobald irgendwas schief läuft, können die
Operator zur Zeit da noch nicht aushelfen.
Dann muss man die man alle manuell neu
starten. Das ist okay, aber irgendwie –
es gibt nicht so viel was sich selbst dann
repariert. Wird wahrscheinlich noch kommen,
aber –
Herald: Du hattest eine Frage?
Mensch 4: Du hattest gerade, wenn der
Master kaputt geht, dann funktionieren die
Services trotzdem weiter. Wie macht ihr das
dann mit diesem Ingress, also wo kommt
das DNS an?
Tobias: Wir haben es versucht über so
einen DNS Round Robin. Also es war einfach –
Der Ingress Controller läuft auf allen – dingens.
Ja gerne was Besseres, aber bei Scaleway, wo wir
sind, die haben halt keinen Loadbalancer
davor. Also die bieten das nicht irgendwie als
Service an. Die haben wohl eine IP, die man
von Node zu Node ziehen kann, aber auch nicht
gleichzeitig an mehrere. Ja, es ist halt ein
günstiges Setup für Code-for. Wenn sich mehr
zusammentun, können wir vielleicht auch
etwas Spannenderes uns überlegen. Ja, aber
bisher ist es einfach so gelöst. Wir haben jetzt
ja auch nicht so lebenswichtige Apps, genau.
Herald: Okay, hat noch jemand eine Frage? Ich
sehe keine mehr. Sonst schreit noch mal jemand.
Tobias: Gut, also wenn noch irgendwie
Fragen später sind: Schreibt auf "Open-
Knowledge-Slack, Code for Münster" oder
@webwurst oder über Twitter oder sonstwie.
Würde ich mich gerne unterhalten mit Leuten.
Herald: Dann nochmal Applaus für Tobias, bitte.
Applaus
Tobias: Vielen Dank.
Abspannmusik
Untertitel erstellt von c3subtitles.de
im Jahr 2019. Mach mit und hilf uns!