01Les variables : ConfigMap
Une ConfigMap regroupe des paires clé et valeur non sensibles. Le Deployment les injecte en variables d'environnement :
apiVersion: v1
kind: ConfigMap
metadata:
name: boutique-config
data:
APP_ENV: production
APP_URL: https://boutique-mon-equipe.demo.k8s.exemple.fr
LOG_LEVEL: info
---
# dans le Deployment, sous le conteneur
envFrom:
- configMapRef: { name: boutique-config }
Une variable modifiée n'atteint pas les pods déjà lancés : relancez-les avec
kubectl rollout restart deploy/boutique. Une ConfigMap peut aussi être montée
comme fichier, pour un nginx.conf ou un config.yaml.
02Les mots de passe : Secret
Un Secret s'utilise comme une ConfigMap, mais son contenu est réservé aux comptes qui en ont le droit et n'apparaît pas dans les affichages par défaut. Créez-le en ligne de commande, pour qu'il ne finisse jamais dans un fichier versionné :
read -rs API_KEY # saisie masquée, rien dans l'historique
kubectl create secret generic boutique-secrets \
--from-literal=DB_PASSWORD="$(openssl rand -base64 24)" \
--from-literal=API_KEY="$API_KEY"
unset API_KEY
# dans le Deployment
envFrom:
- configMapRef: { name: boutique-config }
- secretRef: { name: boutique-secrets }
Le contenu d'un Secret est encodé en base64, pas chiffré : toute personne qui a le droit de le lire le lit en clair. N'écrivez jamais un Secret dans un manifeste versionné. Le chapitre 07 montre comment les gérer avec Git sans les exposer.
03Les données : volumes persistants
Un conteneur perd ses fichiers à chaque redémarrage. Pour les fichiers envoyés par les utilisateurs, un cache à garder ou une petite base, demandez un volume :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: boutique-data
spec:
accessModes: [ReadWriteOnce]
resources:
requests: { storage: 5Gi }
---
# dans le Deployment
spec:
containers:
- name: web
volumeMounts:
- { name: data, mountPath: /data }
volumes:
- name: data
persistentVolumeClaim: { claimName: boutique-data }
Le volume est un disque Ceph répliqué trois fois, sauvegardé chaque nuit. Il est en
ReadWriteOnce : un seul serveur le monte à la fois. Un Deployment qui l'utilise
reste donc à replicas: 1, avec la stratégie Recreate pour que
l'ancien pod libère le disque avant que le nouveau le réclame :
spec:
replicas: 1
strategy:
type: Recreate
Besoin de plus de place ? Augmentez storage dans le PVC et réappliquez : le
volume grandit à chaud. Il ne rétrécit jamais, en revanche.
04Et les bases de données ?
Une base de données tourne très bien dans le cluster, avec son volume. Trois précautions :
- Un StatefulSet plutôt qu'un Deployment pour une base : nom stable, volume attaché à son pod.
- Une vraie sauvegarde. La sauvegarde nocturne de la plateforme copie le
disque à chaud, « comme après une coupure de courant » : suffisant pour un test, pas pour des
données de production. Ajoutez une sauvegarde native (
pg_dump,mysqldump) planifiée par unCronJob, ou demandez une base gérée par l'administrateur. - Une seule copie, sauf à mettre en place la réplication de la base elle-même. Deux pods sur le même volume, c'est la corruption assurée.
05Les images privées
read -rs JETON
kubectl create secret docker-registry regcred \
--docker-server=registry.gitlab.com \
--docker-username=deploy-token-boutique \
--docker-password="$JETON"
unset JETON
# dans le Deployment, sous spec.template.spec
imagePullSecrets:
- name: regcred
Utilisez un jeton de déploiement en lecture seule, propre à l'application, plutôt que votre mot de passe personnel : il se révoque sans casser le reste de votre vie.
Vous codez, nous veillons sur le cluster
Cette plateforme existe pour que vos développeurs déploient sans attendre personne et sans ticket. Nous l'hébergeons et l'exploitons pour vous : réseau, certificats, sauvegardes, mises à jour et surveillance des attaques. Il vous reste le plus intéressant.