Configurer des applications avec des Secrets

KubernetesBeginner
Pratiquer maintenant

Introduction

Les applications ont souvent besoin de valeurs qui ne devraient pas être placées directement dans une image de conteneur ou un manifeste en clair, comme des mots de passe, des jetons ou des identifiants de base de données. Les Secrets Kubernetes stockent ce type de configuration sensible en tant qu'objet distinct et permettent aux Pods de les consommer lors de leur démarrage.

Dans ce laboratoire, vous allez créer un Secret, inspecter attentivement ses données encodées, le connecter à un Pod d'application, mettre à jour le Secret et recréer le Pod afin que l'application lise les nouvelles valeurs. Ce laboratoire se concentre sur le flux de travail fondamental des Secrets. Les laboratoires ultérieurs permettront de pratiquer plus en détail la configuration des variables d'environnement et les montages de fichiers.

Préparer un espace de noms pour la pratique des Secrets

Dans cette étape, vous allez préparer un espace de noms propre pour vous entraîner avec les Secrets.

Commencez dans /home/labex/project. Vous rédigerez un manifeste de Pod dans ce répertoire.

mkdir -p /home/labex/project
cd /home/labex/project

Vérifiez que le serveur API Kubernetes est accessible. Si la machine virtuelle vient de démarrer et que le nœud n'est pas encore prêt, attendez quelques secondes et relancez la commande.

kubectl get nodes --request-timeout=5s

La sortie attendue inclut :

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Attendez que le Pod réseau du cluster soit prêt avant de créer des objets d'application.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Sortie attendue :

pod/calico-node-... condition met

Créez un espace de noms nommé ckad-prep-secrets :

kubectl create namespace ckad-prep-secrets

Définissez cet espace de noms comme espace de noms actuel pour le contexte :

kubectl config set-context --current --namespace=ckad-prep-secrets

Confirmez l'espace de noms actuel :

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Sortie attendue :

ckad-prep-secrets

Créer et inspecter un Secret

Dans cette étape, vous allez créer un Secret qui stocke les paramètres de connexion à une base de données pour une petite application.

La commande kubectl create secret generic crée un Secret opaque. generic signifie que Kubernetes n'attribue pas de signification intégrée particulière aux clés. Chaque drapeau --from-literal ajoute une paire clé-valeur au Secret.

kubectl create secret generic db-credentials \
  --from-literal=DB_USER=orders-app \
  --from-literal=DB_PASSWORD=dev-password-123 \
  --from-literal=DB_NAME=orders

Sortie attendue :

secret/db-credentials created

Inspectez le résumé du Secret :

kubectl get secret db-credentials

Sortie attendue :

NAME             TYPE     DATA   AGE
db-credentials   Opaque   3      ...

Affichez le Secret au format YAML. Kubernetes stocke les valeurs sous data sous forme de chaînes encodées en base64 ; vous ne devez donc pas vous attendre à voir le mot de passe original dans cette sortie.

kubectl get secret db-credentials -o yaml

La sortie attendue inclut :

data:
  DB_NAME: b3JkZXJz
  DB_PASSWORD: ...
  DB_USER: b3JkZXJzLWFwcA==
type: Opaque

L'encodage Base64 n'est pas un chiffrement. Quiconque peut lire l'objet Secret peut décoder ses valeurs. Décodez uniquement le nom d'utilisateur ici pour voir comment fonctionne la représentation sans afficher le mot de passe.

kubectl get secret db-credentials -o 'jsonpath={.data.DB_USER}' | base64 --decode; echo

Sortie attendue :

orders-app

Configurer un Pod à partir du Secret

Dans cette étape, vous allez démarrer un Pod qui lit le Secret sous forme de variables d'environnement.

Le champ envFrom.secretRef importe toutes les clés d'un Secret dans l'environnement du conteneur. C'est similaire au modèle ConfigMap utilisé dans le laboratoire précédent, mais les valeurs proviennent ici d'un objet Secret. La commande dans ce Pod affiche le nom d'utilisateur et le nom de la base de données, puis confirme simplement qu'un mot de passe a été chargé. Elle n'affiche pas le mot de passe lui-même.

Créez secret-reader-pod.yaml :

cat > secret-reader-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: secret-reader
  labels:
    app: secret-reader
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - name: reader
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'echo user=${DB_USER}; echo database=${DB_NAME}; if [ -n "${DB_PASSWORD}" ]; then echo password-loaded; fi; sleep 3600'
    envFrom:
    - secretRef:
        name: db-credentials
EOF

Appliquez le manifeste du Pod :

kubectl apply -f secret-reader-pod.yaml

Sortie attendue :

pod/secret-reader created

Attendez que le Pod soit prêt :

kubectl wait --for=condition=Ready pod/secret-reader --timeout=120s

Sortie attendue :

pod/secret-reader condition met

Lisez les journaux du Pod. L'application confirme que les valeurs du Secret étaient disponibles, mais la valeur du mot de passe n'est pas affichée.

kubectl logs secret-reader -c reader

Sortie attendue :

user=orders-app
database=orders
password-loaded

Mettre à jour le Secret et recréer le Pod

Dans cette étape, vous allez mettre à jour le Secret et recréer le Pod afin que le conteneur reçoive les nouvelles valeurs.

L'environnement d'un conteneur est capturé au moment de son démarrage. Si un Secret est consommé sous forme de variables d'environnement, la mise à jour de l'objet Secret ne réécrit pas l'environnement à l'intérieur d'un conteneur déjà en cours d'exécution. Démarrez un nouveau Pod lorsque l'application doit lire les valeurs mises à jour du Secret.

Appliquez un correctif (patch) au Secret avec un nouvel utilisateur d'application et un nouveau mot de passe :

kubectl patch secret db-credentials --type merge --patch '{"stringData":{"DB_USER":"orders-worker","DB_PASSWORD":"rotated-password-456","DB_NAME":"orders"}}'

Sortie attendue :

secret/db-credentials patched

Confirmez le nom d'utilisateur mis à jour en décodant uniquement DB_USER :

kubectl get secret db-credentials -o 'jsonpath={.data.DB_USER}' | base64 --decode; echo

Sortie attendue :

orders-worker

Supprimez l'ancien Pod :

kubectl delete pod secret-reader

La sortie attendue inclut :

pod "secret-reader" deleted

Recréez le Pod à partir du même manifeste et attendez qu'il soit prêt :

kubectl apply -f secret-reader-pod.yaml
kubectl wait --for=condition=Ready pod/secret-reader --timeout=120s

Sortie attendue :

pod/secret-reader created
pod/secret-reader condition met

Lisez à nouveau les journaux. Le nouveau Pod voit maintenant l'utilisateur mis à jour provenant du Secret et évite toujours d'afficher le mot de passe en clair.

kubectl logs secret-reader -c reader

Sortie attendue :

user=orders-worker
database=orders
password-loaded

Résumé

Vous avez créé un Secret Kubernetes, inspecté ses données encodées, décodé une clé non sensible pour comprendre la représentation, connecté le Secret à un Pod d'application et recréé le Pod après avoir mis à jour le Secret. Vous avez également pratiqué une habitude importante pour la configuration sensible : vérifier que l'application a bien reçu le mot de passe sans imprimer la valeur du mot de passe dans les journaux.