Das Monitoring der IT-Umgebung steht im März auf der Agenda des IT-Administrator. So lesen Sie in der Ausgabe, wie sich Open-Source-Tools wie Logstash, ... (mehr)

Container-Orchestrierung mit Kubernetes

Ein Management- und Orchestrierungs-Tool wie Kubernetes bietet genau solche Möglichkeiten. Das Tool besteht aus einer ganzen Reihe von Services, von denen einige auf einem Steuerungssystem, dem Master-Host, andere auf den einzelnen Docker-Hosts, den sogenannten Minions, laufen. Der app-service auf dem Master stellt eine REST-API zur Kommunikation zur Verfügung, über die der Service Anweisungen von Clients erhält. Eine Anweisung könnte beispielsweise sein, einen bestimmten Container auf einem beliebigen Minion-Host zu erzeugen, in der Kubernetes-Welt Pod genannt. Dieser kann lediglich einen einzelnen oder auch mehrere Container enthalten.

Üblicherweise enthält ein Pod Container für Dienste, die man auf herkömmlichen Systemen gerne zusammen installieren würde. Eine Datei im JSON-Format enthält alle hierfür notwendigen Informationen. Beispielsweise, welches Image für die Container des Pods zum Einsatz kommen soll und auf welchem Port die Dienste innerhalb der Container lauschen sollen. Auf den Minion-Hosts läuft ein Agent-Service mit dem Namen "kubelet" und empfängt Anweisungen des Masters.

Als Kommunikationsbus kommt der etcd-Service zum Einsatz. Hierbei handelt es sich um eine verteilte Key/Value-Datenbank [6], die mittels einfacher HTTP- GET- und PUT-Anweisungen bedient wird. Diese hält Konfigurations- und Status-Informationen des Kubernetes-Clusters vor und liefert diese bei Bedarf im JSON-Format zurück. Der kubelet-Service auf einem Minion-Host fragt diese Datenbank ständig nach Änderungen ab und führt sie gegebenenfalls aus. Beispielsweise kann die Datenbank eine Liste sämtlicher Minion-Hosts des Clusters enthalten. Diese Information wird dann vom app-service dazu verwendet, um zu entscheiden, auf welchen Hosts ein neuer Container erzeugt werden kann.

Installation des Atomic-Hosts

Um in die Welt von Kubernetes einzutauchen, laden Sie sich eines der unter [3,4,5] bereitgestellten Images herunter und installieren es in Ihrer Virtualisierungsumgebung. Wir verwenden für diesen Artikel eine lokale KVM-basierte Installation auf Fedora 21 mit einem CentOS 7 Docker-Image von [5]. Das Image lässt sich hier einfach mittels des Tools virt-manager oder virt-install installieren. Unter [7] finden Sie Setup-Anweisungen für verschiedene Virtualisierungsumgebungen.

Für den ersten Start sollten Sie der so erzeugten virtuellen Maschine eine CD-ROM in Form einer ISO-Datei zur Verfügung stellen. Diese enthält grundlegende Informationen über das virtuelle Atomic-System, beispielsweise den Maschinennamen und das Passwort für den Default-Benutzer. Auch einen SSH-Schlüssel zum Login auf das System oder die gewünschte Netzwerkkonfiguration können Sie an dieser Stelle übergeben. Legen Sie hierfür die beiden Dateien meta-data und user-data an und erzeugen Sie hieraus im Anschluss die ISO-Datei (Listing 1). Diese stellen Sie dem Atomic-Host dann als virtuelles CD-ROM-Laufwerk zur Verfügung. Beim ersten Start des Systems startet der Dienst cloud-init, liest die so zur Verfügung gestellten Informationen ein und konfiguriert anhand dieser das System. Unter [8] finden Sie weitere Informationen zum Thema cloud-init.

Listing 3: Definition eines Pods



{
    "apiVersion": "v1beta1",
    "kind": "Pod",
    "id": "apache-dev",
    "namespace": "default",
    "labels": {
       "name": "apache",
       "stage": "dev"
    },
    "desiredState": {
       "manifest": {
          "version": "v1beta1",
          "id": "apache-dev",
          "volumes": null,
          "containers": [
             {
                "name": "master",
                "image": "fedora/apache",
                "ports": [
                   {
                      "containerPort": 80,
                      "hostPort": 80,
                      "protocol": "TCP"
                  }
                ],
            }
         ],
          "restartPolicy": {
              "always": {}
           }
       },
    },
}

Haben Installation und Konfiguration soweit funktioniert, können Sie sich im Anschluss daran an dem virtuellen System anmelden, um ein Update durchzuführen. Wie zuvor beschrieben, wird in diesem Falle eine neue Instanz des Systems heruntergeladen und beim nächsten Systemstart aktiviert:

ssh centos@atomic.example.com
rpm-ostree upgrade
systemctl reboot

Da es sich bei diesem System um den Master-Host handelt, können Sie direkt im Anschluss an dessen Konfiguration einen zweiten Host mit dem gleichen Image installieren. Dieser wird im Folgenden als Minion-Host dienen, auf denen die Container Pods laufen. Natürlich steht es Ihnen an dieser Stelle frei, beliebig viele Minions zu installieren. Um die grundlegende Funktion von Kubernetes zu verstehen, reicht allerdings ein einzelner Minion-Host aus. Erzeugen Sie hierfür eine zweite virtuelle Maschine und, wie in Listing 1 beschrieben, eine zusätzliche ISO-Datei, die Sie dem Minion-Host bei der Installation zur Verfügung stellen. Im Anschluss an die Installation sollten Sie auch dieses System aktualisieren und neu starten.

Sind Master und Minion auf dem aktuellen Stand, sind die beiden Rechner in der Datei »/etc/hosts« einzutragen und die Kubernetes-Konfigurationsdatei »/etc/kubernetes/config« anzupassen. Dort tragen Sie auf beiden Systemen über die Variable "KUBE_ETCD_SERVER" den Master-Server ein. In der aktuellen Version von Kubernetes wird lediglich ein einzelner Master unterstützt, was sich aber in zukünftigen Releases ändern soll. Auf dem Master sind dann zusätzlich die beiden Dateien »/etc/kubernetes/apiserver« und »/etc/kubernetes/controller-manager« anzupassen. Hier definieren Sie den Hostnamen und den Port des API-Services sowie den Hostnamen des Minion-Servers. Im Anschluss starten Sie auf dem Master alle notwendigen Dienste und überzeugen sich anschließend davon, dass alles fehlerfrei geklappt hat:

systemctl start etcd kube-apiserver kube-controller-manager kube-scheduler
systemctl enable etcd kube-apiserver kube-controller-manager kube-scheduler
systemctl status etcd kube-apiserver kube-controller-manager kube-scheduler

Listing 4: Docker zeigt aktive Container



# docker ps
CONTAINER ID    IMAGE                        COMMAND           CREATED         STATUS                  PORTS    NAMES
a9548bd9ecb1       fedora/apache:latest    "/run-apache.sh"    9 minutes ago   Up 9 minutes ago    k8s_master.39902450_apache.default.etcd_37e66e65-8454-11e4-b2be-5254008d3d8e_e8c7bae6

Auf dem Minion-Host ist neben der Datei »/etc/kubernetes/config« auch noch die Konfigurationsdatei des Minion-Agents anzupassen. Tragen Sie hierfür in der Datei »/etc/kubernetes/kubelet« den Hostnamen, den Port und die IP-Adresse, auf der der Service lauschen soll, ein. Anschließend starten Sie auch hier die notwendigen Dienste:

systemctl start kube-proxy kubelet docker
systemctl enable kube-proxy kubelet docker
systemctl status kube-proxy kubelet docker

Zu diesem Zeitpunkt sollten Sie den Minion-Host auf dem Master sehen. Zur Kommunikation mit dem API-Server kommt das Tool kubectl zum Einsatz:

kubectl get minion
NAME
atomic-host-001

Im nächsten Schritt können Sie Ihren ersten Pod erzeugen. Zur Erinnerung, hierbei handelt es sich um einen oder mehrere Container, die auf einem der zur Verfügung stehenden Minion-Hosts bereitgestellt werden. Die Definition des Pods erfolgt über eine Datei im JSON-Format, in der Sie sämtliche Informationen zu dem Pod festlegen. Dazu gehören beispielsweise das zu verwendende Docker-Image, der Port der Services und ein optionales Port-Mapping zwischen Container und Host. Sie können hier auch Dateisysteme des Hosts bestimmen, die Sie an den Container binden möchten. Dies ist besonders wichtig, da sämtliche Daten, die Sie innerhalb des Containers ändern, nach dem Beenden des Containers verloren sind.

Jeder Pod lässt sich mit einem oder mehreren Labels versehen. Beispielsweise könnten Sie für alle Apache-Server in Produktion die Label "name=apache" und "stage=prod" in die JSON-Datei aufnehmen. Über eine entsprechende Abfrage mittels kubectl können Sie dann später sehr leicht Ihre produktiven Apache-Server identifizieren und feststellen, auf welchem Minion diese eigentlich gerade laufen. Doch zuerst erzeugen Sie Ihren ersten Pod mit der Datei aus Listing 3. Rufen Sie hierfür das Tool kubectl wie folgt auf:

kubectl create -f /tmp/apache-pod.json

Im Hintergrund wird nun auf dem Minion der Docker Prozess aktiv und fängt an, das "fedora/apache"-Image herunterzuladen, wenn es noch nicht vorhanden ist. Das kann durchaus eine gewisse Zeit in Anspruch nehmen. Rufen Sie danach erneut kubectl auf, so sollten Sie sehen, dass der Container nun aktiv ist (Listing 2).

Dass der Apache-Service innerhalb des Containers wie gewohnt funktioniert, überprüfen Sie mit einem einfachen Aufruf von curl:

curl http://atomic-host-001
Apache

Wenn mehrere Apache-Container in Ihrer Umgebung laufen, können Sie die Ausgabe von "kubectl get pod" anhand der zuvor definierten Labels einschränken. Mittels "kubectl get pods -l name=apache -l stage=prod" würde Kubernetes lediglich die Container anzeigen, die über die beiden Labels name=apache und stage=prod verfügen.

Wie Sie in Listing 3 sehen, enthält die Definition des Pods auch den Hinweis, dass im Fehlerfall ein Container sofort wieder neu zu starten ist (restartPolicy: always). Ob das funktioniert, lässt sich sehr leicht überprüfen. Melden Sie sich hierfür mittels SSH auf dem Minion-Host an und weisen Sie docker an, die gerade aktiven Container anzuzeigen (Listing 4).

Beenden Sie den Container manuell, indem Sie ihn mittels »docker stop a9548bd9ecb1« anhalten, werden Sie nach kurzer Zeit feststellen, dass Docker ihn automatisch wieder neu startet. Achten Sie hier auf den Wert in der Spalte "CREATED" in der Ausgabe von "docker ps", bevor und nachdem Sie den Container manuell gestoppt haben.

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023