Secrets - manipulation

Secrets - manipulation#

Dans cette section, vous allez manipuler un nouvel objet kubernetes : les secrets. Dans un premier temps, on verra comment les créer / modifier / observer, puis comment les utiliser en pratique pour injecter de l’information dans les pods.

Création d’un Secret via un manifest YAML#

Créez un fichier my-secret.yaml avec le contenu suivant :

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
stringData:
  username: "myuser"
  password: "mypassword123"
  CONF_VALUE1: "some-configuration-value"

Appliquez ensuite ce manifest pour créer le secret :

kubectl apply -f my-secret.yaml

Exercice : Vérification du contenu d’un secret

  1. Affichez le contenu du secret my-secret au format YAML.

    kubectl get secret my-secret -o yaml
    
  2. Copiez la valeur encodée en Base64 associée à la clé password.

  3. Décodez cette valeur pour vérifier qu’elle correspond bien au mot de passe original.

    # Remplacez <valeur_base64> par la valeur copiée
    echo '<valeur_base64>' | base64 --decode
    

Utilisation d’un Secret dans un Pod

Il y a deux manières principales d’utiliser un secret dans un pod : en tant que variables d’environnement ou en tant que fichiers montés dans un volume.

En tant que variables d’environnement (toutes les clés)

Créez un fichier pod-with-secret-env.yaml :

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-secret-env
spec:
  containers:
  - name: my-container
    image: ubuntu:22.04
    # La commande `env` affiche les variables, `sleep` maintient le pod en vie
    command: [ "/bin/sh", "-c", "env && sleep 3600" ]
    envFrom:
    - secretRef:
        name: my-secret
  restartPolicy: Never

Appliquez-le et observez les logs pour voir toutes les clés du secret apparaître comme variables d’environnement :

kubectl apply -f pod-with-secret-env.yaml
kubectl logs pod-with-secret-env

En tant que variable d’environnement (une seule clé)

Pour plus de contrôle, vous pouvez n’exposer que certaines clés. Créez pod-with-single-key-env.yaml :

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-single-key-env
spec:
  containers:
  - name: my-container
    image: ubuntu:22.04
    command: [ "/bin/sh", "-c", "env && sleep 3600" ]
    env:
      - name: MY_USERNAME
        valueFrom:
          secretKeyRef:
            name: my-secret
            key: username
  restartPolicy: Never

En tant que fichiers dans un volume

Créez un fichier pod-with-secret-volume.yaml :

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-secret-volume
spec:
  containers:
  - name: my-container
    image: ubuntu:22.04
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    volumeMounts:
    - name: secret-volume
      mountPath: "/etc/secret-files"
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: my-secret

Appliquez-le, puis listez et lisez les fichiers dans le pod :

kubectl apply -f pod-with-secret-volume.yaml
kubectl exec -it pod-with-secret-volume -- ls /etc/secret-files
# Affiche le contenu du fichier 'username'
kubectl exec -it pod-with-secret-volume -- cat /etc/secret-files/username

Exercice : Secret avec contenu multi-lignes (fichier HTML)

  1. Créez un fichier index.html localement :

    <!DOCTYPE html>
    <html>
    <head>
    <title>Test depuis un Secret!</title>
    </head>
    <body>
    <h1>Bonjour Kubernetes!</h1>
    <p>Cette page est servie depuis un secret Kubernetes.</p>
    </body>
    </html>
    
  2. Créez un secret à partir de ce fichier :

    kubectl create secret generic nginx-index --from-file=index.html --dry-run=client -o yaml > nginx-secret.yaml
    kubectl apply -f nginx-secret.yaml
    

    Remarquez qu’on utilise ici une fonctionnalité de kubectl de créer des objets en ligne de commande. Avec l’option --dry-run=client on demande à kubectl de ne pas créer l’objet mais juste de le montrer.

  3. Créez un pod Nginx nginx-pod.yaml qui monte ce secret et l’utilise comme page d’accueil.

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-secret-test
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        volumeMounts:
        - name: html-from-secret
          mountPath: /usr/share/nginx/html/index.html # On monte le fichier directement
          subPath: index.html
      volumes:
      - name: html-from-secret
        secret:
          secretName: nginx-index
    
  4. Appliquez ce manifest puis créez soit un service avec un NodePort ou un ingress pour pouvoir y accéder depuis votre navigateur.

Mise à jour des Secrets

Les secrets montés en volume sont mis à jour dynamiquement dans les pods (avec un léger délai). Cependant, les secrets utilisés comme variables d’environnement ne sont pas mis à jour après le démarrage du pod.

Une solution est donc de supprimer le pod et de le recréer. Avec les deployments, il suffira de supprimer le pod (et il sera recréé par le Deployment)