In dieser Anleitung wird gezeigt, wie Sie die Knoten eines Google Kubernetes Engine-Clusters (GKE-Clusters) mithilfe von DaemonSets anpassen. Mit einem DaemonSet wird sichergestellt, dass alle (oder ausgewählte) Knoten eine Kopie eines Pods ausführen. Mit diesem Ansatz können Sie dieselben Tools zur Orchestrierung Ihrer Arbeitslasten verwenden, mit denen Sie auch Ihre GKE-Knoten ändern.
Wenn Sie zum Initialisieren Ihrer Cluster andere Tools und Systeme verwenden als zum Ausführen Ihrer Arbeitslasten, erhöht dies den Verwaltungsaufwand für Ihre Umgebung. Wenn Sie beispielsweise ein Konfigurationsmanagementtool zum Initialisieren der Clusterknoten verwenden, bauen Sie auf ein Verfahren außerhalb der Laufzeitumgebung, in der die übrigen Arbeitslasten ausgeführt werden.
Ziel dieser Anleitung ist es, Systemadministratoren, Systementwickler oder Infrastrukturbetreiber bei der Optimierung der Initialisierung von Kubernetes-Clustern zu unterstützen.
Bevor Sie diese Seite lesen, sollten Sie mit Folgendem vertraut sein:
In dieser Anleitung erfahren Sie, wie Sie mithilfe von Kubernetes-Labels und -Selektoren anhand der auf einen Knoten angewendeten Labels das auszuführende Initialisierungsverfahren auswählen. In diesen Schritten stellen Sie ein DaemonSet bereit, das nur auf Knoten ausgeführt werden soll, auf die das Label default-init
angewendet wurde. Sie könnten allerdings auch einen weiteren Knotenpool erstellen und das Label alternative-init
auf die Knoten in diesem neuen Pool anwenden, um die Flexibilität dieses Mechanismus zu demonstrieren. Im Cluster könnten Sie dann ein weiteres DaemonSet bereitstellen, das so konfiguriert ist, dass es nur auf Knoten mit dem Label alternative-init
ausgeführt wird.
Außerdem können Sie auf jedem Knoten mehrere Initialisierungsverfahren ausführen, nicht nur eines. Mit diesem Mechanismus lassen sich Ihre Initialisierungsverfahren besser strukturieren und die Belange jedes einzelnen klar voneinander abgrenzen.
In dieser Anleitung werden durch das Initialisierungsverfahren für jeden Knoten, der mit dem Label default-init
gekennzeichnet ist, die folgenden Aktionen ausgeführt:
- Fügt dem Knoten ein zusätzliches Laufwerk hinzu.
- Installiert mithilfe des Paketmanagers des Knotenbetriebssystems eine Reihe von Paketen und Bibliotheken.
- Lädt eine Reihe von Linux-Kernelmodulen.
Umgebung bootstrappen
In diesem Abschnitt tun Sie Folgendes:
- Erforderliche Cloud APIs aktivieren
- Dienstkonto mit eingeschränkten Berechtigungen für die Knoten im GKE-Cluster bereitstellen
- GKE-Cluster vorbereiten
- Nutzercluster Administratorrechte gewähren
Cloud APIs aktivieren
Cloud Shell öffnen
Wählen Sie das Google Cloud Projekt aus:
gcloud config set project project-id
Ersetzen Sie
project-id
durch die ID desGoogle Cloud -Projekts, das Sie für diese Anleitung erstellt oder ausgewählt haben.Aktivieren Sie die Google Kubernetes Engine API:
gcloud services enable container.googleapis.com
Dienstkonto zum Verwalten von GKE-Clustern bereitstellen
In diesem Abschnitt erstellen Sie ein Dienstkonto, das den Knoten im Cluster zugeordnet ist. In dieser Anleitung wird dieses Dienstkonto anstelle des Standarddienstkontos von GKE-Knoten verwendet. Als Best Practice empfehlen wir, dem Dienstkonto nur die zum Ausführen der Anwendung erforderlichen Rollen und Zugriffsberechtigungen zuzuweisen.
Folgende Rollen sind für das Dienstkonto erforderlich:
- Rolle "Monitoring-Betrachter" (
roles/monitoring.viewer
). Diese Rolle gewährt Lesezugriff auf die Cloud Monitoring-Konsole und die API. - Rolle "Monitoring-Messwert-Autor" (
roles/monitoring.metricWriter
). Diese Rolle ermöglicht das Schreiben von Monitoringdaten. - Rolle "Log-Autor" (
roles/logging.logWriter
). Diese Rolle gewährt gerade genug Berechtigungen zum Schreiben von Logs. - Rolle "Dienstkontonutzer" (
roles/iam.serviceAccountUser
). Diese Rolle gewährt Zugriff auf Dienstkonten in einem Projekt. In dieser Anleitung verwendet das Initialisierungsverfahren das Dienstkonto, um Vorgänge mit umfangreichen Rechten auszuführen. - Rolle "Compute-Administrator" (
roles/compute.admin
). Diese Rolle bietet vollständige Kontrolle über alle Compute Engine-Ressourcen. In dieser Anleitung benötigt das Dienstkonto diese Rolle, um zusätzliche Laufwerke an Clusterknoten anzuhängen.
So stellen Sie ein Dienstkonto bereit:
Initialisieren Sie in Cloud Shell eine Umgebungsvariable, in der der Name des Dienstkontos gespeichert wird:
GKE_SERVICE_ACCOUNT_NAME=ds-init-tutorial-gke
Erstellen Sie ein Dienstkonto:
gcloud iam service-accounts create "$GKE_SERVICE_ACCOUNT_NAME" \ --display-name="$GKE_SERVICE_ACCOUNT_NAME"
Initialisieren Sie eine Umgebungsvariable, in der der E-Mail-Kontoname des Dienstkontos gespeichert wird:
GKE_SERVICE_ACCOUNT_EMAIL="$(gcloud iam service-accounts list \ --format='value(email)' \ --filter=displayName:"$GKE_SERVICE_ACCOUNT_NAME")"
Binden Sie die IAM-Rollen (Identitäts- und Zugriffsverwaltung) an das Dienstkonto:
gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/compute.admin gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/monitoring.viewer gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/monitoring.metricWriter gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/logging.logWriter gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/iam.serviceAccountUser
GKE-Cluster vorbereiten
In diesem Abschnitt starten Sie den GKE-Cluster, gewähren Berechtigungen und schließen die Clusterkonfiguration ab.
Zum Demonstrieren des Konzepts dieser Anleitung reicht ein Cluster mit einer relativ kleinen Anzahl kleiner Knoten für allgemeine Zwecke aus. Sie erstellen einen Cluster mit einem Knotenpool (dem Standardpool). Anschließend fügen Sie allen Knoten im Standardknotenpool das Label default-init
hinzu.
Erstellen Sie in Cloud Shell einen regionalen GKE-Cluster und starten Sie ihn:
gcloud container clusters create ds-init-tutorial \ --enable-ip-alias \ --image-type=ubuntu_containerd \ --machine-type=n1-standard-2 \ --metadata disable-legacy-endpoints=true \ --node-labels=app=default-init \ --node-locations us-central1-a,us-central1-b,us-central1-c \ --no-enable-basic-auth \ --no-issue-client-certificate \ --num-nodes=1 \ --location us-central1 \ --service-account="$GKE_SERVICE_ACCOUNT_EMAIL"
DaemonSet bereitstellen
In diesem Abschnitt tun Sie Folgendes:
- Erstellen Sie die ConfigMap, in der das Initialisierungsverfahren gespeichert wird.
- Stellen Sie das DaemonSet bereit, mit dem das Initialisierungsverfahren geplant und ausgeführt wird.
Das DaemonSet macht Folgendes:
- Ein Volume konfigurieren, das den Containern, die das DaemonSet verarbeitet, den Inhalt der ConfigMap zur Verfügung stellt.
- Die Volumes für privilegierte Dateisystembereiche des zugrunde liegenden Clusterknotens konfigurieren. In diesen Bereichen können die vom DaemonSet geplanten Container direkt mit dem Knoten interagieren, der sie ausführt.
- Einen init-Container planen und ausführen, der das Initialisierungsverfahren ausführt und nach dessen Abschluss beendet wird.
- Einen Container planen und ausführen, der inaktiv bleibt und keine Ressourcen verbraucht.
Der inaktive Container sorgt dafür, dass ein Knoten nur einmal initialisiert wird. DaemonSets sind so konzipiert, dass alle infrage kommenden Knoten eine Kopie eines Pods ausführen. Wenn Sie einen regulären Container verwenden, führt dieser das Initialisierungsverfahren aus und wird nach Abschluss beendet. Das DaemonSet legt den Pod standardmäßig neu an. Um eine "kontinuierliche Neuplanung" zu vermeiden, führt das DaemonSet zuerst das Initialisierungsverfahren in einem init-Container aus und lässt dann einen Container laufen.
Das folgende Initialisierungsverfahren enthält privilegierte und nicht privilegierte Vorgänge. Mit chroot
können Sie Befehle so ausführen, als ob Sie sie direkt auf dem Knoten und nicht nur in einem Container ausführen würden.
Es ist auch ratsam, jedes Initialisierungsverfahren sorgfältig zu prüfen, da dieses den Status der Knoten Ihres Clusters ändern könnte. Nur eine kleine Gruppe von Personen sollte das Recht haben, diese Verfahren zu ändern, da diese Verfahren die Verfügbarkeit und Sicherheit Ihrer Cluster stark beeinträchtigen können.
So stellen Sie die ConfigMap und das DaemonSet bereit:
Legen Sie in Cloud Shell das Verzeichnis
$HOME
als Arbeitsverzeichnis fest:cd "$HOME"
Klonen Sie das Git-Repository, das die Skripts und Manifestdateien enthält, um das Initialisierungsverfahren bereitzustellen und zu konfigurieren:
git clone https://github.com/GoogleCloudPlatform/solutions-gke-init-daemonsets-tutorial
Ändern Sie das Arbeitsverzeichnis in das gerade geklonte Repository-Verzeichnis:
cd "$HOME"/solutions-gke-init-daemonsets-tutorial
Erstellen Sie eine ConfigMap für das Knoteninitialisierungsskript:
kubectl apply -f cm-entrypoint.yaml
Stellen Sie das DaemonSet bereit:
kubectl apply -f daemon-set.yaml
Prüfen Sie, ob die Knoteninitialisierung abgeschlossen ist:
kubectl get ds --watch
Warten Sie, bis sie für das DaemonSet abgeschlossen und auf dem aktuellen Stand ist. Dies wird in einer Ausgabe wie der folgenden angezeigt:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE node-initializer 3 3 3 3 3 <none> 2h
Initialisierungsverfahren validieren und verifizieren
Nachdem jeder Knoten des Clusters, der mit dem Label default-init
gekennzeichnet ist, das Initialisierungsverfahren ausgeführt hat, können Sie die Ergebnisse prüfen.
Bei jedem Knoten überprüft das Überprüfungsverfahren Folgendes:
- Ein zusätzliches Laufwerk wird angehängt und kann verwendet werden.
- Der Paketmanager des Knotenbetriebssystems hat Pakete und Bibliotheken installiert.
- Kernelmodule werden geladen.
Führen Sie das Überprüfungsverfahren aus:
Führen Sie in Cloud Shell das Überprüfungsskript aus:
kubectl get nodes -o=jsonpath='{range .items[?(@.metadata.labels.app=="default-init")]}{.metadata.name}{" "}{.metadata.labels.failure-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}' | while IFS= read -r line ; do ./verify-init.sh $line < /dev/null; done
Warten Sie, bis das Skript ausgeführt wurde, und prüfen Sie, ob jeder Knoten korrekt initialisiert wurde. Dies wird in etwa so dargestellt:
Verifying gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Packages installed successfully in gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Verifying gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Packages installed successfully in gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Verifying gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) Packages installed successfully in gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b)