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
datagenau 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:
mountPathist genau die Datei, die NGINX als Startseite ausliefert.subPath: index.htmlbedeutet: „Mounte nur den Keyindex.htmlals einzelne Datei.“ OhnesubPathwürde Kubernetes das gesamte Verzeichnis/usr/share/nginx/htmldurch den ConfigMap-Inhalt ersetzen und alles andere löschen, was NGINX dort mitliefert.subPathlässt den Rest des Verzeichnisses unangetastet.name: nginx-index-volumeist 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:
volumes[].name(nginx-index-volume) muss identisch sein mit demnameuntervolumeMountsin Teil c. Das ist die Verbindung zwischen dem Mount des Containers und dem Volume des Pods.configMap.name(nginx-index-config) muss identisch sein mit demmetadata.nameder ConfigMap aus Schritt 1. Das ist es, was das Volume mit deinerindex.htmlfü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¶
- Die Einleitung hat Readiness-Checks erwähnt. Als Zusatzaufgabe: Füge einen
readinessProbehinzu, der einenhttpGetauf/(Port 80) macht, damit Kubernetes den Pod erst als ready markiert, wenn die Seite tatsächlich ausgeliefert wird. - https://kubernetes.io/docs/concepts/configuration/configmap/
- https://kubernetes.io/docs/concepts/storage/volumes/#configmap