Konfiguration
Ziel
In diesem Projekt geht es um die Konfiguration von Pods. Sie werden:
- Umgebungsvariablen zu einem Pod Template hinzufügen
- Secrets erstellen und zu einer Umgebungsvariable hinzufügen
- ConfigMaps erstellen und zu einer Umgebungsvariable hinzufügen
Hilfsmittel
- Versuchen Sie, die unten stehenden Aufgaben mit Hilfe der Folien und des Cheatsheets eigenständig zu lösen.
- Sollten Sie dabei Probleme haben, finden Sie bei jeder Aufgabe einen ausklappbaren Block, in dem der Lösungsweg beschrieben wird.
- Umgebungsvariablen werden auch in der offiziellen Kubernetesdokumentation erklärt
- Die Verwendung von Umgebungsvariablen für die Konfiguration ist ein Prinzip, das auch in der 12factor app beschrieben wird.
- Secrets werden auch in der offiziellen Kubernetes-Dokumentation erklärt
- Verwendung von Secrets in Pods
- Verwaltung von Secrets auf der Kommandozeile mit kubectl
- ConfigMaps werden auch in der offiziellen Kubernetes-Dokumentation erklärt
Aufgabe 1: Umgebungsvariablen
- Erstellen Sie eine Datei
deployment.yaml
, die eine Beschreibung für eine Deployment mit dem Namenweb
enthält, die das Imagenginx
verwendet. Die Beschreibung des Deployments sollte die UmgebungsvariableFOO=bar
enthalten. - Fügen Sie ein Label
exercise: env
zu den Metadaten aller Objekte dieser Aufgabe hinzu, die am Ende bereinigt werden müssen.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
Das YAML-File deployment.yaml
sollte so oder so ähnlich aussehen:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
exercise: env
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx
env:
- name: FOO
value: bar
- Wenden Sie das Deployment an.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f deployment.yaml
- Betrachten Sie die Auswirkungen der Umgebungsvariable auf die Podbeschreibung.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
$ kubectl describe pods
(...)
Containers:
nginx:
Container ID: containerd://08ac0ded36e91e1c28f324203bde9db0af1b952272d91038b97889cb5d0ba218
Image: nginx
(...)
Environment:
FOO: bar
(...)
- Führen Sie eine Shell innerhalb des Pods aus und lassen Sie sich alle Umgebungsvariablen mit
printenv
anzeigen.FOO
sollte aufbar
gesetzt sein.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
Vermeiden Sie die direkte Verwendung des Pod-Namens und verwenden Sie stattdessen den Deployment-Namen. Auf diese Weise kann sich der Pod-Name ändern, ohne dass der Befehl unterbrochen wird:
$ kubectl exec -it deployment/web -- sh
$ printenv
(...)
FOO=bar
(...)
$ exit
$ kubectl exec -it deployment/web -- printenv | grep "FOO"
FOO=bar
- Ändern Sie den Wert der Umgebungsvariablen
FOO
inbaz
. Beobachten Sie, was passiert, wenn Sie die Änderungen mitwatch kubectl
anwenden.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Bearbeiten Sie die Datei
deployment.yaml
und ersetzen Sie die Zeilevalue: bar
durchvalue: baz
. - Öffnen Sie ein weiteres Terminal und führen Sie
watch kubectl get all
aus. - Wenden Sie das neue Deployment an:
kubectl apply -f deployment.yaml
-
Beobachten Sie, wie die Änderungen auf Deployments, ReplicaSets und Pods angewendet werden:
Das bestehende ReplicaSet wird durch ein neues ersetzt, das einen neuen Pod hervorbringt.$ watch kubectl get all NAME READY STATUS RESTARTS AGE pod/web-68d745b7bb-5r572 1/1 Running 0 4s pod/web-cd649748b-f2d72 1/1 Terminating 0 47m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/web 1/1 1 1 47m NAME DESIRED CURRENT READY AGE replicaset.apps/web-68d745b7bb 1 1 1 5s replicaset.apps/web-cd649748b 0 0 0 47m
-
Geben Sie den Wert der Variablen FOO aus:
$ kubectl exec -it deployment/web -- printenv | grep "FOO" FOO=baz
Aufgabe 2: Secrets
- Schauen Sie in die offizielle Dokumentation für Secrets.
- Erstellen Sie eine Datei
secret.yaml
, die die Beschreibung für ein Secret mit dem Namenmy-secret
enthält. Die geheimen Daten sollten eineSECRET_PHRASE
mit dem Wertabracadabra
enthalten. - Fügen Sie ein Label
exercise: secrets
zu den Metadaten hinzu.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- kodiere "abracadabra" in base64:
echo -n "abracadabra" | base64
- Erstelle eine YAML Datei
secret.yaml
mit folgendem Inhalt:Der Wert eines Secrets muss base64-kodiert sein. Je nach den Befehlen, die Sie für die Kodierung der Zeichenfolge verwenden, endet der Wert mitapiVersion: v1 kind: Secret metadata: name: my-secret labels: exercise: secrets type: Opaque data: SECRET_PHRASE: YWJyYWNhZGFicmE=
=
oderK
. Letzteres steht für die Zeichenkette einschließlich eines nachgestellten Zeilenumbruchs "n".
- Wenden Sie das Secret mit
kubectl apply
an.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f secret.yaml
- Schauen Sie sich die Liste der Secrets an und überprüfen Sie den Inhalt des Secrets auf mindestens zwei verschiedene Arten. Verwenden Sie die bekannten Unterbefehle für Untersuchungen, die Sie in früheren Übungen gelernt haben.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
-
Secrets auflisten:
$ kubectl get secrets NAME TYPE DATA AGE my-secret Opaque 1 106s
-
Beschreibung von "my-secret" anzeigen:
$ kubectl describe secret my-secret Name: my-secret Namespace: testnamespace Labels: <none> Annotations: <none> Type: Opaque Data ==== SECRET_PHRASE: 11 bytes
- YAML von "my-secret" anzeigen:
$ kubectl get secrets my-secret -o yaml apiVersion: v1 data: SECRET_PHRASE: YWJyYWNhZGFicmE= kind: Secret metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"SECRET_PHRASE":"YWJyYWNhZGFicmE="},"kind":"Secret","metadata":{"annotations":{},"name":"my-secret","namespace":"testnamespace"},"type":"Opaque"} creationTimestamp: "2024-02-22T10:19:41Z" name: my-secret namespace: testnamespace resourceVersion: "31789210" uid: eb4615ea-616d-47c7-a686-68592d633efc type: Opaque
- Verwenden Sie
kubectl
, um eine JSON-Darstellung des Geheimnisses abzurufen, und verwenden Siejq
, um den Wert des Secrets zu extrahieren. Verwenden Sie dannbase64
, um den Wert zu dekodieren.
jq und Bindestriche in JSON-Objektschlüsseln
Wenn der Schlüssel eines JSON-Objekts Bindestriche oder Leerzeichen enthält, müssen Sie Anführungszeichen um diesen Schlüssel in jq
-Selektoren verwenden:
echo '{ "data": { "mein-spezieller-schlüssel": "bingo" }}' | jq -r '.data. "mein-besonderer-schluessel"'
.data. "mein-spezial-schlüssel"
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
Geben Sie das Geheimnis im json-Format aus, leiten Sie es an jq
weiter, extrahieren Sie den Wert von SECRET_PHRASE
und base64-dekodieren Sie ihn:
$ kubectl get secrets my-secret -o json | jq -r '.data.SECRET_PHRASE' | base64 -d
abracadabra
- Erstellen Sie ein Deployment namens
web
indeployment2.yaml
unter Verwendung des Imagesnginx
, wie Sie es in der vorherigen Übung getan haben. - Erweitern Sie das Deployment und ordnen Sie das Secret einer Umgebungsvariablen
ENV_SECRET_PHRASE
zu und wenden Sie es mitkubectl apply
an. Überprüfen Sie anschließend die Umgebungsvariablen des Pods.
Referenzen für Secrets im Deployment
- Das Feld
valueFrom
wird verwendet, um auf das Kubernetes Secret Objekt zu verweisen. - Das Feld
SecretKeyRef
wird verwendet, um auf den Schlüssel innerhalb der Daten des Secret-Objekts zu verweisen.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Das YAML file
deployment.yaml
sollte so oder so ähnlich aussehen:apiVersion: apps/v1 kind: Deployment metadata: name: web labels: exercise: secrets spec: replicas: 1 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: web image: nginx env: - name: ENV_SECRET_PHRASE valueFrom: secretKeyRef: name: my-secret key: SECRET_PHRASE
- Wenden Sie das Deployment an:
kubectl apply -f deployment2.yaml
- Stellen Sie sicher, dass der Pod erstellt wurde:
$ kubectl get pods NAME READY STATUS RESTARTS AGE web-57cd799b47-7wvbs 1/1 Running 0 16s
- Untersuchen Sie die Umgebung des Containers im Pod:
$ kubectl describe pod web Name: web-57cd799b47-7wvbs (...) Containers: web: (...) Environment: ENV_SECRET_PHRASE: <set to the key 'SECRET_PHRASE' in secret 'my-secret'> Optional: false (...)
- Gibt die Umgebungsvariable aus, die das Secret enthält:
$ kubectl exec -it deployments/web -- printenv | grep ENV_SECRET_PHRASE ENV_SECRET_PHRASE=abracadabra
- Aktualisieren Sie das Secret mit einem neuen Wert und prüfen Sie die Auswirkungen auf den Pod.
Hinweis
Aktualisieren Sie entweder die Beschreibung und wenden Sie sie erneut an oder verwenden Sie kubectl edit secret
, um den Wert des Geheimnisses auf/in dem Pod zu ändern.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Verändern Sie den Wert von
SECRET_PHRASE
zurotated_secret
:sed -i "s/YWJyYWNhZGFicmE=/$(echo -n 'rotated_secret' | base64)/g" secret.yaml kubectl apply -f secret.yaml
- Überprüfen Sie ob die zugehörige Umgebungsvariable geändert wurde:
$ kubectl exec -it deployments/web -- printenv | grep ENV_SECRET_PHRASE ENV_SECRET_PHRASE=abracadabra
- Die Änderung wird erst bei der Neuerstellung des Pods berücksichtigt.
- Löschen Sie den Pod, der dann automatisch vom Deployment neu erstellt wird:
$ kubectl delete pods --selector app=web pod "web-57cd799b47-7wvbs" deleted $ kubectl exec -it deployments/web -- printenv | grep ENV_SECRET_PHRASE ENV_SECRET_PHRASE=rotated_secret
- Anstatt
spec.data
zu verwenden, nutzen Siespec.stringData
um ein unkodiertes Secret zu verwenden. Deployen und inspizieren Sie das neue Secret.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Erstellen Sie ein neues YAML file
secret-2.yaml
mit folgendem Inhalt:apiVersion: v1 kind: Secret metadata: name: my-secret-2 labels: exercise: secrets type: Opaque stringData: SECRET_PHRASE: "abracadabra"
- Wenden Sie das neue Secret an:
kubectl apply -f secret-2.yaml
- Inspizieren Sie das neue Secret:
Obwohl wir
kubectl get secrets my-secret-2 -o yaml apiVersion: v1 data: SECRET_PHRASE: YWJyYWNhZGFicmE= kind: Secret (...)
stringData
und einen Klartextwert bei der Beschreibung des Geheimnisses insecret-2.yaml
verwendet haben, wird bei der Anzeige des Secret-Objekts mitkubectl
der Wert als base64-kodierte Zeichenkette angezeigt.
Aufgabe 3: ConfigMaps
- Schauen Sie in die offizielle Dokumentation für ConfigMaps.
- Erstellen Sie eine Datei
configmap.yaml
, die die Beschreibung für eine ConfigMaps mit dem Namenmy-config
enthält. Die ConfigMap sollte sowohl ein einzeiliges wie auch ein mehrzeiliges Feld (heredoc) enthalten. Fügen Sie ein Labelexercise: configmaps
zu den Deployment-Metadaten hinzu.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Erstellen Sie eine YAML Datei
configmap.yaml
mit folgendem Inhalt:apiVersion: v1 kind: ConfigMap metadata: name: my-config labels: exercise: configmaps data: name: Ernie address: | Sesame Street 123 New York City
- Wenden Sie die ConfigMap mit
kubectl apply
an. Lassen Sie sich das Ergebnis anzeigen.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- ConfigMap anwenden:
kubectl apply -f configmap.yaml
- Überprüfen, dass die ConfigMap erstellt wurde:
$ kubectl get configmaps NAME DATA AGE my-config 2 44s
- Eigenschaften der ConfigMap inspizieren:
$ kubectl get configmap my-config -o yaml apiVersion: v1 data: address: | Sesame Street 123 New York City name: Ernie kind: ConfigMap (...)
- Mehr Beschreibung der ConfigMap anzeigen:
$ kubectl describe configmap my-config Name: my-config (...) Data ==== name: ---- Ernie address: ---- Sesame Street 123 New York City
- Erstellen Sie ein Deployment namens
env
indeployment3.yaml
unter Verwendung des Imagesnginx
(genau wie in der Deployment-Übung zuvor) - Ordnen Sie die ConfigMap-Daten den Umgebungsvariablen
ENV_NAME
undENV_ADDRESS
zu
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Erstellen Sie eine YAML Datei
deployment3.yaml
mit dem folgenden Inhalt:apiVersion: apps/v1 kind: Deployment metadata: name: web labels: exercise: configmaps spec: replicas: 1 selector: matchLabels: app: env template: metadata: name: web labels: app: env spec: containers: - name: web image: nginx env: - name: ENV_NAME valueFrom: configMapKeyRef: name: my-config key: name - name: ENV_ADDRESS valueFrom: configMapKeyRef: name: my-config key: address
- Wenden Sie es mit
kubectl apply
an. Inspizieren Sie die Umgebungsvariable des Pods.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Deployment anwenden:
kubectl apply -f deployment3.yaml
- Ergebnis anzeigen:
$ kubectl describe pod --selector app=env (...) Containers: env: (...) Environment: ENV_NAME: <set to the key 'name' of config map 'my-config'> Optional: false ENV_ADDRESS: <set to the key 'address' of config map 'my-config'> Optional: false
- Umgebungsvariable aus dem Container ausgeben und nach ENV_ suchen:
$ kubectl exec -it deployments/web -- printenv (...) ENV_NAME=Ernie ENV_ADDRESS=Sesame Street 123 New York City (...)
- Erstellen Sie ein Deployment mit dem Namen
envfrom
indeployment4.yaml
unter Verwendung des Imagesnginx
(ähnlich wie bei der vorherigen Aufgabe). - Bilden Sie alle Felder der ConfigMap auf Umgebungsvariablen ab.
envFrom
- Verwenden Sie
envFrom
anstelle vonenv
, um alle Felder der ConfigMap auf Umgebungsvariablen abzubilden. - Die in der ConfigMap verwendeten Schlüssel werden als Namen für die Umgebungsvariablen verwendet.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Erstellen Sie eine YAML Datei
deployment4.yaml
mit dem folgenden Inhalt:apiVersion: apps/v1 kind: Deployment metadata: name: web2 labels: exercise: configmaps spec: replicas: 1 selector: matchLabels: app: envFrom template: metadata: name: web2 labels: app: envFrom spec: containers: - name: envfrom image: nginx envFrom: - configMapRef: name: my-config
- Wenden Sie es mit
kubectl apply
an. Inspizieren Sie die Umgebungsvariable des Pods.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Deployment anwenden:
kubectl apply -f deployment4.yaml
- Ergebnis anzeigen:
$ kubectl describe pod --selector app=envFrom (...) Containers: envfrom: (...) Environment Variables from: my-config ConfigMap Optional: false Environment: <none> (...)
- Umgebungsvariablen aus dem Container ausgeben
$ kubectl exec -it deployments/web2 -- printenv (...) name=Ernie address=Sesame Street 123 New York City (...)
- Aktualisieren Sie die ConfigMap mit einem neuen Wert (z.B. Bert statt Ernie im Namen) und prüfen Sie die Auswirkungen auf den Pod.
Hinweis
- Aktualisieren Sie entweder die Beschreibung und wenden Sie sie erneut an, oder verwenden Sie
kubectl edit configmap
, um den Wert der ConfigMap auf/in dem Pod zu ändern.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Bearbeiten Sie die Datei
configmap.yaml
und ersetzen Sie die Zeilename: Ernie
durchname: Bert
- Übernehmen Sie die ConfigMap:
kubectl apply -f configmap.yaml
- Zeigen Sie die Umgebungsvariablen an:
$ kubectl exec -it deployments/web2 -- printenv (...) name=Ernie (...)
- Die Änderung wird erst bei der Neuerstellung des Pods berücksichtigt.
- Löschen Sie den Pod, der dann automatisch von Deployment: neu erstellt wird:
$ kubectl delete pods --selector app=envFrom pod "web-57cd799b47-7wvbs" deleted
- Zeigen Sie die Umgebungsvariablen an:
$ kubectl exec -it deployments/web2 -- printenv (...) name=Bert (...)
Bonus: MySQL deployen, ohne Credentials bereitzustellen
- Erstellen Sie eine Beschreibung für ein Deployment namens
db
indb.yaml
unter Verwendung des Imagesmysql
einschließlich der UmgebungsvariablenMYSQL_RANDOM_ROOT_PASSWORD=yes
. Setzen Sie es mitkubectl apply
um. Nutzen Sie als Labelexercise: env
.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- The YAML file
db.yaml
should look similar to the following:apiVersion: apps/v1 kind: Deployment metadata: name: db labels: exercise: env spec: replicas: 1 selector: matchLabels: app: db template: metadata: labels: app: db spec: containers: - name: mysql image: mysql:5 env: - name: MYSQL_RANDOM_ROOT_PASSWORD value: "yes"
- Das MySQL-Deployment anwenden:
kubectl apply -f db.yaml
- Lassen Sie sich das Ergebnis mit
kubectl get
,kubectl describe
undkubectl logs
anzeigen.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Die Container Logs anzeigen:
kubectl logs deployments/db
- Führen Sie eine Shell innerhalb des Pods aus und zeigen Sie alle Umgebungsvariablen mit
printenv
an. Prüfen Sie, ob die VariableMYSQL_RANDOM_ROOT_PASSWORD
aufyes
gesetzt ist.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Den Wert von MYSQL_RANDOM_ROOT_PASSWORD ausgeben:
$ kubectl exec -it deployment/db -- printenv | grep "MYSQL_RANDOM_ROOT_PASSWORD" MYSQL_RANDOM_ROOT_PASSWORD=yes
Cleanup
- Löschen Sie alle Objekte, die wir mit
kubectl delete
erstellt haben, indem Sie den Label-Selektor für diese speziellen Übungen verwenden. - Beobachten Sie, wie sie mit
watch kubectl get all
verschwinden.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete deployments --selector exercise=env
kubectl delete deployments --selector exercise=secrets
kubectl delete secrets --selector exercise=secrets
kubectl delete deployments --selector exercise=configmaps
kubectl delete configmaps --selector exercise=configmaps