Die Entwicklung von Kubernetes als Open-Source-Ökosystem für Container-Anwendungen hat 2014 bei Google begonnen. Aufgrund der Erfolgsaussichten für ein solches System wurde es 2015 von Google als Basistechnologie an die Cloud Native Computing Foundation gespendet, einer Organisation unter dem Dach der Linux Foundation, die in demselben Jahr gegründet wurde, um natives Cloud-Computing zu standardisieren. Gründungsmitglieder sind unter anderem die Branchengrößen Google, Red Hat, Twitter, IBM, Docker und VMware.
Kubernetes ist ein modulares Master-Slave-System, das grundsätzlich über das Netzwerk beziehungsweise Netzwerk-Sockets kommuniziert. Der Kubernetes Master orchestriert dabei den gesamten Cluster, konfiguriert und verwaltet die einzelnen Nodes, übernimmt die Zuteilung von Prozessen auf diese Nodes und bietet eine Schnittstelle zur Administration. Auf den einzelnen Nodes läuft ein Prozess, der sogenannte Kubelet, der vom Master kontrolliert wird und die Container auf dem Node startet, stoppt und überwacht. Der zur Lastverteilung gedachte Kube-Proxy läuft ebenfalls auf jedem Node und ist für die Weiterleitung von Verbindungen zum konfigurierten Dienst verantwortlich. Die Container werden in sogenannten Pods organisiert, ein Pod enthält also einen oder mehrere Container, die auf gemeinsame Ressourcen wie Speicher oder Netzwerk zugreifen können. Pods sind damit vergleichbar mit einem physischen Rechner, auf dem mehrere Prozesse ausgeführt werden. Das bedeutet etwa, dass alle Container innerhalb eines Pods die IP-Adresse teilen und über localhost erreichbar sind.
Insbesondere die Netzwerk-Sicherheit sollte bei Kubernetes also, auch wenn Sie es nur mal testen möchten, von Beginn an berücksichtigt werden. Sowohl der Master als auch die einzelnen Nodes benötigen einige TCP-Ports für die Kommunikation untereinander. Auf dem Master läuft der API Server, der die gesamte Cluster-Administration ermöglicht. Jeder Node bietet ein API für den Master zur vollen Kontrolle des Nodes sowie insgesamt drei Status-Dienste: jeweils einen für den Node selbst und die Container und einen weiteren für den Kube-Proxy.
Natürlich ist ein Kubernetes-Cluster selbst nur so sicher, wie das darunter liegende System. Daher ist es wichtig, dass Sie sich mit der Distribution, die Sie einsetzen, gut auskennen und diese auch entsprechend absichern. Gängige Maßnahmen sind regelmäßige, möglichst automatische Updates, SELinux, Festplattenverschlüsselung und regelmäßige Überprüfung mit einem Schwachstellenscanner. Für die meisten Distributionen gibt es entsprechende Dokumente, das von Debian finden Sie etwa unter [1]. Ein Zugang zum Kubernetes-Master über das Internet lässt sich immer über SSH absichern, möglichst über einen demilitarisierten Jump-Host.
Bestenfalls konfigurieren Sie Ihren Kubernetes-Cluster in einem internen IP-Adressbereich. Das muss natürlich in der Netzwerkumgebung möglich sein. Innerhalb eines Unternehmensnetzwerks lässt sich das zumeist einfach realisieren, bei AWS können Sie dafür beispielsweise die Virtual Private Cloud (VPC) nutzen. Ein Problem entsteht bei der Nutzung von Docker hinter einem Proxyserver. Diesen benötigen Sie aber natürlich, wenn Sie einen internen IP-Adressbereich für Ihren Kubernetes-Cluster verwenden. Um für einen Dienst Ihres Systems entsprechende Umgebungsvariablen wie "http_proxy" zu konfigurieren, müssen Sie diese in der Konfiguration des Dienstes hinterlegen. Unter Ubuntu geht dies beispielsweise über Dateien im Ordner "/etc/systemd/system/docker.service.d", den Sie anlegen müssen, falls dieser noch nicht existiert. Innerhalb des Ordners legen Sie nun eine Datei mit dem Namen "http-proxy.conf" an und tragen folgenden Inhalt ein:
[Service]
Environment=HTTP_PROXY=http://[proxy_ip]:[port]
Environment=HTTPS_PROXY=http://[proxy_ip]:[port]/
Environment=FTP_PROXY=http://[proxy_ip]:[port]/
Environment=NO_PROXY=localhost,127.0.0.0/8,[master_ip]
Ersetzen Sie die Werte in Klammern entsprechend. Anschließend müssen Sie den Daemon neu starten. Vorher informieren Sie noch systemd darüber, dass Sie an der Dienstekonfiguration etwas geändert haben:
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
Nun baut Docker Verbindungen über den Proxy auf und kann auch problemlos Container aus dem Internet herunterladen und ausführen.
Das Werkzeug kube-bench [2] läuft selbst in einem Container und kann direkt in Ihrem Kubernetes-Cluster verwendet werden. Es eignet sich dazu, die Konfiguration Ihres Cluster zu überprüfen, und macht Sie anschließend auf mögliche (Sicherheits-)Probleme aufmerksam. Nach der Netzwerk-Absicherung sollte kube-bench als zweiter Schritt vor der Inbetriebnahme Ihres Clusters stehen. So finden Sie die Fehler vor einem möglichen Angreifer. Vor allem dann, wenn Sie aus unterschiedlichen Gründen keine internen IP-Adressen verwenden können, lässt sich Ihr System sonst fast unmittelbar nach der Installation bereits über Suchmaschinen wie Shodan [3] aufspüren. Das Bild zeigt Ihnen, wie leicht es ist, solche Installationen aufzuspüren, und gibt einen guten Überblick, bei welchen Providern offenbar häufig Kubernetes installiert wird.