Zum Inhalt

Lab 12: Konfigurationsdateien mit ConfigMaps ausliefern

Es ist durchaus üblich, kompakte und statische Dateien in ConfigMaps abzulegen und Pods zur Verfügung zu stellen. In diesem Beispiel nutzen wir eine ConfigMap, um eine Startseite für einen NGINX-Pod auszuliefern. In der Realität könnte dies eine Seite sein, auf die der Readiness-Check prüft.

Dies ist ein Selbstbau-Lab: Die ConfigMap bekommst du geschenkt, aber das Pod-YAML schreibst du selbst. Die folgende Anleitung führt dich Stück für Stück hindurch. Ganz unten findest du eine vollständige Lösung, falls du nicht weiterkommst.

Schritt 1: ConfigMap anlegen

Die ConfigMap mit der HTML-Seite sieht wie folgt aus:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-index-config
data:
  index.html: |
    <html>
    <head>
        <title>Willkommen bei NGINX</title>
    </head>
    <body>
        <h1>Hallo, Welt!</h1>
        <p>Dies ist eine benutzerdefinierte Startseite für den NGINX-Server.</p>
    </body>
    </html>

Speichere sie in einer Datei (zum Beispiel configmap.yaml) und wende sie an:

kubectl apply -f configmap.yaml

Merke dir zwei Dinge, auf die du dich später beziehst:

  • Die ConfigMap heißt nginx-index-config (metadata.name).
  • Sie hat unter data genau einen Key, index.html. Dieser Key-Name wird beim Mounten zum Dateinamen.

Schritt 2: Den Pod bauen

Schreibe nun ein Pod-YAML (zum Beispiel pod.yaml) für einen NGINX-Pod, der die index.html aus der ConfigMap als Startseite ausliefert. Der Pod besteht aus vier Teilen. Baue sie in dieser Reihenfolge auf.

a) Der Pod und sein Label

Beginne mit dem Grundgerüst. Wichtig ist neben dem üblichen metadata.name vor allem das Label — der Service, den du in Schritt 3 anlegst, findet den Pod darüber, es muss also vorhanden sein:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx        # der Service selektiert auf dieses Label
spec:
  containers:
    # ... Container kommt hierhin (Teil b) ...
  volumes:
    # ... Volume kommt hierhin (Teil d) ...

b) Der NGINX-Container

Füge innerhalb von spec.containers einen einzelnen Container hinzu, der NGINX ausführt und Port 80 freigibt:

- name: nginx
  image: nginx:1.29.4
  ports:
    - containerPort: 80

c) Die Datei mounten (volumeMounts)

Füge weiterhin innerhalb des Containers einen volumeMounts-Eintrag hinzu. Dies ist der Teil, den du als Vorlage bekommen hast:

volumeMounts:
  - name: nginx-index-volume
    mountPath: /usr/share/nginx/html/index.html
    subPath: index.html

Was jede Zeile bewirkt:

  • mountPath ist genau die Datei, die NGINX als Startseite ausliefert.
  • subPath: index.html bedeutet: „Mounte nur den Key index.html als einzelne Datei.“ Ohne subPath würde Kubernetes das gesamte Verzeichnis /usr/share/nginx/html durch den ConfigMap-Inhalt ersetzen und alles andere löschen, was NGINX dort mitliefert. subPath lässt den Rest des Verzeichnisses unangetastet.
  • name: nginx-index-volume ist eine Referenz — sie zeigt auf ein Volume, das du noch deklarieren musst. Das ist Teil d.

d) Das Volume deklarieren (volumes)

volumeMounts referenziert ein Volume nur über seinen Namen; du musst dieses Volume zusätzlich auf Pod-Ebene unter spec.volumes deklarieren. Dies ist der Block, der alles mit der ConfigMap verbindet:

volumes:
  - name: nginx-index-volume        # muss zu volumeMounts[].name aus Teil c passen
    configMap:
      name: nginx-index-config      # muss zum metadata.name der ConfigMap aus Schritt 1 passen

An den beiden Namens-Übereinstimmungen geht dieses Lab am häufigsten schief, prüfe sie also sorgfältig:

  1. volumes[].name (nginx-index-volume) muss identisch sein mit dem name unter volumeMounts in Teil c. Das ist die Verbindung zwischen dem Mount des Containers und dem Volume des Pods.
  2. configMap.name (nginx-index-config) muss identisch sein mit dem metadata.name der ConfigMap aus Schritt 1. Das ist es, was das Volume mit deiner index.html füllt.

Setze die Teile a–d zu einem pod.yaml zusammen und wende es an:

kubectl apply -f pod.yaml

Prüfe, dass der Pod hochkommt:

kubectl get pod nginx-pod

Sobald er Running ist, geht es weiter mit dem Exposen.

Schritt 3: Den Pod mit einem Service exposen

Für Minikube

Erstelle einen NodePort-Service namens nginx-service, der auf den Pod weiterleitet. Öffne dann einen Tunnel dorthin und prüfe, ob die HTML-Seite erscheint:

minikube service nginx-service

Für EKS und AKS

Lege einen Service vom Typ LoadBalancer namens nginx-service an, der mittels Labels auf den Pod weiterleitet:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
  type: LoadBalancer

Wichtig: Der Selector (app: nginx) muss zu dem Label passen, das du in Teil a auf den Pod gesetzt hast. Wenn die Seite nie lädt, ist ein nicht passender Selector das Erste, was du prüfen solltest.

Frage anschließend die externe IP des LoadBalancers ab:

kubectl get svc nginx-service

Es kann eine kurze Weile dauern, bis die externe IP provisioniert ist.

Aufräumen

kubectl delete pod nginx-pod
kubectl delete service nginx-service
kubectl delete configmap nginx-index-config

Vollständige Lösung

Versuche zuerst, den Pod selbst zusammenzubauen. Wenn du nicht weiterkommst, hier ein komplettes pod.yaml zum Abgleichen.

pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.29.4
      ports:
        - containerPort: 80
      volumeMounts:
        - name: nginx-index-volume
          mountPath: /usr/share/nginx/html/index.html
          subPath: index.html
  volumes:
    - name: nginx-index-volume
      configMap:
        name: nginx-index-config

Bonus