
Podman kube permet de tester des manifests Kubernetes localement, sans cluster. Vous pouvez aussi générer des YAML depuis vos conteneurs existants. C’est idéal pour valider vos manifests avant de les déployer sur un vrai cluster.
À la fin de ce guide, vous saurez :
- Lancer des pods depuis des YAML Kubernetes
- Générer des manifests depuis des conteneurs existants
- Itérer rapidement : generate → edit → play
- Nettoyer proprement avec
kube down
Droit au but
Section intitulée « Droit au but »Pourquoi utiliser kube play ?
Section intitulée « Pourquoi utiliser kube play ? »Le problème : tester un YAML sans cluster
Section intitulée « Le problème : tester un YAML sans cluster »Vous avez un manifest Kubernetes et vous voulez le tester :
- Sans installer Minikube ou Kind
- Sans déployer sur un cluster de dev
- Rapidement, pour valider la syntaxe et le comportement
La solution : podman kube play
Section intitulée « La solution : podman kube play »podman kube play lit un fichier YAML Kubernetes et crée les ressources localement avec Podman.
Ce qui est supporté
Section intitulée « Ce qui est supporté »Podman ne simule pas un cluster Kubernetes complet — il se concentre sur les ressources que vous pouvez tester localement sans orchestrateur. Les ressources de type “réseau” (Services, Ingress) ne sont pas supportées car elles dépendent d’un control plane Kubernetes.
| Ressource | Supporté | Notes |
|---|---|---|
| Pod | ✅ | Complet |
| Deployment | ✅ | Crée les pods |
| DaemonSet | ✅ | Crée un pod |
| ConfigMap | ✅ | Monté comme fichiers ou envvars |
| Secret | ✅ | Monté comme fichiers ou envvars |
| PersistentVolumeClaim | ✅ | Crée un volume Podman |
| Service | ❌ | Utilisez les ports du pod |
| Ingress | ❌ | Non supporté |
| NetworkPolicy | ❌ | Non supporté |
kube play : lancer un YAML
Section intitulée « kube play : lancer un YAML »Syntaxe de base
Section intitulée « Syntaxe de base »podman kube play <fichier.yaml>Premier exemple
Section intitulée « Premier exemple »-
Créer un manifest simple
nginx-pod.yaml apiVersion: v1kind: Podmetadata:name: nginx-weblabels:app: nginxspec:containers:- name: nginximage: docker.io/library/nginx:alpineports:- containerPort: 80hostPort: 8080 -
Lancer avec kube play
Fenêtre de terminal podman kube play nginx-pod.yamlRésultat Pod:nginx-webContainer:nginx-web-nginx -
Vérifier
Fenêtre de terminal podman pod psRésultat POD ID NAME STATUS CREATED # OF CONTAINERSabc123def456 nginx-web Running 10 seconds ago 2 -
Tester
Fenêtre de terminal curl http://localhost:8080
Exemple avec Deployment
Section intitulée « Exemple avec Deployment »apiVersion: apps/v1kind: Deploymentmetadata: name: web-appspec: replicas: 2 # Crée 2 pods selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: web image: docker.io/library/nginx:alpine ports: - containerPort: 80podman kube play deployment.yamlOptions utiles de kube play
Section intitulée « Options utiles de kube play »Les options les plus utiles permettent de contrôler le réseau, de charger des ConfigMaps externes, et surtout d’itérer rapidement avec --replace.
| Option | Description | Exemple |
|---|---|---|
--network | Réseau à utiliser | --network my-net |
--configmap | Charger un ConfigMap externe | --configmap cm.yaml |
--start | Démarrer les pods (défaut: true) | --start=false |
--replace | Remplacer les pods existants | --replace |
--down | Alias pour kube down | (voir section dédiée) |
kube generate : créer un YAML
Section intitulée « kube generate : créer un YAML »Le cas d’usage
Section intitulée « Le cas d’usage »Vous avez des conteneurs qui fonctionnent avec podman run. Vous voulez les “exporter” en YAML Kubernetes pour :
- Les versionner dans Git
- Les déployer ailleurs
- Les transformer en vraies ressources Kubernetes
# Depuis un conteneurpodman kube generate <container-name> > pod.yaml
# Depuis un podpodman kube generate <pod-name> > pod.yamlExemple : conteneur simple
Section intitulée « Exemple : conteneur simple »# Créer un conteneurpodman run -d --name my-nginx -p 8080:80 nginx:alpine
# Générer le YAMLpodman kube generate my-nginxapiVersion: v1kind: Podmetadata: name: my-nginx-pod labels: app: my-nginx-podspec: containers: - name: my-nginx image: docker.io/library/nginx:alpine ports: - containerPort: 80 hostPort: 8080Exemple : pod complet
Section intitulée « Exemple : pod complet »# Créer un pod avec plusieurs conteneurspodman pod create --name api-stack -p 8080:80podman run -d --pod api-stack --name nginx nginx:alpinepodman run -d --pod api-stack --name redis redis:alpine
# Générer le YAMLpodman kube generate api-stack > api-stack.yamlLe YAML généré contient les deux conteneurs dans le même pod.
Options de kube generate
Section intitulée « Options de kube generate »Deux options principales : écrire directement dans un fichier (-f) ou générer aussi un Service Kubernetes (-s) pour faciliter la transition vers un vrai cluster.
| Option | Description | Exemple |
|---|---|---|
-f, --filename | Écrire dans un fichier | -f pod.yaml |
-s, --service | Générer aussi un Service | -s |
# Générer Pod + Servicepodman kube generate my-nginx -sWorkflow d’itération
Section intitulée « Workflow d’itération »Le workflow typique est :
Démonstration
Section intitulée « Démonstration »-
Prototyper avec le CLI
Fenêtre de terminal # Créer le pod manuellementpodman pod create --name demo -p 8080:80podman run -d --pod demo --name app nginx:alpine -
Générer le YAML
Fenêtre de terminal podman kube generate demo > demo.yaml -
Éditer le YAML
Ajoutez des ressources, des variables d’environnement, etc.
demo.yaml (édité) apiVersion: v1kind: Podmetadata:name: demospec:containers:- name: appimage: docker.io/library/nginx:alpineports:- containerPort: 80hostPort: 8080resources:limits:memory: "128Mi"cpu: "500m"env:- name: ENVvalue: "production" -
Supprimer l’ancien pod
Fenêtre de terminal podman pod rm -f demo -
Relancer avec le YAML modifié
Fenêtre de terminal podman kube play demo.yaml -
Vérifier les changements
Fenêtre de terminal podman inspect demo-app --format '{{.Config.Env}}'# [ENV=production ...]
L’option —replace
Section intitulée « L’option —replace »Pour éviter de supprimer manuellement le pod :
# Première foispodman kube play demo.yaml
# Modifications...
# Remplacer directementpodman kube play --replace demo.yamlkube down : nettoyer proprement
Section intitulée « kube down : nettoyer proprement »podman kube down <fichier.yaml>Ce que kube down supprime
Section intitulée « Ce que kube down supprime »kube down est conservateur par défaut : il supprime les pods et conteneurs, mais préserve les volumes pour éviter toute perte de données accidentelle. Utilisez --force uniquement si vous voulez un nettoyage complet.
| Ressource | Supprimée ? | Notes |
|---|---|---|
| Pods | ✅ | Toujours |
| Conteneurs | ✅ | Tous les conteneurs du pod |
| Volumes créés par le YAML | ⚠️ | Seulement avec --force |
| Réseaux | ❌ | Non supprimés |
# Créerpodman kube play demo.yaml
# Vérifierpodman pod ps
# Supprimerpodman kube down demo.yamlPods stopped:demoPods removed:demoSupprimer les volumes aussi
Section intitulée « Supprimer les volumes aussi »Par défaut, kube down préserve les volumes (pour ne pas perdre de données).
# Supprimer pods + volumespodman kube down --force demo.yamlVérifier ce qui reste après kube down
Section intitulée « Vérifier ce qui reste après kube down »# Vérifier les pods (devrait être vide)podman pod ps
# Vérifier les volumes (peuvent rester)podman volume ls
# Nettoyer manuellement les volumes orphelinspodman volume pruneConfigMaps et Secrets
Section intitulée « ConfigMaps et Secrets »ConfigMap
Section intitulée « ConfigMap »apiVersion: v1kind: ConfigMapmetadata: name: app-configdata: app.conf: | server { listen 80; } LOG_LEVEL: debug---apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx:alpine volumeMounts: - name: config-volume mountPath: /etc/nginx/conf.d env: - name: LOG_LEVEL valueFrom: configMapKeyRef: name: app-config key: LOG_LEVEL volumes: - name: config-volume configMap: name: app-config items: - key: app.conf path: default.confpodman kube play config.yamlapiVersion: v1kind: Secretmetadata: name: db-secrettype: Opaquedata: password: cGFzc3dvcmQxMjM= # base64 encoded---apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx:alpine env: - name: DB_PASSWORD valueFrom: secretKeyRef: name: db-secret key: passwordEncoder un secret en base64 :
echo -n 'password123' | base64# cGFzc3dvcmQxMjM=Lab : workflow complet
Section intitulée « Lab : workflow complet »Objectif : créer une stack API avec nginx + backend, la transformer en YAML, et itérer.
-
Créer la stack avec des commandes
Fenêtre de terminal # Créer le podpodman pod create --name api-demo -p 8080:80# Backend (simule une API)podman run -d --pod api-demo --name backend \python:3.12-alpine python -m http.server 3000# Frontend (nginx)podman run -d --pod api-demo --name frontend \nginx:alpine -
Vérifier que ça fonctionne
Fenêtre de terminal # Étatpodman pod pspodman ps --pod# Testcurl http://localhost:8080 -
Générer le YAML
Fenêtre de terminal podman kube generate api-demo > api-demo.yamlcat api-demo.yaml -
Éditer le YAML
Ajoutez des variables d’environnement, des labels, etc.
-
Supprimer et recréer
Fenêtre de terminal podman pod rm -f api-demopodman kube play api-demo.yaml -
Vérifier
Fenêtre de terminal podman pod pscurl http://localhost:8080 -
Nettoyer
Fenêtre de terminal podman kube down api-demo.yaml
Checklist de validation :
-
podman pod psmontre le pod -
podman ps --podmontre les conteneurs -
curl localhost:8080fonctionne - Après
kube down,podman pod psest vide -
podman volume lsmontre les volumes restants (si PVC)
Dépannage
Section intitulée « Dépannage »Erreurs courantes
Section intitulée « Erreurs courantes »La plupart des erreurs viennent de trois sources : un pod qui existe déjà (nom en conflit), une image mal référencée (oubli du registry), ou un port déjà utilisé.
| Erreur | Cause | Solution |
|---|---|---|
Error: pod already exists | Pod avec ce nom existe | --replace ou supprimer le pod |
image not found | Image avec tag local | Ajouter docker.io/library/ |
hostPort already in use | Port déjà utilisé | Changer le hostPort ou libérer le port |
ConfigMap not found | ConfigMap pas dans le même fichier | Mettre ConfigMap avant Pod dans le YAML |
Commandes de diagnostic
Section intitulée « Commandes de diagnostic »# Voir ce qui a été créépodman pod pspodman ps --pod
# Logs d'un conteneurpodman logs <container-name>
# Inspecter le podpodman pod inspect <pod-name>
# Vérifier un YAML sans le lancerpodman kube play --start=false <fichier.yaml>Le pod ne démarre pas
Section intitulée « Le pod ne démarre pas »# Vérifier les logspodman kube play my-pod.yamlpodman logs <container-name>
# Problème d'image ?podman pull docker.io/library/nginx:alpine
# Problème de port ?ss -tlnp | grep <port>Bonnes pratiques
Section intitulée « Bonnes pratiques »Organisation des fichiers
Section intitulée « Organisation des fichiers »Répertoiredeploy/
Répertoirebase/
- pod.yaml
- configmap.yaml
- secret.yaml
Répertoiredev/
- pod-dev.yaml
Répertoireprod/
- pod-prod.yaml
Conventions
Section intitulée « Conventions »- Un fichier par ressource ou tout dans un fichier avec
---séparateurs - ConfigMap avant Pod : les dépendances d’abord
- Images complètes :
docker.io/library/nginx:alpinepasnginx:alpine - Labels explicites : pour le filtrage et la documentation
Versionner les YAML
Section intitulée « Versionner les YAML »# Générer avec datepodman kube generate my-pod > pod-$(date +%Y%m%d).yaml
# Ou utiliser Gitgit add pod.yamlgit commit -m "feat: add resource limits"À retenir
Section intitulée « À retenir »kube play: lance un YAML Kubernetes localementkube generate: crée un YAML depuis des conteneurs existants--replace: recrée le pod sans suppression manuellekube down: supprime le pod, préserve les volumes (sauf--force)- Workflow : CLI → generate → edit → play → iterate
- Scope limité : pas de Services, Ingress, NetworkPolicy