Kubernetes Basics
Last updated
Last updated
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Der ursprüngliche Autor dieser Seite ist Jorge (lies seinen ursprünglichen Beitrag hier)
Ermöglicht das Ausführen von Containern in einer Container-Engine.
Der Scheduler ermöglicht eine effiziente Planung von Containern.
Hält Container am Leben.
Ermöglicht die Kommunikation zwischen Containern.
Ermöglicht Bereitstellungstechniken.
Verarbeitet große Datenmengen.
Node: Betriebssystem mit Pod oder Pods.
Pod: Wrapper um einen Container oder mehrere Container. Ein Pod sollte nur eine Anwendung enthalten (normalerweise läuft ein Pod nur 1 Container). Der Pod ist die Art und Weise, wie Kubernetes die Containertechnologie abstrahiert.
Service: Jeder Pod hat 1 interne IP-Adresse aus dem internen Bereich des Nodes. Er kann jedoch auch über einen Service exponiert werden. Der Service hat ebenfalls eine IP-Adresse und sein Ziel ist es, die Kommunikation zwischen Pods aufrechtzuerhalten, sodass, wenn einer ausfällt, der neue Ersatz (mit einer anderen internen IP) über die gleiche IP des Services zugänglich ist. Er kann als intern oder extern konfiguriert werden. Der Service fungiert auch als Lastenausgleich, wenn 2 Pods mit demselben Service verbunden sind.
Wenn ein Service erstellt wird, kannst du die Endpunkte jedes Services mit kubectl get endpoints
finden.
Kubelet: Primärer Node-Agent. Die Komponente, die die Kommunikation zwischen Node und kubectl herstellt und nur Pods ausführen kann (über den API-Server). Der Kubelet verwaltet keine Container, die nicht von Kubernetes erstellt wurden.
Kube-proxy: Ist der Service, der für die Kommunikation (Services) zwischen dem Apiserver und dem Node verantwortlich ist. Die Basis ist ein IPtables für Nodes. Erfahrene Benutzer könnten andere Kube-Proxys von anderen Anbietern installieren.
Sidecar-Container: Sidecar-Container sind die Container, die zusammen mit dem Hauptcontainer im Pod ausgeführt werden sollten. Dieses Sidecar-Muster erweitert und verbessert die Funktionalität der aktuellen Container, ohne sie zu ändern. Heutzutage wissen wir, dass wir Containertechnologie verwenden, um alle Abhängigkeiten für die Anwendung zu verpacken, damit sie überall ausgeführt werden kann. Ein Container macht nur eine Sache und macht diese Sache sehr gut.
Master-Prozess:
Api Server: Ist der Weg, wie die Benutzer und die Pods mit dem Master-Prozess kommunizieren. Nur authentifizierte Anfragen sollten erlaubt sein.
Scheduler: Die Planung bezieht sich darauf, sicherzustellen, dass Pods den Nodes zugeordnet werden, damit Kubelet sie ausführen kann. Er hat genug Intelligenz, um zu entscheiden, welcher Node mehr verfügbare Ressourcen hat, um den neuen Pod zuzuweisen. Beachte, dass der Scheduler keine neuen Pods startet, er kommuniziert nur mit dem Kubelet-Prozess, der im Node läuft, der den neuen Pod starten wird.
Kube Controller Manager: Er überprüft Ressourcen wie Replica-Sets oder Deployments, um zu prüfen, ob beispielsweise die richtige Anzahl von Pods oder Nodes läuft. Falls ein Pod fehlt, kommuniziert er mit dem Scheduler, um einen neuen zu starten. Er kontrolliert Replikation, Tokens und Kontodienste für die API.
etcd: Datenspeicher, persistent, konsistent und verteilt. Ist die Datenbank von Kubernetes und der Schlüssel-Wert-Speicher, in dem der vollständige Zustand der Cluster gespeichert wird (jede Änderung wird hier protokolliert). Komponenten wie der Scheduler oder der Controller Manager sind auf diese Daten angewiesen, um zu wissen, welche Änderungen aufgetreten sind (verfügbare Ressourcen der Nodes, Anzahl der laufenden Pods...).
Cloud Controller Manager: Ist der spezifische Controller für Flusskontrollen und Anwendungen, d.h.: wenn du Cluster in AWS oder OpenStack hast.
Beachte, dass es mehrere Nodes (die mehrere Pods ausführen) geben kann, und es kann auch mehrere Master-Prozesse geben, deren Zugriff auf den Api-Server lastenausgeglichen und deren etcd synchronisiert ist.
Volumes:
Wenn ein Pod Daten erstellt, die nicht verloren gehen sollten, wenn der Pod verschwindet, sollten sie in einem physischen Volume gespeichert werden. Kubernetes erlaubt es, ein Volume an einen Pod anzuhängen, um die Daten zu persistieren. Das Volume kann auf der lokalen Maschine oder in einem Remote-Speicher sein. Wenn du Pods auf verschiedenen physischen Nodes ausführst, solltest du einen Remote-Speicher verwenden, damit alle Pods darauf zugreifen können.
Weitere Konfigurationen:
ConfigMap: Du kannst URLs konfigurieren, um auf Services zuzugreifen. Der Pod wird Daten von hier abrufen, um zu wissen, wie er mit den anderen Services (Pods) kommunizieren kann. Beachte, dass dies nicht der empfohlene Ort ist, um Anmeldeinformationen zu speichern!
Secret: Dies ist der Ort, um geheime Daten wie Passwörter, API-Schlüssel... in B64 kodiert zu speichern. Der Pod kann auf diese Daten zugreifen, um die erforderlichen Anmeldeinformationen zu verwenden.
Deployments: Hier werden die Komponenten angegeben, die von Kubernetes ausgeführt werden sollen. Ein Benutzer arbeitet normalerweise nicht direkt mit Pods, Pods sind in ReplicaSets abstrahiert (Anzahl der gleichen Pods, die repliziert werden), die über Deployments ausgeführt werden. Beachte, dass Deployments für zustandslose Anwendungen gedacht sind. Die minimale Konfiguration für ein Deployment ist der Name und das Image, das ausgeführt werden soll.
StatefulSet: Diese Komponente ist speziell für Anwendungen wie Datenbanken gedacht, die auf denselben Speicher zugreifen müssen.
Ingress: Dies ist die Konfiguration, die verwendet wird, um die Anwendung öffentlich mit einer URL exponieren. Beachte, dass dies auch mit externen Services erfolgen kann, aber dies ist der richtige Weg, um die Anwendung zu exponieren.
Wenn du ein Ingress implementierst, musst du Ingress-Controller erstellen. Der Ingress-Controller ist ein Pod, der der Endpunkt sein wird, der die Anfragen empfängt und überprüft und sie an die Services lastenausgleicht. Der Ingress-Controller wird die Anfrage basierend auf den konfigurierten Ingress-Regeln senden. Beachte, dass die Ingress-Regeln auf verschiedene Pfade oder sogar Subdomains zu verschiedenen internen Kubernetes-Services verweisen können.
Eine bessere Sicherheitspraktik wäre es, einen Cloud-Lastenausgleich oder einen Proxy-Server als Einstiegspunkt zu verwenden, um keinen Teil des Kubernetes-Clusters exponiert zu haben.
Wenn eine Anfrage empfangen wird, die keiner Ingress-Regel entspricht, wird der Ingress-Controller sie an den "Default Backend" weiterleiten. Du kannst den Ingress-Controller describe
verwenden, um die Adresse dieses Parameters zu erhalten.
minikube addons enable ingress
CA ist die vertrauenswürdige Wurzel für alle Zertifikate innerhalb des Clusters.
Ermöglicht es Komponenten, sich gegenseitig zu validieren.
Alle Cluster-Zertifikate werden von der CA signiert.
etcd hat sein eigenes Zertifikat.
Typen:
apiserver-Zertifikat.
kubelet-Zertifikat.
scheduler-Zertifikat.
Minikube kann verwendet werden, um einige schnelle Tests auf Kubernetes durchzuführen, ohne eine vollständige Kubernetes-Umgebung bereitstellen zu müssen. Es wird die Master- und Node-Prozesse auf einer Maschine ausführen. Minikube wird VirtualBox verwenden, um den Node auszuführen. Siehe hier, wie man es installiert.
Kubectl
ist das Befehlszeilenwerkzeug für Kubernetes-Cluster. Es kommuniziert mit dem API-Server des Master-Prozesses, um Aktionen in Kubernetes auszuführen oder um Daten abzufragen.
Das Dashboard ermöglicht es Ihnen, einfacher zu sehen, was Minikube ausführt. Sie finden die URL, um darauf zuzugreifen, in:
Jede Konfigurationsdatei hat 3 Teile: Metadaten, Spezifikation (was gestartet werden muss), Status (gewünschter Zustand). Innerhalb der Spezifikation der Bereitstellungs-Konfigurationsdatei finden Sie die Vorlage, die mit einer neuen Konfigurationsstruktur definiert ist, die das auszuführende Image definiert:
Beispiel für Bereitstellung + Dienst, die in derselben Konfigurationsdatei deklariert sind (von hier)
Da ein Dienst normalerweise mit einer Bereitstellung verbunden ist, ist es möglich, beide in derselben Konfigurationsdatei zu deklarieren (der in dieser Konfiguration deklarierte Dienst ist nur intern zugänglich):
Beispiel für die Konfiguration eines externen Dienstes
Dieser Dienst wird extern zugänglich sein (überprüfen Sie die Attribute nodePort
und type: LoadBlancer
):
Dies ist nützlich für Tests, aber für die Produktion sollten Sie nur interne Dienste und ein Ingress haben, um die Anwendung bereitzustellen.
Beispiel einer Ingress-Konfigurationsdatei
Dies wird die Anwendung unter http://dashboard.com
bereitstellen.
Beispiel einer Secrets-Konfigurationsdatei
Beachten Sie, wie die Passwörter in B64 codiert sind (was nicht sicher ist!)
Beispiel für ConfigMap
Eine ConfigMap ist die Konfiguration, die den Pods gegeben wird, damit sie wissen, wie sie andere Dienste finden und darauf zugreifen können. In diesem Fall wird jeder Pod wissen, dass der Name mongodb-service
die Adresse eines Pods ist, mit dem sie kommunizieren können (dieser Pod wird ein mongodb ausführen):
Dann kann diese Adresse innerhalb einer deployment config auf folgende Weise angegeben werden, sodass sie in die Umgebungsvariablen des Pods geladen wird:
Beispiel für die Volumen-Konfiguration
Sie finden verschiedene Beispiele für Speicher-Konfigurations-YAML-Dateien in https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes. Beachten Sie, dass Volumen nicht innerhalb von Namespaces sind
Kubernetes unterstützt mehrere virtuelle Cluster, die von demselben physischen Cluster unterstützt werden. Diese virtuellen Cluster werden Namespaces genannt. Sie sind für den Einsatz in Umgebungen mit vielen Benutzern, die über mehrere Teams oder Projekte verteilt sind, gedacht. Für Cluster mit wenigen bis mehreren Dutzend Benutzern sollten Sie keine Namespaces erstellen oder darüber nachdenken müssen. Sie sollten nur beginnen, Namespaces zu verwenden, um eine bessere Kontrolle und Organisation jedes Teils der in Kubernetes bereitgestellten Anwendung zu haben.
Namespaces bieten einen Geltungsbereich für Namen. Die Namen von Ressourcen müssen innerhalb eines Namespaces eindeutig sein, jedoch nicht über Namespaces hinweg. Namespaces können nicht ineinander geschachtelt werden, und jede Kubernetes Ressource kann nur in einem Namespace sein.
Es gibt standardmäßig 4 Namespaces, wenn Sie Minikube verwenden:
kube-system: Es ist nicht für die Benutzer gedacht und Sie sollten es nicht anfassen. Es ist für Master- und kubectl-Prozesse.
kube-public: Öffentlich zugängliche Daten. Enthält ein ConfigMap, das Clusterinformationen enthält.
kube-node-lease: Bestimmt die Verfügbarkeit eines Knotens.
default: Der Namespace, den der Benutzer verwenden wird, um Ressourcen zu erstellen.
Beachten Sie, dass die meisten Kubernetes-Ressourcen (z. B. Pods, Dienste, Replikationscontroller und andere) in einigen Namespaces sind. Andere Ressourcen wie Namespace-Ressourcen und niedrigstufige Ressourcen, wie Knoten und persistentVolumes, befinden sich jedoch nicht in einem Namespace. Um zu sehen, welche Kubernetes-Ressourcen sich in einem Namespace befinden und welche nicht:
Sie können den Namespace für alle nachfolgenden kubectl-Befehle in diesem Kontext speichern.
Helm ist der Paketmanager für Kubernetes. Er ermöglicht das Verpacken von YAML-Dateien und deren Verteilung in öffentlichen und privaten Repositories. Diese Pakete werden Helm Charts genannt.
Helm ist auch eine Template-Engine, die es ermöglicht, Konfigurationsdateien mit Variablen zu generieren:
Ein Secret ist ein Objekt, das sensible Daten wie ein Passwort, ein Token oder einen Schlüssel enthält. Solche Informationen könnten andernfalls in einer Pod-Spezifikation oder in einem Image abgelegt werden. Benutzer können Secrets erstellen und das System erstellt ebenfalls Secrets. Der Name eines Secret-Objekts muss ein gültiger DNS-Subdomänenname sein. Lesen Sie hier die offizielle Dokumentation.
Secrets können Dinge wie Folgendes sein:
API, SSH-Schlüssel.
OAuth-Token.
Anmeldeinformationen, Passwörter (im Klartext oder b64 + Verschlüsselung).
Informationen oder Kommentare.
Datenbankverbindungs-Code, Strings… .
Es gibt verschiedene Typen von Secrets in Kubernetes
Eingebauter Typ | Verwendung |
---|---|
Opaque | willkürliche benutzerdefinierte Daten (Standard) |
kubernetes.io/service-account-token | Token des Dienstkontos |
kubernetes.io/dockercfg | serialisierte ~/.dockercfg-Datei |
kubernetes.io/dockerconfigjson | serialisierte ~/.docker/config.json-Datei |
kubernetes.io/basic-auth | Anmeldeinformationen für die grundlegende Authentifizierung |
kubernetes.io/ssh-auth | Anmeldeinformationen für die SSH-Authentifizierung |
kubernetes.io/tls | Daten für einen TLS-Client oder -Server |
bootstrap.kubernetes.io/token | Bootstrap-Token-Daten |
Der Opaque-Typ ist der Standardtyp, das typische Schlüssel-Wert-Paar, das von Benutzern definiert wird.
Wie Secrets funktionieren:
Die folgende Konfigurationsdatei definiert ein Secret namens mysecret
mit 2 Schlüssel-Wert-Paaren username: YWRtaW4=
und password: MWYyZDFlMmU2N2Rm
. Sie definiert auch ein Pod namens secretpod
, das die in mysecret
definierten username
und password
in den Umgebungsvariablen SECRET_USERNAME
__ und __ SECRET_PASSWOR
verfügbar macht. Es wird auch das username
-Secret innerhalb von mysecret
im Pfad /etc/foo/my-group/my-username
mit 0640
Berechtigungen gemountet.
etcd ist ein konsistenter und hochverfügbarer Key-Value-Speicher, der als Kubernetes-Backend-Speicher für alle Cluster-Daten verwendet wird. Lassen Sie uns auf die in etcd gespeicherten Secrets zugreifen:
Sie werden sehen, dass Zertifikate, Schlüssel und URLs im Dateisystem (FS) gespeichert sind. Sobald Sie diese haben, können Sie sich mit etcd verbinden.
Sobald Sie die Kommunikation hergestellt haben, können Sie die Geheimnisse abrufen:
Verschlüsselung zum ETCD hinzufügen
Standardmäßig werden alle Geheimnisse im Klartext in etcd gespeichert, es sei denn, Sie wenden eine Verschlüsselungsschicht an. Das folgende Beispiel basiert auf https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
Danach müssen Sie das --encryption-provider-config
-Flag auf dem kube-apiserver
setzen, um auf den Speicherort der erstellten Konfigurationsdatei zu verweisen. Sie können /etc/kubernetes/manifest/kube-apiserver.yaml
bearbeiten und die folgenden Zeilen hinzufügen:
Scrollen Sie nach unten in den volumeMounts:
Scrollen Sie nach unten in den volumeMounts zu hostPath:
Überprüfen, ob Daten verschlüsselt sind
Daten werden verschlüsselt, wenn sie in etcd geschrieben werden. Nach dem Neustart Ihres kube-apiserver
sollte jedes neu erstellte oder aktualisierte Secret verschlüsselt gespeichert werden. Um dies zu überprüfen, können Sie das etcdctl
-Befehlszeilenprogramm verwenden, um den Inhalt Ihres Secrets abzurufen.
Erstellen Sie ein neues Secret mit dem Namen secret1
im default
-Namespace:
Lesen Sie dieses Secret mit dem etcdctl-Befehlszeilenprogramm aus etcd:
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
wobei [...]
die zusätzlichen Argumente für die Verbindung zum etcd-Server sein müssen. 3. Überprüfen Sie, ob das gespeicherte Secret mit k8s:enc:aescbc:v1:
vorangestellt ist, was darauf hinweist, dass der aescbc
-Provider die resultierenden Daten verschlüsselt hat. 4. Überprüfen Sie, ob das Secret korrekt entschlüsselt wird, wenn es über die API abgerufen wird:
sollte mykey: bXlkYXRh
entsprechen, mydata ist kodiert, überprüfen Sie das Dekodieren eines Secrets, um das Secret vollständig zu dekodieren.
Da Secrets beim Schreiben verschlüsselt werden, wird das Aktualisieren eines Secrets diesen Inhalt verschlüsseln:
Finale Tipps:
Versuche, keine Geheimnisse im FS zu speichern, hole sie aus anderen Quellen.
Schau dir https://www.vaultproject.io/ an, um zusätzlichen Schutz für deine Geheimnisse zu erhalten.
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)