Plattform für den Aufbau eines Container-Ökosystems Kubernetes Cluster mit einem Klick einrichten

Von Saied Bitar & Lasse Juretzko

Um einen Kubernetes Cluster zu erstellen, sind einige Schritte notwendig. Allerdings lässt sich die Erstellung des Clusters so automatisieren, dass sich dieser mit nur einem Klick zur Verfügung stellen lässt.

Firmen zum Thema

Mit einem einzelnen Ansible-Skript lässt sich ein kompletter Kubernetes-Cluster provisionieren.
Mit einem einzelnen Ansible-Skript lässt sich ein kompletter Kubernetes-Cluster provisionieren.
(Bild: ant0ine / Unsplash)

Kubernetes ist eine portable, erweiterbare Open-Source-Plattform zur Verwaltung von containerisierten Arbeitslasten und Services, die sowohl die deklarative Konfiguration als auch die Automatisierung des Deployments erleichtert. Zusätzlich verwaltet Kubernetes Netzwerk, Speicher und die Infrastruktur, um Software betreiben zu können.

Aktuell wird Kubernetes beginnend von der Softwareentwicklung, Teststages bis hin zu Produktivsystemen verwendet. Das macht Kubernetes insbesondere im Enterprise-Bereich zu einer unverzichtbaren Lösung. Kubernetes kann für das Deployment von Anwendungen, Microservices, Infrastruktur für Continuous Integration and Delivery (CI/CD) sowie für das Staging verwendet werden.

Deployment von Anwendungen

Anwendungen können auf dem Cluster automatisiert deployt werden. Durch Verwendung des Infrastructure-as-Code Ansatzes (IaC) kann das Deployment reproduzierbar erfolgen. Das bedeutet, dass das Bereitstellen einer Anwendung in einer zentralen Stelle beschrieben werden kann. Auf diese Weise wird das Deployment einer Anwendung enorm erleichtert und Verwaltungsaufwand erheblich gemindert.

Microservices

In einem Kubernetes Cluster können Anwendungen in Form von Microservices deployt werden. Das hat den Vorteil, dass für jeden Microservice Hochverfügbarkeit und Skalierbarkeit garantiert ist, da jeder Microservice als einzelner Service verwaltet werden kann. Kubernetes stellt dazu die Infrastruktur bereit, da Services leicht miteinander kommunizieren können.

Infrastruktur für CI/CD

Durch seine Flexibilität kann der Kubernetes Cluster als Möglichkeit verwendet werden, CI/CD Jobs zu betreiben. So kann beispielsweise mit dem Kubernetes Plug-in für Jenkins-Jobs auf einem Kubernetes Cluster laufen.

Staging

Kubernetes Namespaces ermöglichen es, Stages zu erstellen, die isoliert voneinander betrachtet werden können. Dadurch kann ein Cluster für unterschiedliche Test-, Dev- und Prod-Stages verwendet werden.

Automatisierung der Cluster-Provisionierung

Soll ein Cluster neu provisioniert oder ein weiterer Cluster angelegt werden, erspart die Automatisierung die Arbeit, den Cluster manuell zu provisionieren und bereitzustellen. Im Folgenden schildern wir die Vorgehensweise unter Verwendung verschiedener Tools im Detail.

Wir beginnen dabei mit einer Konfigurationsdatei, der cluster-config.yml, die den Cluster beschreibt. Ausgehend von dieser Datei wird ein Ansible Role gestartet, die von einem Jenkins Job getriggert wurde. Diese Ansible Role erstellt dann aus den in der Konfiguration angegeben Virtuellen Maschinen (VMs) einen Kubernetes Cluster.

Verwendete Tools

Jenkins

Jenkins ist ein CI/CD Tool zum Automatisieren von Aufgaben. Eine Aufgabe wird als Jenkins-Job bezeichnet und kann durch eine entsprechende Jenkinsfile konfiguriert werden. Ein Jenkinsfile besteht aus Stages, die mit Parametern flexibel konfigurierbar sind.

Ansible

Ansible dient zur Provisionierung von einer großen Anzahl von Systemen, um diese auf einen reproduzierbaren Stand zu bringen. Ansible verwendet Playbooks als wiederverwendbare Konfiguration und Strukturierung der Aufgaben, die auf den Systemen ausgeführt werden sollen. Ein Playbook besteht aus einer Liste von Roles, die zum Ablauf der Aufgaben dienen, sowie Inventories, die eine Liste der Zielsysteme beinhalten. Mehr zu Playbooks in den Ansible Docs.

Jede Role hat eine feste Ordnerstruktur. Hier werden unter anderem tasks, templates und files verwendet. Ein Task stellt die kleinste Einheit von Ansible dar und kann beispielsweise aus Dateien kopieren, Packages installieren oder Ordner erstellen bestehen. Mit Templates bzw. Files kann man Dateien mit bzw. ohne Parameter beschreiben, die auf das Zielsystem kopiert werden können.

Vorbereitung

Damit ein Cluster erstellt werden kann, müssen vorher einige Vorkehrungen bei den VMs und in Jenkins getroffen werden.

Vorbereitung der VMs

Für einen Kubernetes Cluster werden mindestens zwei VMs benötigt. Es muss sichergestellt werden, dass alle Master und Nodes miteinander kommunizieren können. Zusätzlich sollten alle VMs vom Jenkins mit SSH erreichbar sein und einen entsprechenden User mit SSH Key oder Passwort besitzen, der von Ansible zum Provisionieren verwendet wird. Dieser User sollte auch als Key in Jenkins eingetragen werden.

Vorbereitung von Jenkins

Zum Einrichten des Clusters wird hier Jenkins verwendet. Auf dem Jenkins Server sollte das Ansible Plug-in installiert sein. In diesem Beispiel wird auch das AnsiColor Plug-in verwendet, das ist jedoch optional.

Konfiguration

Der Cluster wird innerhalb einer YML-Datei konfiguriert. Diese Konfiguration besteht aus einer Liste Hostnames/IPs von Master und Worker Nodes. Folgend ein Beispiel für eine Konfigurationsdatei:

# Master Node
masters:
  master: "kubernetes-master.adesso-insure.de"
# Liste aller Worker Nodes
nodes:
  node1: "kubernetes-node1.adesso-insure.de"
  node2: "kubernetes-node2.adesso-insure.de"

Funktionsweise

Die Pipeline besteht aus einem Jenkins-Job, der ein Ansible Playbook triggert. Das Playbook startet verschiedene Ansible Roles, eine zum Generieren des Inventories und eine zum Provisionieren des Clusters.

Jenkins Job

Um das Provisionieren des Clusters zu starten, wird ein Jenkins-Job verwendet. Es gibt zwei Stages, die jeweils die Role zum Generieren des Inventories beziehungsweise zum Erstellen des Clusters verwendet werden. Es wird dazu das Playbook mit den jeweiligen Tags kubernetes-prepare bzw. kubernetes-init getriggert. Bei der zweiten Stage wird zusätzlich eine Credentials ID benötigt, die den SSH User enthält, der in Jenkins eingetragen wurde (siehe oben, Abschnitt Vorbereitung).

Ansible Playbook

Das Playbook besteht aus drei Plays, ein Play zum Generieren des Inventories, eines zum Provisionieren der Master Nodes und eines zum Provisionieren der Worker Nodes. Es werden die entsprechenden Roles kubernetes/prepare und kubernetes/init (siehe untere Abschnitte) ausgeführt. Das Playbook findet sich im Anhang des Artikels unter playbook.yml.

Ansible Role zum Generieren des Inventories

Zum Generieren des Inventories wird die Role kubernetes/init verwendet. Diese bedient sich aus der Konfiguration, wie oben beschrieben. Der einzige Task ist das Erstellen des Inventories.

Im Template ist der Aufbau des generierten Inventories dargestellt. Zunächst werden Master und Worker Nodes konfiguriert, mit Namen und entsprechendem Host. Dann werden Gruppen [masters] und [nodes] erstellt, damit das Playbook diese verwenden kann. Zum Schluss geht es noch daran, die SSH-Konfigurationen zu erstellen. Die Variablen masters und nodes werden hier aus der Konfiguration gelesen.

tasks/main.yml:
- name: "Inventory aus Konfiguration erstellen"
  template:
    src: "inventory.ini"
    dest: "{{ playbook_dir }}/inventories/kubernetes-generated.ini"

Das Template templates/inventory.ini und ein Beispiel für ein generiertes Inventory finden sich im Anhang unter inventory.ini bzw. exampleinv.ini.

Ansible Role zum Erstellen des Clusters

Diese Role wird zum eigentlichen Erstellen des Clusters verwendet und beinhaltet eine Ansammlung von Tasks in der tasks/main.yml, sowie Skripte down.sh, install.sh und up.sh. Alle Dateien sind im Anhang zu finden.

Als erstes werden notwenige Packages installiert und das System konfiguriert. Unter anderem wird Docker installiert sowie alle für Kubernetes notwenige Packages wie kubectl, kubeadm und kubelet. Anschließend wird getestet, ob schon ein Cluster existiert. Wenn der Cluster schon existiert, werden die folgenden Schritte übersprungen.

Zunächst wird Kubernetes gestoppt, um sicherzustellen, dass noch kein Node einem Cluster zugeordnet ist. Anschließend wird unterschieden, ob das Skript auf dem Master oder einer Node ausgeführt wird. Auf dem Master starten wir dann den Cluster mit:

kubeadm init

An dieser Stelle geschieht die eigentliche Provisionierung des Clusters. Auf den Nodes wird dann …

kubeadm join

… ausgeführt, um dem Cluster beizutreten. Es ist empfehlenswert, die einzelnen Befehle in den Skripten optional als eigene Ansible-Module zu konfigurieren. Nach einem Klick ist der Cluster nun provisioniert und einsatzbereit.

Fazit

Saied Bitar
Saied Bitar
(Bild: Christoph Kottmann Fotografie)

Mit diesem Ansible Skript zum Provisionieren eines Kubernetes Cluster wurde nicht nur Grundstein geschaffen, um die Installation von Kubernetes zu automatisieren, sondern auch das Hinzufügen weiterer Nodes in den Cluster ohne Aufwand ermöglicht. Durch die Modularität der Ansible Roles besteht außerdem die Möglichkeit, weitere Konfiguration des Clusters durchzuführen und Anwendungen zu deployen.

* Saied Bitar ist Competence-Center-Leiter bei der adesso insurance solutions GmbH. Er verantwortet dort DevOps Themen und Themen rund um Clouds und Build- und Deployment-Infrastruktur.

Lasse Juretzko
Lasse Juretzko
(Bild: adesso insurance)

* Lasse Juretzko arbeitet seit September 2020 bei adesso insurance solutions im Bereich DevOps, Infrastruktur und CI/CD. Darüber hinaus studiert er seit 2021 Mathematik in der RWTH Aachen.

Artikelfiles und Artikellinks

Datei: playbook.yml

Datei: Jenkinsfile

Datei: exampleinv.ini

Datei: inventory.ini

Datei: down.sh

Datei: install.sh

Datei: main.yml

Datei: up.sh

(ID:47756176)