Elegir entre Docker o Podman para entornos de pruebas y desarrollo

¿Cuando elegimos Docker o Podman?

Muchas veces nos encontramos que tenemos muy pocos recursos y necesitamos un entorno para realizar una completa demostración de producto a un cliente.

En esos casos vamos a necesitar simular un entorno de la manera más sencilla y con menos recursos posibles y para ello usaremos contenedores, pero ¿cual es la mejor solución para esos pequeños entornos?

Docker

Docker es el entorno de contedores estandar en el mercado, es el más extendido y conforma un conjunto de herramientas extraordinariamente potentes como son un cliente desde linea de comandos, un API server, un gestor del ciclo de vida de los contenedores (containerd), un lanzador de contenedores (runc).

Elegir entre Docker o Podman para entornos de pruebas y desarrollo 1

Instalar docker es realmente fácil, ya que docker suministra un script que realiza el proceso de preparar y configurar los requisitos y los repositorios necesario y por último instala y configura docker dejando el servicio listo para usar.

Podman

Podman es un entorno de contenedores que no utiliza un servicio y por lo tanto no dispone de un API server, las peticiones se hacen únicamente desde la linea de comandos, lo que tiene ventajas y desventajas que explicaremos al final.

Instalar podman es fácil en un entorno Centos (yum install -y podman para Centos 7 y yum install -y container-tools para Centos 8) pero necesita cierto trabajo en un entorno Debian:

# sudo apt update && sudo apt install -y software-properties-common dirmngr
# sudo apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys 0x018BA5AD9DF57A4448F0E6CF8BECF1637AD8C79D
# sudo sh -c "echo 'deb http://ppa.launchpad.net/projectatomic/ppa/ubuntu bionic main' > /etc/apt/sources.list.d/container.list"
# sudo apt update && sudo apt install -y podman skopeo buildah uidmap debootstrap

Despliegue con Ansible

En nuestro caso hemos utilizado los roles Ansible desarrollados en https://github.com/aescanero/disasterproject, para desplegar dos máquinas virtuales, una con podman y la otra con docker.

En el caso de usar una distribución basada en Debian instalamos Ansible:

$ sudo sh -c 'echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" >>/etc/apt/sources.list'
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
$ sudo apt-get update && sudo apt-get install -y ansible 

Procedemos a descargar el entorno y configurar Ansible:

$ git clone https://github.com/aescanero/disasterproject
$ cd disasterproject/ansible
$ chmod 600 files/insecure_private_key

Editamos el archivo inventory.yml y le ponemos el siguiente formato:

all:
  children:
    vms:
      hosts:
        MACHINE_NAME1:
          memory: MEMORY_IN_MB
          vcpus: vCPUS_FOR_VM
          vm_ip: "IP_VM_MACHINA_NAME1"
          linux_flavor: "debian|centos"
          container_engine: "docker|podman"
        MACHINE_NAME2:
          memory: MEMORY_IN_MB
          vcpus: vCPUS_FOR_VM
          vm_ip: "IP_VM_MACHINA_NAME2"
          linux_flavor: "debian|centos"
          container_engine: "docker|podman"
      vars:
        network_name: NETWORK_NAME
        network: "VM_NETWORK"

Existen algunas variables globales que cuelgan de “vars:”, que son:

  • network_name: Nombre descriptivo de la red de libvirt que crearemos y que además será el nombre del interface que se configurará en el anfitrión KVM y que servirá de puerta de enlace de las máquinas virtuales
  • network: los tres primeros campos de la dirección IPv4 para confirmar una red con máscara 255.255.255.0, las máquinas virtuales deberán tener una IP de dicho rango (menos 0,1 y 255)

El formato de cada equipo se define por los siguientes atributos:

  • nombre: Nombre descriptivo de la máquina virtual a desplegar, será además el hostname del equipo
  • memory: Memoria de la máquina virtual en MB
  • vcpus: Número de CPUs virtuales en la máquina virtual
  • vm_ip: IP de la máquina virtual, debe pertenecer al rango definido en la variable general “network”
  • linux_flavor: Es la distribución de la máquina virtual, se permiten dos opciones: debian y centos
  • container_engine: (Opcional) Es el motor de contenedores que se puede desplegar en la máquina virtual, se permiten dos opciones: docker y podman

Desplegamos el entorno con:

$ ansible-playbook -i inventory.yml create.yml --ask-become-pass

Como acceder

Como resultado obtenemos dos máquinas virtuales a las cuales podemos acceder vía ssh con ssh -i files/insecure_private_key vagrant@IP_MÁQUINA_VIRTUAL, en cada una de ellas procedemos a lanzar un contenedor, docker run -td nginx y podman run -dt nginx. Una vez desplegados los contenedor nginx, analizamos que servicios se ven ejecutados en cada caso.

Resultados de la comparativa

  • Docker, arranca 32 procesos para lanzar nginx:
containerd-+-containerd-shim-+-nginx---nginx
                     |                 `-10*[{containerd-shim}]
                     `-8*[{containerd}]
dockerd---9*[{dockerd}]
3194 root      20   0  546332  92220  39252 S  0.0  9.5   0:07.23 dockerd
 2314 root      20   0  463200  41696  25768 S  0.0  4.3   0:00.57 containerd
 3621 root      20   0   32648   5244   4564 S  0.0  0.5   0:00.08 nginx
 3603 root      20   0   11720   4612   3856 S  0.0  0.5   0:00.03 containerd-shim
 3500 root      20   0   20472   2692   1656 S  0.0  0.3   0:00.00 dhclient
 3479 root      20   0   20352   2676   1636 S  0.0  0.3   0:00.00 dhclient
 3656 systemd+  20   0   33100   2508   1468 S  0.0  0.3   0:00.00 nginx
  • Podman, arranca un proceso para lanzar nginx:
conmon-+-nginx---nginx
                 `-{gmain}
 3471 root      20   0   32648   5180   4500 S  0.0  0.5   0:00.06 nginx
 3482 systemd+  20   0   33100   2420   1380 S  0.0  0.2   0:00.00 nginx
 3461 root      20   0   85800   1924   1768 S  0.0  0.2   0:00.00 conmon

Entre las dos máquinas virtuales hay solo 100 MB de diferencia entre ambas:

1,5G docker.qcow2
1,4G podman.qcow2

Como conclusión tenemos los siguientes puntos:

DockerPodman
Gestión de ciclo de vida, por ejemplo reinicio de contenedores que fallan automáticamente, iniciar contenedores automáticamente cuando el equipo se reinicia, ejecuta chequeos sobre los contenedores, iniciar contenedores en un orden determinado, etc.Es compatible con Docker a nivel de CLI, imagen y carga desde registros.
Depende de systemd para gestionar el ciclo de vida de los contenedores.
Requiere más recursos, pero en un entorno de demo/desarrollo con pocos contenedores no debería de requerir importantes recursos.Dispone de más recursos disponibles para los contenedores, lo que es ideal para un entorno de demos en máquinas virtuales.
Ocupa un espacio menor y requiere de menos dependencias.

Podman es un proyecto respaldado por RedHat que está tomando fuerza y muchos servicios de desarrollo se plantean su adopción (por ejemplo el proyecto syslog-ng: https://www.syslog-ng.com/community/b/blog/posts/replacing-docker-with-podman-in-the-syslog-ng-build-container

Más información en como adaptar Podman en Replacing Docker with Podman.

Volver arriba