Actualizar a Podman 6: qué se rompe y cómo comprobar tu servidor antes
Índice de contenidos
- Puntos clave
- Qué retira Podman 6
- Cómo lo probé
- Qué pasa con una base de datos BoltDB
- Qué pasa con las redes CNI
- Qué pasa con iptables
- Qué pasa con slirp4netns y pasta
- Qué pasa con Quadlet y podman compose
- El script de comprobación
- Orden recomendado para actualizar
- Preguntas frecuentes
- ¿Puedo saltar de Podman 4 directamente a Podman 6?
- ¿Se pierden mis contenedores al migrar de BoltDB a SQLite?
- ¿Tengo que cambiar mis ficheros Quadlet?
- Conclusión
- Fuentes
Podman 6 retiró cgroups v1, CNI, iptables, slirp4netns y BoltDB. Lo he probado con Podman 6.1.3 sobre estados creados con 4.9.4 y 5.8.7: BoltDB se migra solo, pero una red CNI desaparece sin aviso y un contenedor con slirp4netns no arranca. Incluyo un script de 38 líneas que detecta cada caso antes de actualizar.
Podman 6, publicado el 24 de junio de 2026, retira siete cosas de golpe: cgroups v1, la red CNI, iptables, slirp4netns, la base de datos BoltDB y el soporte de Mac con Intel y de Windows 10. Lo he probado con Podman 6.1.3, la última versión a 7 de octubre de 2026, sobre estados creados con Podman 4.9.4 y 5.8.7. BoltDB y slirp4netns se arreglan con un comando, pero una red CNI desaparece sin ningún aviso. Abajo tienes cada caso reproducido y un script de comprobación. Si aún no conoces Podman, empieza por Podman: contenedores sin daemon ni root. También hay versión en inglés.
Puntos clave
- Las notas de la versión 6.0.0 dicen: "Support for CNI networking has been removed. Please use Netavark instead." Hay siete retiradas de soporte y una reescritura del análisis de los ficheros de configuración.
- Podman 6.1.3 migró un estado BoltDB creado con Podman 4.9.4 a SQLite sin pasos extra: conservó contenedor, volumen y red, y dejó el original como
bolt_state.db-old. - Una red CNI no se migra. Con 6.1.3 el contenedor quedó en
Exitedypodman startfalló conunable to find network with name legacy: network not found. - Un contenedor rootless creado con
--network slirp4netnsno arranca en Podman 6 hasta que ejecutaspodman system migrate. - Debian forky trae Podman 5.8.6, Ubuntu 26.04 trae 5.7.0 y Fedora 44 trae 5.8.7: de las que comprobé, solo Fedora 45, aún en preparación, empaqueta Podman 6.1.3.
Qué retira Podman 6
Las notas de la versión 6.0.0[1] enumeran los cambios incompatibles. Los que afectan a un servidor Linux son estos:
| Se retira | Qué usar en su lugar | Quién lo nota |
|---|---|---|
| cgroups v1 | cgroups v2 | Distribuciones antiguas o con systemd.unified_cgroup_hierarchy=0 |
| CNI (Container Network Interface) | Netavark | Redes creadas con Podman 3 o 4 que nunca se migraron |
| iptables | nftables | Quien fija NETAVARK_FW=iptables |
| slirp4netns | pasta | Contenedores rootless con --network slirp4netns |
| BoltDB | SQLite | Estados antiguos que nunca se migraron |
| Mac con Intel, Windows 10 | Hardware y sistema actuales | Quien usa podman machine |
Además, el análisis de containers.conf, storage.conf y registries.conf se reescribió con una única lógica de búsqueda y orden. Podman 6.0.0 exige versiones concretas del resto de herramientas: Buildah 1.44.0, Skopeo 1.23 y Netavark y Aardvark 2.0.0. En el mismo lanzamiento, podman volume prune solo borra volúmenes anónimos sin usar, como Docker; para el comportamiento anterior hay que añadir --all.
Tres de los cambios probablemente ya los cumples si usas una distribución reciente. Fedora 44 y Debian trixie arrancan con cgroups v2. En mis pruebas, Netavark 1.17.2 (Fedora 44) y 1.14.0 (Debian trixie, con Podman 5.4.2) crearon la tabla inet netavark de nftables sin configurar nada.
Cómo lo probé
Todo corrió el 7 de octubre de 2026 en Docker Engine 29.5.2 sobre arm64, con el kernel 7.0.14.
La imagen oficial quay.io/podman/stable seguía en Podman 5.8.7 y no tenía etiquetas de la versión 6. Construí dos imágenes con Fedora: fedora:44 con Podman 5.8.7 y fedora:45 con Podman 6.1.3, Netavark 2.1.0, aardvark-dns 2.1.0, passt 20261002 y crun 1.30.1. Para el estado antiguo usé quay.io/podman/stable:v4.9.4. Los contenedores corrieron con --privileged y systemd como proceso 1; el almacén y las redes iban en volúmenes de Docker para pasar el mismo estado de una versión a otra.
FROM fedora:45
RUN dnf -y install podman podman-compose netavark aardvark-dns passt \
systemd nftables iptables-nft shadow-utils jq procps-ng iproute \
iputils curl-minimal fuse-overlayfs crun
RUN useradd -m app
CMD ["/sbin/init"]
La imagen de Fedora no deja newuidmap con permisos para rootless; hace falta chmod u+s /usr/bin/newuidmap /usr/bin/newgidmap.
Qué pasa con una base de datos BoltDB
Podman 4.9.4 todavía puede crear BoltDB si lo pides en containers.conf; Podman 5.8.7 ya no (the BoltDB backend has been deprecated, no new BoltDB databases can be created). Por eso creé el estado con la 4.9.4:
printf '[engine]\ndatabase_backend="boltdb"\n' \
> /etc/containers/containers.conf.d/50-bolt.conf
podman volume create data
podman network create appnet
podman run -d --name web --network appnet -v data:/usr/share/nginx/html \
-p 8081:80 nginx:alpine
podman exec web sh -c \
'echo hello-from-podman4 > /usr/share/nginx/html/index.html'
podman stop web
Después monté el mismo almacén (/var/lib/containers) y las redes (/etc/containers/networks) en la imagen con Podman 6.1.3. Primer comando, podman ps -a:
Old database has been renamed to
/var/lib/containers/storage/libpod/bolt_state.db-old
and will no longer be used
web Exited (0) 6 seconds ago appnet
Podman 6.1.3 renombró bolt_state.db a bolt_state.db-old (131 072 bytes) y creó /var/lib/containers/storage/db.sql (122 880 bytes). podman info pasó a decir sqlite. El contenedor, el volumen data y la red appnet seguían ahí; podman start web lo arrancó y podman exec web cat /usr/share/nginx/html/index.html devolvió hello-from-podman4. Podman 5.8.7 hizo lo mismo con el mismo estado: la migración no es nueva de la 6.
Haz una copia de /var/lib/containers/storage (o de ~/.local/share/containers/storage si es rootless) antes del primer arranque. Si el estado de BoltDB se corrompe, el fichero -old es tu única vuelta atrás.
Qué pasa con las redes CNI
Aquí está el riesgo real. Para fabricar una red CNI usé Podman 4.9.4 con el paquete containernetworking-plugins 1.3.0 y network_backend="cni". podman info dijo net=cni, la red legacy quedó en /etc/cni/net.d/legacy.conflist y el contenedor web corrió en ella. Luego lo paré y abrí el mismo estado con Podman 6.1.3, sin tocar la configuración:
$ podman network ls
NETWORK ID NAME DRIVER
2f259bab93aa podman bridge
$ podman start web
Error: unable to start container "84097e20...":
unable to find network with name legacy: network not found
Podman 6 no avisa de que hay redes CNI: usa Netavark, no ve el conflist y la red legacy deja de existir. El fichero sigue en /etc/cni/net.d, sin usar. Si fuerzas network_backend="cni", Podman 6.1.3 responde unsupported network backend "cni", only netavark is supported, y la compilación de Fedora de Podman 5.8.7 ya decía cni support is not enabled in this build.
La salida es recrear cada red con el mismo rango, que se lee del conflist:
SUB=$(jq -r '.plugins[]|select(.type=="bridge")|.ipam.ranges[0][0].subnet' \
/etc/cni/net.d/legacy.conflist)
podman network create --subnet "$SUB" legacy
podman start web
Con 10.89.0.0/24 el contenedor arrancó, recibió 10.89.0.2 y respondió 200 en el puerto publicado. Si tus contenedores usaban la red podman por defecto de CNI y nunca crearon redes propias, no tienes nada que recrear.
Qué pasa con iptables
Netavark 2.1.0 solo acepta nftables. Con NETAVARK_FW=iptables, Podman 6.1.3 falló con netavark: Must provide a valid firewall backend, got iptables. En el mismo entorno, Podman 5.8.7 con Netavark 1.17.2 sí creó reglas en las tablas ip nat y ip filter al fijar esa variable.
Mira si la tienes en un fichero .env, en una unidad de systemd o en containers.conf (firewall_driver). Si no la fijaste nunca, no cambia nada: la tabla inet netavark ya existía con Podman 5.
Qué pasa con slirp4netns y pasta
En rootless, Podman 6.1.3 informa RootlessNetworkCmd como pasta, y un contenedor con -p 8090:80 respondió 200 en 127.0.0.1:8090. El proceso que reenvía el puerto es pasta:
/usr/sbin/pasta --config-net -t 8090-8090:80-80 --dns-forward 169.254.1.1 ...
Dentro del contenedor, pasta copia la dirección del anfitrión (172.17.0.2/16, la de mi contenedor de pruebas) en lugar de crear una subred propia; es el diseño de pasta[2], no un fallo. Pedir slirp4netns falla de inmediato:
$ podman run --rm --network slirp4netns alpine true
Error: slirp4netns support has been removed, use
--network=pasta instead; for existing containers,
run `podman system migrate`
Para un contenedor que ya existía, creé uno con Podman 5.8.7 (podman create --network slirp4netns) y lo abrí con la 6.1.3. podman start dio slirp4netns support has been removed, run 'podman system migrate' to update this container to use pasta. Tras podman system migrate, podman inspect mostró pasta en HostConfig.NetworkMode.
El arranque posterior del contenedor migrado falló por el directorio de ejecución de la otra imagen, algo propio de mi montaje con dos imágenes. No lo atribuyo a Podman. Un clon hecho con podman container clone sí arrancó.
Qué pasa con Quadlet y podman compose
Probé las dos cosas en rootless con Podman 6.1.3. En Quadlet, estos dos ficheros en ~/.config/containers/systemd/ generaron y arrancaron las unidades sin cambios:
# hello-data.volume
[Volume]
UID=101
GID=101
# hello.container
[Container]
Image=nginx:alpine
PublishPort=8094:80
Network=pasta
Volume=hello-data.volume:/usr/share/nginx/html:Z
[Install]
WantedBy=default.target
systemctl --user daemon-reload y systemctl --user start hello.service dejaron la unidad en active, el puerto 8094 respondió 200 y podman quadlet list mostró hello.container ... active/running. Las claves UID= y GID= de .volume son nuevas de Podman 6.0.0. Me equivoqué una vez: escribí Volume=hello-data: sin .volume y Podman creó un volumen suelto en lugar de usar el del Quadlet. La documentación de los ficheros de Quadlet[3] lo deja claro; el sufijo es lo que enlaza los dos.
Para podman compose, un fichero con un servicio nginx que depende de otro:
podman compose up -d
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8095/
podman exec stack_web_1 getent hosts api
podman compose delega en un proveedor externo; aquí fue podman-compose 1.6.0 y lo avisa con Executing external compose provider "/usr/sbin/podman-compose". Con el fichero tal cual, podman compose up -d agrupó los servicios en un pod y falló con unable to create pod cgroup ... was already loaded or has a fragment file.
Un podman pod create suelto fallaba igual con el gestor de cgroups systemd y funcionaba con --cgroup-manager=cgroupfs. Apunta a mi entorno, un systemd dentro de un contenedor de Docker, y no a Podman 6; no lo probé en un servidor físico.
Añadí al principio del fichero x-podman: con in_pod: false. Entonces los dos servicios arrancaron, el puerto 8095 respondió 200 y getent hosts api devolvió 10.89.0.2 api.dns.podman. Si trabajas con Compose en Docker, el artículo sobre Docker Compose 5.5 cubre el otro lado de esta migración.
El script de comprobación
Reuní todo lo anterior en un script de solo lectura, 38 líneas de sh. Ejecútalo como root y con cada usuario rootless:
#!/bin/sh
warn=0
bad() { echo "BLOCKER $*"; warn=1; }
ok() { echo "ok $*"; }
pi() { podman info --format "$1" 2>/dev/null; }
echo "podman: $(podman --version)"
fs=$(stat -fc %T /sys/fs/cgroup)
[ "$fs" = cgroup2fs ] && ok "cgroups v2" || bad "cgroups v1 ($fs)"
db=$(pi '{{.Host.DatabaseBackend}}')
[ "$db" = sqlite ] && ok "database: sqlite" \
|| echo "migrate database: $db (back up first)"
nb=$(pi '{{.Host.NetworkBackend}}')
[ "$nb" = netavark ] && ok "network: netavark" || bad "network: $nb"
for d in /etc/cni/net.d "$HOME/.config/cni/net.d"; do
ls "$d"/*.conflist >/dev/null 2>&1 && bad "CNI networks in $d"
done
Segunda mitad: busca ajustes en los ficheros de configuración y revisa los contenedores existentes.
conf() {
grep -rEs "$1" /etc/containers /usr/share/containers \
"$HOME/.config/containers" | grep -vE '^[^:]*:[[:space:]]*#' || true
}
chk() { hits=$(conf "$1"); [ -n "$hits" ] && { echo "$hits"; bad "$2"; }; }
[ "$NETAVARK_FW" = iptables ] && bad "NETAVARK_FW=iptables"
chk '^\s*firewall_driver\s*=\s*"?iptables' "firewall_driver iptables"
chk 'network_backend\s*=\s*"?cni' "network_backend cni in config"
chk 'slirp4netns|network_cmd_path' "slirp4netns in config"
[ "$(pi '{{.Host.RootlessNetworkCmd}}')" = slirp4netns ] \
&& bad "rootless network command is slirp4netns"
for c in $(podman ps -a -q); do
m=$(podman inspect --format '{{.HostConfig.NetworkMode}}' "$c")
case "$m" in slirp4netns*) bad "container $c uses $m";; esac
done
echo "exit: $warn"
exit $warn
Lo corrí en cuatro estados distintos.
- Con Podman 6.1.3 limpio, salió
exit: 0. - Con Podman 4.9.4 y CNI, marcó
BLOCKER network: cni, laconflisty elnetwork_backendde la configuración. - Con el estado BoltDB y
NETAVARK_FW=iptables, avisó demigrate database: boltdby del bloqueo de iptables. - Con Podman 5.8.7 y un contenedor slirp4netns, marcó tres bloqueos; es la salida de la imagen de portada.
El script no ve los contenedores de otros usuarios ni la configuración fuera de /etc/containers, /usr/share/containers y ~/.config/containers.
Orden recomendado para actualizar
- Ejecuta el script como root y con cada usuario rootless.
- Copia
/var/lib/containers/storagey~/.local/share/containers/storage. - Recrea las redes CNI con Netavark y quita
NETAVARK_FW=iptables. - Actualiza el paquete. En Fedora y Debian la ruta es el gestor de paquetes; no hay una imagen
quay.io/podman/stablede la 6 a 7 de octubre de 2026. - Ejecuta
podman system migratecomo cada usuario rootless si tenías contenedores con slirp4netns. - Arranca los contenedores y comprueba las unidades de Quadlet con
podman quadlet list.
La 6.1.3, del 29 de septiembre de 2026, corrige la CVE-2026-94603 y retira podman run sobre imágenes de checkpoint. Si usas checkpoints, lee las notas de esa versión[4].
Preguntas frecuentes
¿Puedo saltar de Podman 4 directamente a Podman 6?
En mi prueba, sí con el estado: un almacén BoltDB creado con 4.9.4 se migró a SQLite con la 6.1.3 sin pasar por la 5. Lo que no se salta es la red CNI, que tienes que recrear a mano.
¿Se pierden mis contenedores al migrar de BoltDB a SQLite?
No: en mi prueba el contenedor, el volumen y la red siguieron ahí y el volumen conservó su contenido. La copia previa sigue siendo necesaria, porque la migración es de un solo sentido y el fichero bolt_state.db-old no se vuelve a leer.
¿Tengo que cambiar mis ficheros Quadlet?
Los míos, con Network=pasta, PublishPort y un volumen enlazado con .volume, no necesitaron cambios. Revisa solo los que usen Network=slirp4netns: u opciones de slirp4netns, y los que dependan de la estructura de podman quadlet install, que cambió en 6.0.0.
Conclusión
Podman 6 es un salto de versión con consecuencias limitadas si tu host es reciente: en mis pruebas, BoltDB y slirp4netns se resolvieron con un comando, y Quadlet y podman compose funcionaron. La excepción es CNI, porque la red desaparece sin ningún aviso. Antes de actualizar, ejecuta el script, copia el almacén y recrea las redes.
Fuentes: [1] Notas de la versión 6.0.0 de Podman[1], [2] Notas de la versión 6.1.3[4], [3] Ficheros Quadlet (podman-systemd.unit)[3], [4] podman compose[5], [5] passt y pasta[2], [6] Podman en Debian forky[6], [7] Netavark[7].