Cours de virtualisation avancée: Kubernetes, suite

1. S'attacher à un pod

kubectl exec -it <nom pod> -- /bin/bash

2. Récupérer les logs d'un pod

kubectl logs <nom pod>

3. Stocker des configurations

3.1. ConfigMap

doc

  • Utilisé pour stocker des couples clef-valeurs
  • Données non protégées

Utilisé par exemple pour stocker la configuration d'une application

3.1.1. Créer une ConfigMap

apiVersion: v1 
kind: ConfigMap  # un nouveau type
  metadata:
    name: my-app-config # on lui met un nom
  data:  # puis une liste de clefs-valeurs
    database_uri: mongodb://localhost:27017

3.1.2. Utiliser une ConfigMap

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
    - name: test-container
      image: my-image
      env:
        - name: DATABASE_URI
          valueFrom:
            configMapKeyRef:
              name: my-app-config
              key: database_uri

Ici, nous indiquons où aller chercher les valeurs pour les variables d’environnement.

4. Stocker des fichiers

Consultez ce guide de la doc

  • Plusieurs méthodes:
    • Statique: en local sur les nœuds;
    • Dynamique: en utilisant un serveur distant, par ex NFS, Ceph ou autre.
  • Étapes:
    • Créer un espace ou un contrôleur de stockage;
    • Créer une "demande de stockage";
    • Attacher ce stockage à un Pod.
  • L'administrateur du cluster doit configurer des espaces de stockage ou des contrôleurs pour les rendre disponible
  • Si on fait une demande de stockage et qu'elle ne peut pas être remplie, elle reste en attente jusqu’à ce qu'elle puisse être remplie

Par exemple, si je demande un volume de 10G mais que l'administrateur n'a rendu disponible que des volumes de 5G, il faudra que j'attende qu'un volume de 10G soit disponible, sinon, je dois me contenter de 5G.

5. Méthode statique

5.1. PersistentVolume (PV)

  • Permet de rendre disponible au cluster un espace de stockage;
  • Attention, ce stockage ne sera pas directement accessible par les pods.

5.1.1. Créer un PersistentVolume

doc

apiVersion: v1
kind: PersistentVolume  # un nouveau type
metadata:
  name: pv-volume
  labels:
    type: local
spec:
  storageClassName: manual  # la classe du stockage
  capacity:
    storage: 10Gi  # la taille du volume
  accessModes:
    - ReadWriteOnce
  hostPath:  # on veut stocker sur le nœud physique
    path: "/mnt/data"  # son emplacement sur le nœud

Vérifications:

❯ kubectl get pv pv-volume
NAME       CAPACITY   ACCESSMODES   ...   STATUS      STORAGECLASS
pv-volume  10Gi       RWO           ...   Available   manual
  • Cette configuration rendra disponible 1 volume de 10G, qui pourra ensuite être utilisé avec PersistentVolumeClaim;
  • storageClassName: manual indique que nous utilisons un stockage "statique";
  • ReadwriteOnce indique que seul un nœud pourra monter ce stockage, il sera donc disponible uniquement pour les Pods tournant sur ce nœud.

5.2. PersistentVolumeClaim (PVC)

Permet à un Pod de demander l'accès au stockage

5.2.1. Créer un PersistentVolumeClaim

doc

apiVersion: v1
kind: PersistentVolumeClaim  # un nouveau type
metadata:
  name: app-pv-claim  # un nom
spec:
  storageClassName: manual  # la classe du stockage
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi  # la taille demandée

Vérifications:

❯ kubectl get pvc app-pv-claim
NAME            STATUS    VOLUME     CAPACITY   ACCESSMODES   STORAGECLASS   AGE
app-pv-claim    Bound     pv-volume  10Gi       RWO           manual         30s

5.3. Utiliser ce stockage dans un Pod

5.3.1. Créer le Pod

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  volumes:
    - name: my-app-storage  # un nom pour le volume
      persistentVolumeClaim:
        claimName: app-pv-claim  # le nom du "claim" à utiliser
  containers:
    - name: my-app
      image: nginx
      ports:
        - containerPort: 80
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"  # point de montage dans le /pod/
          name: my-app-storage  # nom du stockage

6. Méthode dynamique

  • Il faut que l'admin ait configuré un contrôleur de stockage dynamique, avec NFS par exemple.

6.1. PersistentVolumeClaim (PVC)

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-claim
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  resources:
    requests:
      storage: 10Gi
  • ReadWriteMany indique que ce PVC pourra être monté dans plusieurs Pods
  • storageClassName: nfs indique que nous allons utiliser la classe de stockage NFS

6.2. Utilisation dans un Pod

  • Exactement comme vu avant, il faut cependant changer le nom du PVC utilisé

7. La sécurité au sein de K8s

7.1. De bonnes pratiques Docker

7.1.1. Définir un utilisateur

  • Par défaut, votre application conteneurisée sera lancée en root dans le conteneur.
  • Il faut créer un autre utilisateur et indiquer à Docker de l’utiliser avant de déclarer la commande ou le point d'entrée

Un Dockerfile:

FROM debian

# ...

RUN useradd test
USER test

# CMD / ENTRYPOINT

7.1.2. Multi-stage build

doc

  • Permet de n'embarquer que l'application donc sans ses dépendances de build.
  • Réduit la taille de l'image finale.
  • Réduit la surface d'attaque en limitant le nombre de paquets intégrés.

Un Dockerfile:

FROM debian as builder
RUN apt install -y nodejs npm
RUN npm install && npm run build

FROM nginx
COPY --from=builder /app/dist/html /var/www/html

7.2. Des outils spécifiques à K8S

7.2.1. Trivy

  • Permet de lister les vulnérabilités connues dans les Pods
  • Permet de lister les vulnérabilités dues à la configuration du cluster
trivy k8s --report=summary

trivy k8s --severity=CRITICAL --report=all

8. Aller plus loin