Anwendungen auf Kubernetes bereitstellen

KubernetesBeginner
Jetzt üben

Einführung

In diesem Lab lernen Sie, wie Sie Anwendungen auf einem Kubernetes-Cluster bereitstellen. Wir beginnen mit der Einrichtung einer Kubernetes-Umgebung mithilfe von Minikube. Anschließend erkunden Sie wichtige kubectl-Befehle, um mit Ihrem Cluster zu interagieren und Kubernetes-Ressourcen zu verwalten. Als Nächstes erstellen Sie eine einfache YAML-Manifestdatei, wenden diese auf Ihren Cluster an und überprüfen den Status der Bereitstellung. Abschließend lernen Sie, wie Sie über kubectl proxy auf Ihre bereitgestellte Anwendung zugreifen.

Dieses Lab behandelt grundlegende Kubernetes-Fähigkeiten, einschließlich Cluster-Einrichtung, grundlegendem Ressourcenmanagement und Anwendungsbereitstellung. Am Ende dieses Labs werden Sie ein solides Verständnis dafür haben, wie Sie mit Kubernetes arbeiten und Ihre eigenen Anwendungen bereitstellen.

Kubernetes-Cluster starten

In diesem Schritt starten wir einen Kubernetes-Cluster mit Minikube. Minikube ist ein hervorragendes Werkzeug für die Entwicklung und das Erlernen von Kubernetes, da es Ihnen ermöglicht, einen Single-Node-Kubernetes-Cluster in einer virtualisierten Umgebung auszuführen. Anschließend überprüfen wir, ob der Cluster korrekt läuft und einsatzbereit ist.

Öffnen Sie zuerst Ihr Terminal. Hier geben Sie Befehle ein, um mit Ihrem Computer zu interagieren. Um den Minikube-Cluster zu starten, geben Sie den folgenden Befehl ein und drücken Sie Enter:

minikube start

Dieser Befehl initiiert den Prozess der Erstellung und des Starts Ihres Kubernetes-Clusters. Minikube lädt notwendige Komponenten herunter und konfiguriert Ihren Cluster. Sie sehen im Terminal Ausgaben, während Minikube startet. Hier ist ein Beispiel, wie die Ausgabe aussehen könnte:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Automatically selected the docker driver
📌  Using Docker driver with root permissions
🔥  Creating kubernetes in kubernetes cluster
🔄  Restarting existing kubernetes cluster
🐳  Preparing Kubernetes v1.26.1 on Docker 20.10.23 ...
🚀  Launching Kubernetes ...
🌟  Enabling addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace

Sobald Minikube gestartet ist, überprüfen wir, ob es läuft und der Kubernetes-Cluster bereit ist. Führen Sie die folgenden Befehle nacheinander aus und drücken Sie nach jedem Befehl Enter:

minikube status
kubectl get nodes

Der Befehl minikube status zeigt Ihnen den Status von Minikube selbst an. Der Befehl kubectl get nodes kommuniziert mit Ihrem Kubernetes-Cluster und ruft Informationen über die Knoten (Computer) in Ihrem Cluster ab. Da Minikube ein Single-Node-Cluster ist, sollten Sie einen Knoten aufgelistet sehen.

Hier ist ein Beispiel für die Ausgabe, die Sie sehen könnten:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

Lassen Sie uns aufschlüsseln, was diese Ausgabe uns sagt:

  1. Der minikube-Status zeigt Running für host, kubelet und apiserver. Dies deutet darauf hin, dass die Kernkomponenten von Minikube korrekt laufen.
  2. kubectl get nodes zeigt einen Knoten namens minikube mit dem STATUS Ready. Ready bedeutet, dass dieser Knoten bereit ist, Anwendungen auszuführen. control-plane unter ROLES zeigt an, dass dieser Knoten als Control Plane für den Kubernetes-Cluster fungiert und den Cluster verwaltet und orchestriert.

Diese Befehle bestätigen, dass:

  1. Minikube in der virtuellen Maschinenumgebung läuft.
  2. Ein Kubernetes-Cluster von Minikube erstellt und konfiguriert wurde.
  3. Der Kubernetes-Cluster im Status Ready ist und zur Verwendung bereitsteht.
  4. Sie einen Single-Node-Kubernetes-Cluster haben, bei dem der minikube-Knoten als Control Plane fungiert.

Grundlegende kubectl-Befehle und Syntax erlernen

In diesem Schritt werden wir grundlegende kubectl-Befehle untersuchen. kubectl ist das Kommandozeilenwerkzeug, mit dem Sie mit Ihrem Kubernetes-Cluster interagieren können. Es ist unerlässlich für die Verwaltung von Kubernetes-Ressourcen. Wir werden zeigen, wie Sie kubectl verwenden, um Ressourcen anzuzeigen und grundlegendes Kubernetes-Objektmanagement zu verstehen.

Beginnen wir mit der Erkundung der Namespaces in Ihrem Kubernetes-Cluster. Namespaces sind eine Möglichkeit, Ihre Kubernetes-Ressourcen zu organisieren. Standardmäßig verfügen Kubernetes-Cluster über mehrere Namespaces für Systemkomponenten und Benutzerressourcen. Um eine Liste der Namespaces anzuzeigen, führen Sie den folgenden Befehl aus:

kubectl get namespaces

Dieser Befehl listet alle in Ihrem Cluster verfügbaren Namespaces auf. Beispielausgabe:

NAME              STATUS   AGE
default           Active   10m
kube-node-lease   Active   10m
kube-public       Active   10m
kube-system       Active   10m

Sie sehen normalerweise mindestens diese Standard-Namespaces:

  • default: Der Standard-Namespace für vom Benutzer erstellte Ressourcen, wenn kein anderer Namespace angegeben ist.
  • kube-node-lease: Wird für Node-Leases verwendet, die dem Control Plane helfen, den Zustand der Nodes zu verfolgen.
  • kube-public: Ist für Ressourcen vorgesehen, die öffentlich zugänglich sein sollen (obwohl dies selten für sensible Informationen verwendet wird).
  • kube-system: Enthält Systemressourcen, wie z. B. Kernkomponenten von Kubernetes.

Als Nächstes betrachten wir die Systemkomponenten, die im Namespace kube-system laufen. Viele Kernkomponenten von Kubernetes laufen als Pods in diesem Namespace. Um Pods in einem bestimmten Namespace anzuzeigen, verwenden Sie das Flag -n oder --namespace, gefolgt vom Namespace-Namen. Führen Sie den folgenden Befehl aus, um Pods im Namespace kube-system anzuzeigen:

kubectl get pods -n kube-system

Dieser Befehl listet alle Pods auf, die im Namespace kube-system laufen. Beispielausgabe:

NAME                               READY   STATUS    RESTARTS   AGE
coredns-787d4945fb-j8rhx           1/1     Running   0          15m
etcd-minikube                       1/1     Running   0          15m
kube-apiserver-minikube             1/1     Running   0          15m
kube-controller-manager-minikube    1/1     Running   0          15m
kube-proxy-xb9rz                    1/1     Running   0          15m
kube-scheduler-minikube             1/1     Running   0          15m
storage-provisioner                 1/1     Running   0          15m

Diese Ausgabe zeigt die Namen der Pods, ihren READY-Status (wie viele Container im Pod von der Gesamtzahl bereit sind), ihren STATUS (z. B. Running), wie oft sie RESTARTED wurden, und ihr AGE. Dies sind die wesentlichen Komponenten, die Kubernetes zum Laufen bringen.

Nun erkunden wir einige grundlegende kubectl-Befehlsmuster. Die allgemeine Syntax für kubectl-Befehle lautet:

kubectl [command] [TYPE] [NAME] [flags]

Lassen Sie uns dies aufschlüsseln:

  • kubectl: Das Kommandozeilenwerkzeug selbst.
  • [command]: Gibt an, welche Aktion Sie ausführen möchten. Gängige Befehle sind:
    • get: Zeigt eine oder mehrere Ressourcen an.
    • describe: Zeigt Details zu einer bestimmten Ressource an.
    • create: Erstellt eine neue Ressource.
    • delete: Löscht Ressourcen.
    • apply: Wendet eine Konfiguration auf eine Ressource an. Dies werden wir später oft verwenden.
  • [TYPE]: Gibt den Kubernetes-Ressourcentyp an, mit dem Sie interagieren möchten. Gängige Ressourcentypen sind:
    • pods: Die kleinsten bereitstellbaren Einheiten in Kubernetes.
    • deployments: Verwaltet Sätze von Pods für Skalierung und Updates.
    • services: Macht Anwendungen, die in Pods laufen, verfügbar.
    • nodes: Die Worker-Maschinen in Ihrem Kubernetes-Cluster.
    • namespaces: Logische Gruppierungen von Ressourcen.
  • [NAME]: Der Name einer bestimmten Ressource. Dies ist optional; wenn Sie den Namen weglassen, operiert kubectl auf allen Ressourcen des angegebenen Typs.
  • [flags]: Optionale Flags zur Änderung des Befehlsverhaltens (z. B. -n <namespace>, -o wide).

Sehen wir uns einige Beispiele an:

## Alle Ressourcen im Standard-Namespace abrufen
kubectl get all

## Einen bestimmten Ressourcentyp beschreiben (den 'minikube'-Knoten)
kubectl describe nodes minikube

Der Befehl kubectl get all ruft Informationen über alle Ressourcentypen (Services, Deployments, Pods usw.) im default-Namespace ab. Die Beispielausgabe könnte wie folgt aussehen:

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   20m

Dies zeigt, dass wir im default-Namespace einen service namens kubernetes haben.

Der Befehl kubectl describe nodes minikube liefert viele detaillierte Informationen über den minikube-Knoten, einschließlich seines Status, seiner Kapazität, Adressen und mehr. Dies ist hilfreich, um den Zustand und die Konfiguration Ihrer Knoten zu verstehen.

Diese Befehle helfen Ihnen dabei:

  1. Die Ressourcen in Ihrem Kubernetes-Cluster anzuzeigen.
  2. Detaillierte Informationen über Clusterkomponenten und deren aktuellen Status zu erhalten.
  3. Die grundlegende Befehlsstruktur und Syntax von kubectl zu verstehen.

Erstellen eines einfachen YAML-Manifests

Bevor Sie Ihr erstes YAML-Manifest erstellen, ist es wichtig, die wichtigsten Kubernetes-Objekte zu verstehen, mit denen Sie arbeiten werden. Diese Objekte sind die Bausteine für die Verwaltung und Orchestrierung Ihrer Anwendungen innerhalb von Kubernetes.

Verständnis von Kubernetes-Objekten

  • Pod: Die grundlegendste Einheit in Kubernetes. Ein Pod ist wie eine Box, die einen oder mehrere Container enthalten kann. Diese Container innerhalb eines Pods teilen sich dasselbe Netzwerk und denselben Speicher. Betrachten Sie einen Pod als eine einzelne Instanz Ihrer Anwendung.
  • Deployment: Deployments werden zur Verwaltung von Pods verwendet. Sie stellen sicher, dass jederzeit eine gewünschte Anzahl von Pod-Replikaten läuft. Wenn ein Pod ausfällt, ersetzt ein Deployment ihn automatisch. Deployments kümmern sich auch auf kontrollierte Weise um Updates Ihrer Anwendung, wie z. B. Rolling Updates.
  • Service: Services bieten eine stabile Möglichkeit, auf Ihre in Pods laufende Anwendung zuzugreifen. Da Pods erstellt und zerstört werden können, können sich ihre IP-Adressen ändern. Ein Service bietet eine feste IP-Adresse und einen DNS-Namen, der immer auf die von ihm verwalteten Pods verweist. Dies ermöglicht es anderen Teilen Ihrer Anwendung oder externen Benutzern, zuverlässig auf Ihre Anwendung zuzugreifen, ohne einzelne Pod-IPs verfolgen zu müssen.

Hier ist ein Diagramm, das die Beziehungen zwischen diesen Objekten veranschaulicht:

graph TD; A[Deployment] -->|Manages| B[Pods] B -->|Contains| C[Containers] B -->|Communicates via| D[Services] D -->|Exposes| E[External Clients]

Das Verständnis dieser Objekte ist entscheidend, da Sie deren gewünschten Zustand und Konfiguration mithilfe von YAML-Manifesten definieren werden.

YAML-Manifest-Übersicht

Ein YAML-Manifest in Kubernetes ist eine Datei im YAML-Format, die die Kubernetes-Objekte beschreibt, die Sie erstellen oder verwalten möchten. YAML ist eine menschenlesbare Sprache zur Daten serialisierung. Die Verwendung von YAML für Kubernetes-Manifeste bietet mehrere Vorteile:

  1. Deklarative Verwaltung: Sie beschreiben den gewünschten Zustand Ihrer Ressourcen in der YAML-Datei (z. B. "Ich möchte, dass 3 Replikate meiner Anwendung laufen"). Kubernetes arbeitet dann daran, den tatsächlichen Zustand mit Ihrem gewünschten Zustand abzugleichen. Dies wird als deklarative Verwaltung bezeichnet.
  2. Versionskontrolle: YAML-Dateien sind textbasiert und können einfach in Versionskontrollsystemen wie Git gespeichert werden. Dies ermöglicht es Ihnen, Änderungen an Ihren Kubernetes-Konfigurationen im Laufe der Zeit zu verfolgen, zu früheren Konfigurationen zurückzukehren und mit anderen zusammenzuarbeiten.
  3. Wiederverwendbarkeit und Portabilität: Sie können YAML-Manifeste in verschiedenen Umgebungen (Entwicklung, Test, Produktion) mit minimalen Änderungen wiederverwenden. Dies macht Ihre Deployments konsistenter und reproduzierbarer.

Nachdem Sie die Grundlagen von Kubernetes-Objekten und YAML-Manifesten verstanden haben, sind Sie bereit, Ihr erstes Manifest zu erstellen.

Erstellen eines YAML-Manifests

Navigieren Sie zuerst zu Ihrem Projektverzeichnis. Es wird davon ausgegangen, dass Sie ein Verzeichnis project in Ihrem Home-Verzeichnis (~) haben. Wenn Sie es nicht haben, erstellen Sie es jetzt mit mkdir project. Ändern Sie dann Ihr aktuelles Verzeichnis zu project mit cd project:

cd ~/project

Erstellen Sie als Nächstes ein neues Verzeichnis, um Ihre Kubernetes-Manifeste zu speichern. Nennen wir es k8s-manifests. Verwenden Sie den Befehl mkdir, um das Verzeichnis zu erstellen, und dann cd, um hineinzuwechseln:

mkdir -p k8s-manifests
cd k8s-manifests

Nun erstellen Sie Ihre erste YAML-Manifestdatei. Beginnen wir mit einem einfachen Manifest für einen NGINX-Pod. NGINX ist ein beliebter Webserver. Wir erstellen einen Pod, der einen einzelnen NGINX-Container ausführt. Verwenden Sie den Texteditor nano, um eine Datei namens nginx-pod.yaml zu erstellen:

nano nginx-pod.yaml

nano ist ein einfacher Texteditor, der in Ihrem Terminal läuft. Sobald nano geöffnet ist, fügen Sie den folgenden Inhalt in die Datei ein:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

Lassen Sie uns jeden Teil dieses YAML-Manifests verstehen:

  • apiVersion: v1: Gibt die Kubernetes-API-Version an, die für die Erstellung dieses Objekts verwendet werden soll. v1 ist die Kern-API-Gruppe und wird für grundlegende Objekte wie Pods, Services und Namespaces verwendet.
  • kind: Pod: Zeigt an, dass Sie eine Pod-Ressource definieren.
  • metadata:: Enthält Daten über den Pod, wie z. B. seinen Namen und seine Labels.
    • name: nginx-pod: Setzt den Namen des Pods auf nginx-pod. Dies ist, wie Sie diesen Pod innerhalb von Kubernetes referenzieren werden.
    • labels:: Labels sind Schlüssel-Wert-Paare, die Objekten zugeordnet sind. Sie werden verwendet, um Objektmengen zu organisieren und auszuwählen. Hier fügen wir diesem Pod ein Label app: nginx hinzu.
  • spec:: Beschreibt den gewünschten Zustand des Pods.
    • containers:: Eine Liste von Containern, die innerhalb des Pods ausgeführt werden sollen. In diesem Fall haben wir nur einen Container.
      • - name: nginx: Setzt den Namen des Containers auf nginx.
      • image: nginx:latest: Gibt das zu verwendende Container-Image an. nginx:latest bezieht sich auf die neueste Version des NGINX Docker-Images von Docker Hub.
      • ports:: Eine Liste von Ports, die dieser Container verfügbar machen wird.
        • - containerPort: 80: Gibt an, dass der Container Port 80 verfügbar machen wird. Port 80 ist der Standard-HTTP-Port.

Nachdem Sie den Inhalt eingefügt haben, speichern Sie die Datei und beenden Sie nano. Tun Sie dies, indem Sie Ctrl+X (Beenden) drücken, dann Y (Ja zum Speichern) eingeben und schließlich Enter drücken, um den Dateinamen zu bestätigen und zu speichern.

Nachdem Sie Ihre nginx-pod.yaml-Datei erstellt haben, müssen Sie sie auf Ihren Kubernetes-Cluster anwenden, um den Pod zu erstellen. Verwenden Sie den Befehl kubectl apply mit dem Flag -f, das die Datei mit dem Manifest angibt:

kubectl apply -f nginx-pod.yaml

Dieser Befehl sendet das Manifest an Ihren Kubernetes-Cluster, und Kubernetes erstellt den Pod wie definiert. Sie sollten eine Ausgabe sehen, die dieser ähnelt:

pod/nginx-pod created

Um zu überprüfen, ob der Pod erstellt wurde und läuft, verwenden Sie den Befehl kubectl get pods. Dieser listet alle Pods im Standard-Namespace auf. Sie können auch kubectl describe pod nginx-pod verwenden, um detaillierte Informationen über den nginx-pod zu erhalten. Führen Sie diese Befehle aus:

kubectl get pods
kubectl describe pod nginx-pod

Beispielausgabe für kubectl get pods:

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          1m

Diese Ausgabe zeigt, dass der nginx-pod READY (1 von 1 Container ist bereit) ist und sein STATUS Running ist. Das bedeutet, dass Ihr NGINX-Pod erfolgreich erstellt wurde und läuft.

Erstellen wir nun ein Manifest für eine komplexere Ressource: ein Deployment. Ein Deployment verwaltet eine Reihe von Pods und stellt sicher, dass die gewünschte Anzahl von Replikaten läuft. Erstellen Sie eine neue Datei namens nginx-deployment.yaml mit nano:

nano nginx-deployment.yaml

Fügen Sie den folgenden Inhalt in nginx-deployment.yaml ein:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

Heben wir die wichtigsten Unterschiede und neuen Teile im Vergleich zum nginx-pod.yaml-Manifest hervor:

  • apiVersion: apps/v1: Für Deployments verwenden Sie die API-Version apps/v1, die Teil der API-Gruppe apps ist und übergeordnete Anwendungsmanagement-Ressourcen behandelt.
  • kind: Deployment: Zeigt an, dass Sie eine Deployment-Ressource definieren.
  • spec:: Der spec-Abschnitt für ein Deployment ist komplexer, da er definiert, wie das Deployment Pods verwalten soll.
    • replicas: 3: Dies ist neu. Es gibt an, dass Sie 3 Replikate (Kopien) Ihres Pods laufen lassen möchten. Das Deployment stellt sicher, dass immer 3 Pods vorhanden sind, die den in der template definierten Kriterien entsprechen.
    • selector:: Ein Selektor wird vom Deployment verwendet, um zu identifizieren, welche Pods es verwalten soll.
      • matchLabels:: Definiert die Labels, die Pods haben müssen, um von diesem Deployment ausgewählt zu werden. Hier werden Pods mit dem Label app: nginx ausgewählt.
    • template:: Die template definiert die Pod-Spezifikation, die das Deployment zum Erstellen neuer Pods verwendet. Es ist im Wesentlichen dieselbe Pod-Definition wie in unserem nginx-pod.yaml-Beispiel, einschließlich metadata.labels und spec.containers. Wichtig: Die hier in template.metadata.labels definierten Labels müssen mit den selector.matchLabels übereinstimmen, damit das Deployment diese Pods verwalten kann.

Speichern und beenden Sie nano (Ctrl+X, Y, Enter).

Wenden Sie nun dieses Deployment-Manifest auf Ihren Cluster an:

kubectl apply -f nginx-deployment.yaml

Sie sollten eine Ausgabe wie diese sehen:

deployment.apps/nginx-deployment created

Überprüfen Sie das Deployment und die von ihm erstellten Pods. Verwenden Sie kubectl get deployments, um den Status des Deployments zu überprüfen, und kubectl get pods, um die Pods anzuzeigen.

kubectl get deployments
kubectl get pods

Beispielausgabe:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m
  • kubectl get deployments zeigt, dass das nginx-deployment READY 3/3, UP-TO-DATE 3 und AVAILABLE 3 hat. Das bedeutet, dass das Deployment erfolgreich 3 Pods erstellt hat und diese verwaltet, und alle sind bereit und verfügbar.
  • kubectl get pods listet nun drei Pods auf, deren Namen mit nginx-deployment- beginnen. Dies sind die von Ihrem nginx-deployment erstellten und verwalteten Pods.

Anwenden des YAML-Manifests

In diesem Schritt werden wir den Befehl kubectl apply detaillierter untersuchen und verschiedene Möglichkeiten zum Anwenden von Kubernetes-Manifesten kennenlernen. Aufbauend auf den YAML-Dateien aus dem vorherigen Schritt werden wir verschiedene Techniken zum Anwenden von Manifesten demonstrieren.

Stellen Sie zunächst sicher, dass Sie sich im richtigen Verzeichnis befinden:

cd ~/project/k8s-manifests

Erstellen wir ein neues Unterverzeichnis, um unsere Manifeste weiter zu organisieren. Erstellen Sie ein Verzeichnis namens manifests und wechseln Sie hinein:

mkdir -p manifests
cd manifests

Nun erstellen wir ein Manifest für eine einfache Webanwendung, das sowohl ein Deployment als auch einen Service in einer einzigen Datei enthält. Erstellen Sie eine neue Datei namens web-app.yaml mit nano:

nano web-app.yaml

Fügen Sie den folgenden Inhalt zu web-app.yaml hinzu:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

Dieses Manifest definiert zwei Kubernetes-Ressourcen in einer einzigen Datei, getrennt durch ---. Dies ist eine gängige Methode, um zusammengehörige Ressourcen zu gruppieren. Lassen Sie uns aufschlüsseln, was neu ist:

  • Mehrere Ressourcen in einer Datei: Die Datei web-app.yaml enthält nun zwei separate Kubernetes-Ressourcendefinitionen: ein Deployment und einen Service. Der Trenner --- wird verwendet, um zwischen ihnen zu unterscheiden.
  • kind: Service: Dies definiert eine Service-Ressource.
    • spec.selector.app: web: Dieser Service zielt auf Pods ab, die das Label app: web haben. Dies stimmt mit den Labels überein, die wir für die von dem web-app-Deployment erstellten Pods festgelegt haben.
    • spec.type: ClusterIP: Gibt den Servicetyp als ClusterIP an. Das bedeutet, dass der Service über eine interne IP-Adresse innerhalb des Clusters verfügbar gemacht wird und typischerweise für die Kommunikation zwischen Services innerhalb des Clusters verwendet wird.
    • spec.ports: Definiert, wie der Service Ports an die Ziel-Pods weiterleitet.
      • port: 80: Der Port des Services selbst, auf den Sie zugreifen werden.
      • targetPort: 80: Der Port auf den Ziel-Pods, an den der Service den Datenverkehr weiterleitet.

Lassen Sie uns nun dieses Manifest mit verschiedenen Methoden anwenden.

Methode 1: Die gesamte Datei anwenden

Dies ist die gebräuchlichste Methode, ein Manifest anzuwenden. Verwenden Sie kubectl apply -f, gefolgt vom Dateinamen:

kubectl apply -f web-app.yaml

Dieser Befehl erstellt sowohl das Deployment als auch den Service, die in web-app.yaml definiert sind. Sie sollten eine Ausgabe wie diese sehen:

deployment.apps/web-app created
service/web-service created

Methode 2: Aus einem Verzeichnis anwenden

Sie können alle Manifeste in einem Verzeichnis auf einmal anwenden. Wenn Sie mehrere Manifestdateien im Verzeichnis manifests haben, können Sie sie alle anwenden, indem Sie das Verzeichnis anstelle einer bestimmten Datei angeben:

kubectl apply -f .

Der Punkt (.) repräsentiert das aktuelle Verzeichnis. kubectl sucht nach YAML-Dateien in diesem Verzeichnis und wendet alle davon an. Dies ist nützlich, wenn Sie Ihre Manifeste in mehreren Dateien innerhalb eines Verzeichnisses organisiert haben.

Methode 3: Von einer URL anwenden (Optional)

kubectl apply kann Manifeste auch direkt von einer URL anwenden. Dies ist nützlich, um schnell Beispielanwendungen oder online gehostete Konfigurationen bereitzustellen. Sie können beispielsweise das Redis-Master-Deployment aus dem Kubernetes-Beispiel-Repository bereitstellen:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/redis-master-deployment.yaml

Dadurch wird das Manifest von der URL heruntergeladen und auf Ihren Cluster angewendet. Hinweis: Seien Sie vorsichtig beim Anwenden von Manifesten aus nicht vertrauenswürdigen URLs, da diese Ihren Cluster potenziell verändern können.

Lassen Sie uns einige zusätzliche Optionen für kubectl apply untersuchen.

Dry Run

Sie können das Flag --dry-run=client verwenden, um das Anwenden eines Manifests zu simulieren, ohne tatsächlich Änderungen am Cluster vorzunehmen. Dies ist nützlich, um zu überprüfen, ob Ihr Manifest gültig ist, und um zu sehen, welche Ressourcen erstellt oder geändert würden:

kubectl apply -f web-app.yaml --dry-run=client

Dieser Befehl gibt aus, was erstellt oder geändert würde, aber er wendet die Änderungen nicht tatsächlich auf Ihren Cluster an.

Ausführliche Ausgabe

Für eine detailliertere Ausgabe von kubectl apply können Sie das Flag -v gefolgt von einer Detaillierungsstufe (z. B. -v=7) verwenden. Höhere Detaillierungsstufen liefern detailliertere Informationen, die für die Fehlersuche hilfreich sein können:

kubectl apply -f web-app.yaml -v=7

Dies gibt viel mehr Informationen über die ausgeführten API-Anfragen und die Verarbeitung des Manifests aus.

Überprüfen Sie die durch das Anwenden von web-app.yaml erstellten Ressourcen. Verwenden Sie kubectl get deployments und kubectl get services, um die Deployments und Services in Ihrem Cluster aufzulisten:

## Deployments auflisten
kubectl get deployments

## Services auflisten
kubectl get services

## Das Deployment beschreiben, um weitere Details anzuzeigen
kubectl describe deployment web-app

Beispielausgabe für kubectl get deployments:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           3m33s
redis-master       0/1     1            0           23s
web-app            2/2     2            2           42s

Beispielausgabe für kubectl get services:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   8m28s
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    46s

Beachten Sie, dass Sie nun ein web-app-Deployment mit 2/2 READY-Replikaten und einen web-service vom Typ ClusterIP haben.

Lassen Sie uns kurz den Unterschied zwischen deklarativer und imperativer Verwaltung in Kubernetes diskutieren, insbesondere im Kontext von kubectl apply und kubectl create.

  • kubectl apply: Verwendet einen deklarativen Ansatz. Sie definieren den gewünschten Zustand in Ihren Manifestdateien, und kubectl apply versucht, diesen Zustand zu erreichen. Wenn Sie kubectl apply mehrmals mit demselben Manifest ausführen, nimmt Kubernetes nur dann Änderungen vor, wenn Unterschiede zwischen dem gewünschten Zustand im Manifest und dem aktuellen Zustand im Cluster bestehen. kubectl apply wird im Allgemeinen für die Verwaltung von Kubernetes-Ressourcen empfohlen, da es robuster und einfacher zu verwalten ist. Es verfolgt die Konfiguration Ihrer Ressourcen und ermöglicht inkrementelle Updates.
  • kubectl create: Verwendet einen imperativen Ansatz. Sie weisen Kubernetes direkt an, eine Ressource zu erstellen. Wenn Sie versuchen, kubectl create für eine bereits vorhandene Ressource auszuführen, führt dies in der Regel zu einem Fehler. kubectl create ist im Vergleich zu kubectl apply weniger flexibel für die Verwaltung von Updates und Änderungen.

In den meisten Fällen, insbesondere für die Verwaltung von Anwendungs-Deployments, ist kubectl apply die bevorzugte und empfohlene Methode aufgrund seiner deklarativen Natur und besseren Handhabung von Updates und Konfigurationsmanagement.

Überprüfen des Deployment-Status

In diesem Schritt lernen Sie, wie Sie den Status von Kubernetes-Deployments und anderen Ressourcen mit verschiedenen kubectl-Befehlen inspizieren und überprüfen können. Sie werden verschiedene Möglichkeiten erkunden, um Informationen über Ihre laufenden Anwendungen und deren Zustand innerhalb des Kubernetes-Clusters zu sammeln.

Stellen Sie zunächst sicher, dass Sie sich im Verzeichnis manifests Ihres Projekts befinden:

cd ~/project/k8s-k8s-manifests/manifests

Beginnen wir mit der Auflistung aller Deployments im aktuellen Namespace (der default ist, es sei denn, Sie haben ihn geändert). Verwenden Sie kubectl get deployments:

kubectl get deployments

Dieser Befehl liefert einen prägnanten Überblick über Ihre Deployments. Beispielausgabe:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           4m44s
redis-master       1/1     1            1           94s
web-app            2/2     2            2           113s

Hier ist die Bedeutung jeder Spalte:

  • NAME: Der Name des Deployments.
  • READY: Zeigt die Anzahl der bereiten Replikate im Verhältnis zur gewünschten Anzahl von Replikaten an (z. B. bedeutet 3/3, dass 3 gewünschte Replikate bereit sind).
  • UP-TO-DATE: Gibt an, wie viele Replikate auf den neuesten gewünschten Zustand aktualisiert wurden.
  • AVAILABLE: Zeigt an, wie viele Replikate derzeit verfügbar sind, um Datenverkehr zu bedienen.
  • AGE: Wie lange das Deployment bereits läuft.

Um detailliertere Informationen in einem breiteren Format zu erhalten, können Sie das Flag -o wide mit kubectl get deployments verwenden:

kubectl get deployments -o wide

Beispielausgabe:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                      SELECTOR
nginx-deployment   3/3     3            3           4m58s   nginx        nginx:latest                app=nginx
redis-master       1/1     1            1           108s    master       registry.k8s.io/redis:e2e   app=redis,role=master,tier=backend
web-app            2/2     2            2           2m7s    web          nginx:alpine                app=web

Die Ausgabe von -o wide enthält zusätzliche Spalten wie CONTAINERS, IMAGES und SELECTOR, die mehr Kontext zum Deployment liefern.

Um die Pods zu inspizieren, die Teil eines bestimmten Deployments sind, können Sie Labels verwenden. Denken Sie daran, dass wir in unserem web-app-Deployment-Manifest das Label app: web für die Pods gesetzt haben. Sie können dieses Label verwenden, um Pods mit kubectl get pods -l <label_selector> zu filtern. Um die mit dem web-app-Deployment verbundenen Pods anzuzeigen, führen Sie Folgendes aus:

kubectl get pods -l app=web

Beispielausgabe:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          10m
web-app-xxx-zzz           1/1     Running   0          10m

Dies listet die Pods auf, die dem Label-Selektor app=web entsprechen, also die Pods, die vom web-app-Deployment verwaltet werden.

Für tiefgehende Informationen zu einem bestimmten Deployment verwenden Sie kubectl describe deployment <deployment_name>. Beschreiben wir das web-app-Deployment:

kubectl describe deployment web-app

kubectl describe liefert eine Fülle von Informationen über das Deployment, darunter:

  • Name, Namespace, CreationTimestamp, Labels, Annotations: Grundlegende Metadaten über das Deployment.
  • Selector: Der Label-Selektor, der zur Identifizierung von Pods verwendet wird, die von diesem Deployment verwaltet werden.
  • Replicas: Gewünschte, aktualisierte, Gesamt-, verfügbare und nicht verfügbare Replikatzählungen.
  • StrategyType, RollingUpdateStrategy: Details zur Update-Strategie (z. B. RollingUpdate).
  • Pod Template: Die Spezifikation, die zum Erstellen von Pods für dieses Deployment verwendet wird.
  • Conditions: Bedingungen, die den Status des Deployments anzeigen (z. B. Available, Progressing).
  • Events: Eine Liste von Ereignissen im Zusammenhang mit dem Deployment, die bei der Fehlerbehebung hilfreich sein können.

Schauen Sie sich die Abschnitte Conditions und Events in der describe-Ausgabe an. Diese Abschnitte liefern oft Hinweise, wenn es Probleme mit Ihrem Deployment gibt. Wenn ein Deployment beispielsweise nicht Available wird, zeigen die Events möglicherweise Fehler im Zusammenhang mit dem Image-Pulling, Pod-Erstellungsfehlern usw. an.

Um den Status des Services zu überprüfen, können Sie ähnliche Befehle verwenden. Listen Sie zunächst alle Services auf:

kubectl get services

Beispielausgabe:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   10m
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    2m47s

Dies zeigt den web-service zusammen mit seinem TYPE (ClusterIP), CLUSTER-IP und den verfügbaren PORT(S).

Für weitere Details zu einem Service verwenden Sie kubectl describe service <service_name>:

kubectl describe service web-service

Die Ausgabe von describe service enthält:

  • Name, Namespace, Labels, Annotations: Grundlegende Metadaten.
  • Selector: Der Label-Selektor, der zur Identifizierung der Ziel-Pods verwendet wird.
  • Type: Der Servicetyp (ClusterIP in diesem Fall).
  • IP, IPs: Die dem Service zugewiesene Cluster-IP-Adresse.
  • Port, TargetPort: Für den Service definierte Port-Mappings.
  • Endpoints: Zeigt die IP-Adressen und Ports der Pods an, die diesen Service derzeit unterstützen. Dies ist sehr wichtig. Wenn Sie keine Endpunkte sehen, bedeutet dies, dass der Service nicht korrekt mit Pods verbunden ist, wahrscheinlich aufgrund einer Diskrepanz im Selektor.
  • Session Affinity, Events: Weitere Servicekonfigurationen und Ereignisse.

Bei der Überprüfung des Deployment-Status sollten Sie auf Folgendes achten:

  • Deployment READY-Status: Stellen Sie sicher, dass die gewünschte Anzahl von Replikaten angezeigt wird (z. B. 2/2 für web-app).
  • Pod STATUS: Alle Pods sollten den Status Running haben.
  • Service Endpoints: Überprüfen Sie, ob der Service Endpunkte hat und ob diese den IP-Adressen Ihrer laufenden Pods entsprechen. Wenn keine Endpunkte vorhanden sind, beheben Sie Probleme mit dem Selektor des Services und den Pod-Labels.
  • Auf Warnungen oder Fehler prüfen: Untersuchen Sie die Ausgabe von kubectl describe deployment <deployment_name> und kubectl describe service <service_name> auf ungewöhnliche Bedingungen oder Fehler in den Abschnitten Events.

Durch die Verwendung dieser kubectl-Befehle können Sie den Status Ihrer Deployments und Services in Kubernetes effektiv überwachen und überprüfen und sicherstellen, dass Ihre Anwendungen wie erwartet ausgeführt werden.

Zugriff auf die Anwendung über kubectl proxy

In diesem Schritt lernen Sie, wie Sie mit kubectl proxy auf Ihre Kubernetes-Anwendungen zugreifen können. kubectl proxy erstellt eine sichere Proxy-Verbindung zum Kubernetes API-Server, wodurch Sie von Ihrer aktuellen Umgebung aus auf Cluster-Services und Pods zugreifen können. Dies ist sehr nützlich für die Entwicklung und Fehlersuche, insbesondere wenn Sie auf Dienste zugreifen möchten, die nicht extern verfügbar gemacht werden.

Stellen Sie zunächst sicher, dass Sie sich im Projektverzeichnis befinden:

cd ~/project/k8s-manifests/manifests

Starten Sie kubectl proxy im Hintergrund. Dieser Befehl führt den Proxy in einem separaten Prozess aus, sodass Sie Ihr Terminal weiterhin nutzen können.

kubectl proxy --port=8080 &

Das & am Ende des Befehls führt ihn im Hintergrund aus. Sie sollten eine Ausgabe wie diese sehen:

Starting to serve on 127.0.0.1:8080

Wenn Ihr Terminal nach Ausführung dieses Befehls hängt, müssen Sie möglicherweise einmal Ctrl+C drücken, um zur Eingabeaufforderung zurückzukehren. Der Proxy sollte weiterhin im Hintergrund laufen.

Lassen Sie uns nun die Namen der Pods ermitteln, die Teil Ihres web-app-Deployments sind. Sie können erneut kubectl get pods -l app=web verwenden:

## Get pod names for the 'web-app'
kubectl get pods -l app=web

Beispielausgabe:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          20m
web-app-xxx-zzz           1/1     Running   0          20m

Notieren Sie sich einen der Pod-Namen, z. B. web-app-xxx-yyy. Sie werden diesen Pod-Namen verwenden, um den API-Pfad zum Zugriff auf den NGINX-Webserver, der in diesem Pod läuft, zu erstellen.

Kubernetes-API-Ressourcen sind über bestimmte Pfade zugänglich. Um über kubectl proxy auf einen Pod zuzugreifen, müssen Sie eine URL wie diese erstellen:

http://localhost:8080/api/v1/namespaces/<namespace>/pods/<pod_name>/proxy/

Lassen Sie uns diese URL aufschlüsseln:

  • http://localhost:8080: Die Adresse, an der kubectl proxy läuft. Standardmäßig lauscht es im Port 8080 in Ihrer aktuellen Umgebung.
  • /api/v1: Gibt die Kubernetes-API-Version (v1) an.
  • /namespaces/<namespace>: Der Namespace, in dem Ihr Pod läuft. In unserem Fall ist es default.
  • /pods/<pod_name>: Der Name des Pods, auf den Sie zugreifen möchten. Ersetzen Sie <pod_name> durch den tatsächlichen Namen Ihres Pods (z. B. web-app-xxx-yyy).
  • /proxy/: Zeigt an, dass Sie eine Verbindung zum Pod weiterleiten möchten.

Um die Verwendung des Pod-Namens in der URL zu erleichtern, speichern wir den Namen des ersten Pods in einer Shell-Variable. Führen Sie diesen Befehl aus, der kubectl get pods und jsonpath verwendet, um den Namen des ersten Pods mit dem Label app=web zu extrahieren:

## Get the name of the first pod with label 'app=web'
POD_NAME=$(kubectl get pods -l app=web -o jsonpath='{.items[0].metadata.name}')
echo $POD_NAME ## Optional: print the pod name to verify

Nun können Sie die Variable $POD_NAME in Ihrem curl-Befehl verwenden, um auf die NGINX-Standardseite zuzugreifen, die von Ihrem Pod bereitgestellt wird. Verwenden Sie curl, um eine HTTP-Anfrage an die Proxy-URL zu senden. Ersetzen Sie ${POD_NAME} in der URL durch die gerade festgelegte Variable:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}/proxy/

Wenn alles korrekt funktioniert, sollte dieser Befehl den HTML-Inhalt der Standard-NGINX-Begrüßungsseite zurückgeben. Die Beispielausgabe ist HTML-Inhalt, der beginnt mit:

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    ...
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    ...
  </body>
</html>

Diese Ausgabe bestätigt, dass Sie erfolgreich auf den NGINX-Webserver zugegriffen haben, der über den kubectl proxy in Ihrem Pod läuft.

Lassen Sie uns ein paar weitere Dinge untersuchen, die Sie mit kubectl proxy tun können.

Auflisten aller Pods im Standard-Namespace über den Proxy:

Sie können direkt über den Proxy auf die Kubernetes-API zugreifen. Um beispielsweise alle Pods im default-Namespace aufzulisten, können Sie diese URL verwenden:

curl http://localhost:8080/api/v1/namespaces/default/pods/

Dies gibt eine JSON-Antwort zurück, die Informationen über alle Pods im default-Namespace enthält.

Detaillierte Informationen zu einem bestimmten Pod über den Proxy abrufen:

Um detaillierte Informationen zu einem bestimmten Pod zu erhalten (ähnlich wie bei kubectl describe pod), können Sie direkt auf den API-Endpunkt des Pods zugreifen:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}

Dies gibt eine JSON-Antwort mit detaillierten Informationen über den angegebenen Pod zurück.

Stoppen von kubectl proxy:

Wenn Sie mit der Verwendung von kubectl proxy fertig sind, sollten Sie es stoppen. Da wir es im Hintergrund gestartet haben, müssen Sie seine Prozess-ID (PID) finden und beenden. Sie können den Befehl jobs verwenden, um Hintergrundprozesse aufzulisten:

jobs

Dies zeigt die Hintergrundprozesse an, die von Ihrer aktuellen Terminalsitzung ausgeführt werden. Sie sollten kubectl proxy aufgelistet sehen. Um es zu stoppen, können Sie den Befehl kill gefolgt von der Prozess-ID verwenden. Wenn jobs beispielsweise [1] Running kubectl proxy --port=8080 & anzeigt, ist die Prozess-ID 1. Sie würden verwenden:

kill %1

Ersetzen Sie %1 durch die Job-ID, die vom jobs-Befehl angezeigt wird. Alternativ können Sie die Prozess-ID mit ps aux | grep kubectl proxy finden und dann kill <PID> verwenden.

Wichtige Punkte, die Sie sich über kubectl proxy merken sollten:

  • kubectl proxy erstellt eine sichere, authentifizierte Verbindung zum Kubernetes API-Server.
  • Es ermöglicht Ihnen den Zugriff auf Cluster-Ressourcen (Pods, Services usw.) von Ihrer aktuellen Umgebung aus, als ob Sie sich innerhalb des Cluster-Netzwerks befänden.
  • Es ist sehr nützlich für die Fehlersuche, Entwicklung und Erkundung der Kubernetes-API.
  • Aus Sicherheitsgründen ist kubectl proxy nur auf localhost (127.0.0.1) zugänglich. Es ist nicht dazu gedacht, Dienste öffentlich verfügbar zu machen.

Zusammenfassung

In diesem Lab haben Sie erfolgreich gelernt, wie Sie Anwendungen auf einem Kubernetes-Cluster mit Minikube bereitstellen. Sie haben mit der Einrichtung eines Kubernetes-Clusters mit Minikube begonnen und dessen Status überprüft. Anschließend haben Sie wichtige kubectl-Befehle zur Interaktion mit Ihrem Cluster und zur Verwaltung von Ressourcen kennengelernt. Sie haben gelernt, Namespaces aufzulisten, Details zu Nodes und Pods abzurufen und die grundlegende Befehlsstruktur von kubectl zu verstehen. Diese Schritte haben Ihnen eine solide Grundlage für die Arbeit mit Kubernetes vermittelt.

Sie haben dann einfache YAML-Manifeste für einen Pod und ein Deployment erstellt, diese mit kubectl apply auf Ihren Cluster angewendet und den Bereitstellungsstatus mit verschiedenen kubectl-Befehlen wie get und describe überprüft. Diese praktische Erfahrung ermöglichte es Ihnen, den deklarativen Ansatz zur Bereitstellung von Anwendungen auf Kubernetes zu verstehen und effektiv mit dem Cluster zu interagieren.

Schließlich haben Sie gelernt, wie Sie mit kubectl proxy auf Ihre bereitgestellte Anwendung zugreifen können, was eine sichere Möglichkeit bietet, mit der API Ihres Clusters zu interagieren und von Ihrer aktuellen Umgebung aus auf Dienste und Pods zuzugreifen. Dies ist eine wertvolle Technik für die Entwicklung, Fehlersuche und Erkundung Ihrer Kubernetes-Umgebung.

Durch den Abschluss dieses Labs haben Sie praktische Erfahrungen mit wichtigen Kubernetes-Konzepten und -Tools gesammelt und sind damit auf dem besten Weg, komplexere Anwendungen auf Kubernetes bereitzustellen und zu verwalten.