De Docker Compose à Kubernetes via Podman
Rédigé par Nicolas Sulek
Aucun commentaire
Classé dans : Système
Plusieurs possibilités pour migrer vers Podman :
- remplacer le moteur d'exécution de conteneur Docker par Podman et continuer à utiliser Docker Compose
- utiliser podman-compose
- utiliser les services systemd pour retranscrire les dépendances entre conteneurs
- passer à Quadlet
- réécrire les fichiers docker-compose.yml en fichier YAML pour Kubernetes
Déploiement via docker-compose
Prenons comme exemple un déploiement basique de VaultWarden avec Nginx en reverse-proxy :
services:
nginx:
image: nginx:alpine
container_name: nginx
environment:
- TZ=Europe/Paris
volumes:
- /etc/localtime:/etc/localtime:ro
- /home/vaultwarden/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- 443:443
restart: always
image: vaultwarden/server:alpine
container_name: vaultwarden
environment:
TZ: Europe/Paris
DOMAIN: "https://toto.example.org/"
SIGNUPS_ALLOWED: "false"
INVITATIONS_ALLOWED: "false"
SHOW_PASSWORD_HINT: "false"
volumes:
- /etc/localtime:/etc/localtime:ro
- /home/vaultwarden/vaultwarden:/data
restart: always
depends_on:
- nginx
Docker Compose et Podman
Installons docker-compose et podman :apt install docker-compose podmanSous Debian, le paquet docker-compose installera également Docker, ce qui n'est clairement pas utile pour la suite.
Nous allons donc le désactiver :
systemctl stop docker.service docker.socket systemctl disable docker.service docker.socketet le remplacer par Podman :
rm /run/docker.sock ln -s /run/podman/podman.sock /run/docker.sockOn peut maintenant instancier nos conteneurs en utilisant docker-compose et podman :
docker-compose up -dOn vérifie avec podman ps :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e6899c44175 docker.io/library/nginx:alpine nginx -g daemon o... About a minute ago Up About a minute ago 0.0.0.0:443->443/tcp nginx 1b4f1698f547 docker.io/vaultwarden/server:alpine /start.sh About a minute ago Up About a minute ago vaultwarden
Conversion en YAML pour Kubernetes
On va maintenant pouvoir utiliser podman pour générer un fichier YAML pour Kubernetes en lui spécifiant les conteneurs à récupérer :podman kube generate nginx vaultwarden > vaultwarden.yamlIl peut y avoir des Warning relatifs à des annotations tronquées :
WARN[0000] Truncation Annotation: "https://github.com/nginxinc/docker-nginx.git#cffeb933620093bc0c08c0b28c3d5cbaec79d729:mainline/alpine" to "https://github.com/nginxinc/docker-nginx.git#cffeb933620093bc0c": Kubernetes only allows 63 charactersMais rien de grave, ce ne sont que des annotations que l'on pourra corriger voire supprimer.
On obtient le fichier résultat suivant :
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-4.3.1
# NOTE: If you generated this yaml from an unprivileged and rootless podman container on an SELinux
# enabled system, check the podman generate kube man page for steps to follow to ensure that your pod/container
# has the right permissions to access the volumes added.
---
apiVersion: v1
kind: Pod
metadata:
annotations:
com.docker.official-images.bashbrew.arch/nginx: amd64
io.kubernetes.cri-o.TTY/nginx: "false"
io.kubernetes.cri-o.TTY/vaultwarden: "false"
io.podman.annotations.autoremove/nginx: "FALSE"
io.podman.annotations.autoremove/vaultwarden: "FALSE"
io.podman.annotations.init/nginx: "FALSE"
io.podman.annotations.init/vaultwarden: "FALSE"
io.podman.annotations.privileged/nginx: "FALSE"
io.podman.annotations.privileged/vaultwarden: "FALSE"
io.podman.annotations.publish-all/nginx: "FALSE"
io.podman.annotations.publish-all/vaultwarden: "FALSE"
org.opencontainers.image.base.digest/nginx: sha256:0d0ef5c914d3ea700147da1bd050c59edb8bb12ca312f3800b29d7c8
org.opencontainers.image.base.name/nginx: nginx:1.27.4-alpine-slim
org.opencontainers.image.created/nginx: "2025-02-05T21:27:16Z"
org.opencontainers.image.revision/nginx: cffeb933620093bc0c08c0b28c3d5cbaec79d729
org.opencontainers.image.source/nginx: https://github.com/nginxinc/docker-nginx.git#cffeb933620093bc0c
org.opencontainers.image.url/nginx: https://hub.docker.com/_/nginx
org.opencontainers.image.version/nginx: 1.27.4-alpine
creationTimestamp: "2025-02-18T10:10:21Z"
labels:
app: nginx-pod
name: nginx-pod
spec:
automountServiceAccountToken: false
containers:
- args:
- nginx
- -g
- daemon off;
env:
- name: TZ
value: Europe/Paris
image: docker.io/library/nginx:alpine
name: nginx
ports:
- containerPort: 443
hostPort: 443
securityContext:
capabilities:
drop:
- CAP_MKNOD
- CAP_NET_RAW
- CAP_AUDIT_WRITE
volumeMounts:
- mountPath: /etc/localtime
name: etc-localtime-host-0
readOnly: true
- env:
- name: DOMAIN
value: https://toto.example.org/
- name: SIGNUPS_ALLOWED
value: "false"
- name: INVITATIONS_ALLOWED
value: "false"
- name: TZ
value: Europe/Paris
- name: SHOW_PASSWORD_HINT
value: "false"
image: docker.io/vaultwarden/server:alpine
name: vaultwarden
securityContext:
capabilities:
drop:
- CAP_MKNOD
- CAP_NET_RAW
- CAP_AUDIT_WRITE
volumeMounts:
- mountPath: /etc/localtime
name: etc-localtime-host-1
readOnly: true
- mountPath: /data
name: home-vaultwarden-vaultwarden-host-2
enableServiceLinks: false
volumes:
- hostPath:
path: /etc/localtime
type: File
name: etc-localtime-host-0
- hostPath:
path: /etc/localtime
type: File
name: etc-localtime-host-1
- hostPath:
path: /home/vaultwarden/vaultwarden
type: Directory
name: home-vaultwarden-vaultwarden-host-2
Nettement plus verbeux et long que notre docker-compose.yml d'origine.
On constate que podman va générer :
- 1 pod (nginx-pod)
- 1 nginx
- 1 vaultwarden
Il ne restera plus qu'à modifier ce joli fichier pour le mettre à notre convenance, mais il est normalement déjà fonctionnel.
Après avoir arrêter les conteneurs lancés via docker-compose, on peut instancier les nouveaux avec :
podman kube play vaultwarden.yaml
Exposition des conteneurs
Un léger détail mais qui a son importance, les conteneurs ne sont plus directement exposés sur l'adresse IP publique de l'hôte, la faute à Kubernetes et au pod.Il faudra, par exemple, rajouter un reverse proxy sur l'hôte redirigeant vers nos conteneurs, et sans doute supprimer le conteneur nginx n'ayant plus de raison d'être.
On obtiendrait ainsi le fichier vaultwarden.yaml suivant :
---
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2025-02-18T10:10:21Z"
labels:
app: vaultwarden-pod
name: vaultwarden-pod
spec:
ports:
- name: "80"
nodePort: 31849
port: 80
targetPort: 80
selector:
app: vaultwarden-pod
type: NodePort
---
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2025-02-18T10:10:21Z"
labels:
app: vaultwarden-pod
name: vaultwarden-pod
spec:
automountServiceAccountToken: false
containers:
- env:
- name: TZ
value: Europe/Paris
- name: DOMAIN
value: https://toto.example.org/
- name: INVITATIONS_ALLOWED
value: "false"
- name: SHOW_PASSWORD_HINT
value: "false"
- name: SIGNUPS_ALLOWED
value: "false"
image: docker.io/vaultwarden/server:alpine
name: vaultwarden
ports:
- containerPort: 80
hostIP: 127.0.0.1
hostPort: 80
securityContext:
capabilities:
drop:
- CAP_MKNOD
- CAP_NET_RAW
- CAP_AUDIT_WRITE
volumeMounts:
- mountPath: /data
name: home-vaultwarden-vaultwarden-host-2
- mountPath: /etc/localtime
name: etc-localtime-host-2
readOnly: true
enableServiceLinks: false
volumes:
- hostPath:
path: /home/vaultwarden/vaultwarden
type: Directory
name: home-vaultwarden-vaultwarden-host-2
- hostPath:
path: /etc/localtime
type: File
name: etc-localtime-host-2