Aller au contenu principal

TP 3

Gérer des volumes, ConfigMaps, Secrets et appliquer des restrictions dans Kubernetes

Ce TP vise à expérimenter l'utilisation des volumes, ConfigMaps, Secrets ainsi qu'à ajouter des restrictions de sécurité et de ressources aux Pods dans Kubernetes.


0. Utiliser Exec

  • Action : Utiliser kubectl exec pour exécuter des commandes dans un Pod.
    Observation : Vous devez être capable d'accéder au shell du Pod pour exécuter des commandes internes.
    Indice
    Utiliser la commande kubectl exec -it [nom du pod] -- /bin/sh.

1. Un volume non persistant

  • Action : Monter un volume de type emptyDir dans un Pod et observer la suppression des données après la suppression du Pod.
    Votre volume doit être déclaré dans la section volumes et le pod doit utiliser ce volume dans la section volumeMounts de son YAML.
    Le volume doit être nommé myDir et être monté dans /data sur le pod.
    Observation : Les données créées dans le volume ne doivent pas être conservées après la suppression du Pod.

    Indice
    Un exemple est disponible dans la documentation kubernetes.
    Vérifiez la disparition du contenu du volume avec kubectl delete ... et kubectl apply .....
  • Action : Ajouter un initContainer qui écrit un timestamp dans le volume emptyDir, puis lire ce timestamp depuis le Pod principal.
    La commande du initContainer avec une image ubuntu:latest est date > /data/timestamp.txt.
    Observation : Le Pod principal doit afficher le timestamp écrit par l'initContainer.

    Indice
    . Utilisez kubectl exec pour lire le fichier.

Solution

Afficher
  • Utiliser kubectl exec pour accéder au shell du Pod : kubectl exec -it [nom du pod] -- /bin/sh
  • Monter un volume de type emptyDir avec un initContainer pour écrire un timestamp :
apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
spec:
initContainers:
- name: init-container
image: busybox
command: ["sh", "-c", "date > /data/timestamp.txt"]
volumeMounts:
- name: mydir
mountPath: /data
containers:
- name: app-container
image: ubuntu:latest
command: ["tail", "-f", "/dev/null"]
volumeMounts:
- name: mydir
mountPath: /data
volumes:
- name: mydir
emptyDir: {}
  • Afficher le timestamp : kubectl exec emptydir-pod -c app-container -- cat /data/timestamp.txt

2. Un volume persistant entre deux pods

  • Action : Lancer un Pod avec un volume de type PersistentVolume pour écrire des données dans un fichier.
    Il faut que vous fassiez un fichier qui contienne un PersistentVolumeClaim et le Pod qui fait référence à ce Claim.
    Le nom du pod est writer-pod et le nom du PersistentVolume est pv-claim.
    La storageClassName par défaut est utilisée, pas besoin de la spécifier.
    L'AccessMode du PersistentVolume est de typeReadWriteMany.
    La ligne de commande pour écrire est while true; do echo "$(date)" >> /data/timestamp.txt; sleep 5; done
    Observation : Vous devez voir un timestamp ajouté toutes les 5 secondes à la suite du fichier /data/timestamp.txt.

    Indice
    Un exemple est disponible dans la documentation officielle.
    Utiliser kubectl exec et la commande shell `while true; do echo "$(date)" >> /data/timestamp.txt; sleep 5; done`.
  • Action : Lancer un second Pod avec le même volume de type PersistentVolume pour lire les données créées par le premier Pod.
    Il faut que vous fassiez un fichier qui contienne uniquement le Pod qui fait référence au PersistentVolume créé précédemment.
    Sa commande doit être ["/bin/sh", "-c", "tail -f /data/timestamp.txt"]
    Observation : Vous devriez voir le contenu du fichier dans la sortie standard avec les nouvelles lignes ajoutées toutes les 5 secondes.

    Indice
    Utiliser kubectl logs ou kubectl exec pour lire le fichier avec la commande `tail -f /data/timestamp.txt`.

Solution

Afficher
  • Écrire des données dans un volume PersistentVolume :

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-claim
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi

---

apiVersion: v1
kind: Pod
metadata:
name: writer-pod
spec:
containers:
- name: writer
image: ubuntu:latest
command: ["/bin/sh", "-c", "while true; do echo $(date) >> /data/timestamp.txt; sleep 5; done"]
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: pv-claim
  • Lire les données dans un second Pod :
apiVersion: v1
kind: Pod
metadata:
name: reader-pod
spec:
containers:
- name: reader
image: ubuntu:latest
command: ["/bin/sh", "-c", "tail -f /data/timestamp.txt"]
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: pv-claim
  • Afficher le contenu depuis le second Pod : Utiliser kubectl logs reader-pod

3. Un volume de type ConfigMap

Redis est une base de données clef-valeur très rapide qu'on peut configurer avec un fichier.

# file: /etc/redis.conf
maxmemory 2mb
maxmemory-policy allkeys-lru
  • Action : Créer un ConfigMap pour la configuration du service Redis en utilisant le fichier d'exemple fourni.

    Observation : Le ConfigMap doit contenir les paramètres de configuration nécessaires au service Redis.

Indice
Utiliser kubectl create configmap --from-file pour créer et stocker la configuration.
  • Action : Appliquer et afficher le ConfigMap, puis l’utiliser dans un Pod Redis.
    Dans le manifeste, l'image est redis:latest.
    Le volume de type configMap est déclaré sous le nom de example-redis-config.
    Le fichier est monté dans /redis-master/redis.conf.
    La commande pour démarrer Redis est ["redis-server", "/redis-master/redis.conf"]
    Observation : Le Pod Redis doit démarrer avec la configuration fournie par le ConfigMap.
Indice
Un exemple complet est fourni dans la documentation officielle.

Solution

Afficher
  • Créer et utiliser un ConfigMap pour Redis : kubectl create configmap <nom_du_configmap> --from-file=<fichier_config> puis kubectl apply -f <configmap.yaml>.
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis.conf: |
maxmemory 2mb
maxmemory-policy allkeys-lru

---

apiVersion: v1
kind: Pod
metadata:
name: redis-pod
spec:
containers:
- name: redis
image: redis
command: ["redis-server", "/redis-master/redis.conf"]
volumeMounts:
- name: config-volume
mountPath: /redis-master
volumes:
- name: config-volume
configMap:
name: redis-config

  • Afficher la configuration de redis: kubectl exec -it redis-pod -- redis-cli config get maxmemory

4. Un volume de type secrets consommé via les variables d'environnement

  • Action : Créer un Secret en ligne de commande un secret pour les identifiants de connexion à une base de données Postgres.
    Le Secret nommé postgres-secret doit contenir les deux variables suivantes :
    POSTGRES_USER => user
    POSTGRES_PASSWORD => password
    Observation : Le secret apparaît dans la liste des secrets.
Indice
Un exemple est disponible dans la documentation officielle.
Utiliser kubectl create secret ... pour créer le Secret, puis vérifier son contenu avec kubectl describe secret ....
  • Action : Afficher et utiliser le Secret dans un Pod avec Postgres.
    Le pod utilise le secret créé précédemment et le déclare comme volume nommé Observation : Le Pod doit lire les identifiants depuis le Secret et démarrer correctement.
Indice

Utiliser kubectl describe secret pour afficher le Secret et l'associer au Pod Postgres.

Solution

Afficher
  • Créer un secret en ligne de commande : kubectl create secret generic postgres-secret --from-literal=POSTGRES_USER=user --from-literal=POSTGRES_PASSWORD=password
  • Utiliser un Secret pour Postgres consommé en variables d'environnement :
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
type: Opaque
data:
POSTGRES_USER: dXNlcg== # "user" en base64
POSTGRES_PASSWORD: cGFzc3dvcmQ= # "password" en base64

---

apiVersion: v1
kind: Pod
metadata:
name: postgres-pod
spec:
containers:
- name: postgres
image: postgres
env:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_PASSWORD

5. Configurer les ressources et les bases de sécurité des pods

Voici les deux actions manquantes pour le TP3 formatées selon le template de la phase 2 avec les solutions via des manifestes YAML. des restrictions de sécurité au Pod

  • Action : Ajouter des restrictions de sécurité à un Pod .
    Le pod est nommé stress-pod, il utilise l'image bretfisher/stress:latest avec la ligne de commande ["/bin/sh", "-c", "tail -f /dev/null"].
    Le conteneur du Pod doit être exécuté sous l'utilisateur 999 et le groupe 999, avec un système de fichiers en lecture seule (readOnlyRootFilesystem).
    Observation : Le contexte de sécurité doit être appliqué quand on se exec dans le pod et qu'on utilise la commande whoami.
Indice

Voir la >documentation officielle sur la sécurité des Pods. Utiliser les sections securityContext, runAsUser, runAsGroup, et readOnlyRootFilesystem dans le fichier YAML.

  • Action : Ajouter des restrictions de ressources (CPU, mémoire) au Pod.
    On utilise le même pod nommé stress-pod, qui utilise l'image bretfisher/stress:latest avec la ligne de commande ["/bin/sh", "-c", "tail -f /dev/null"].
    Le conteneur du Pod doit être configuré pour utiliser 500m de CPU et 100Mi de mémoire à la fois comme limite et comme demande (réservation).
    Observation : Les ressources doivent apparaître dans la description du pod et on peut faire crasher avec la commande stress --vm 1 --vm-bytes 200m
Indice

Voir la documentation officielle sur les ressources et les limites.
Utiliser les sections resources.limits et resources.requests dans le fichier YAML.

Solution

Afficher
  • Ajouter des restrictions de sécurité et de ressources (CPU, mémoire) au Pod :
apiVersion: v1
kind: Pod
metadata:
name: stress-pod
spec:
containers:
- name: stress-container
image: bretfisher/stress:latest
command: ["/bin/sh", "-c", "tail -f /dev/null"]
resources:
limits:
cpu: "500m"
memory: "100Mi"
requests:
cpu: "500m"
memory: "100Mi"
securityContext:
runAsUser: 999
runAsGroup: 999
readOnlyRootFilesystem: true

Avancé

  • Configurer les quotas de ressources au niveau du namespace et observer leur impact sur les Pods déployés.