Capítulo 11. Uso de la CLI de container-tools
11.1. podman
El comando podman
(que significa Pod Manager) permite ejecutar contenedores como entidades independientes, sin necesidad de que intervengan Kubernetes, el tiempo de ejecución de Docker o cualquier otro tiempo de ejecución de contenedores. Es una herramienta que puede actuar como reemplazo del comando docker
, implementando la misma sintaxis de línea de comandos, mientras que agrega aún más características de administración de contenedores. Las características de podman
incluyen:
-
Based on the Docker interface: Dado que la sintaxis de
podman
es un reflejo del comandodocker
, la transición apodman
debería ser fácil para quienes estén familiarizados condocker
. Managing containers and images: Tanto las imágenes de contenedores compatibles con Docker como con OCI pueden utilizarse con
podman
para:- Ejecutar, detener y reiniciar contenedores
- Creación y gestión de imágenes de contenedores (push, commit, configuración, build, etc.)
-
Managing pods: Además de ejecutar contenedores individuales,
podman
puede ejecutar un conjunto de contenedores agrupados en un pod. Un pod es la unidad de contenedores más pequeña que gestiona Kubernetes. -
Working with no runtime:
podman
no utiliza ningún entorno de ejecución para trabajar con contenedores.
Estas son algunas de las características de implementación de Podman que debes conocer:
-
Podman, Buildah y el motor de contenedores CRI-O utilizan el mismo directorio de almacenamiento back-end,
/var/lib/containers
, en lugar de utilizar la ubicación de almacenamiento de Docker (/var/lib/docker
), por defecto. - Aunque Podman, Buildah y CRI-O comparten el mismo directorio de almacenamiento, no pueden interactuar con los contenedores del otro. Sin embargo, estas herramientas pueden compartir imágenes. Eventualmente esas funciones podrán compartir contenedores.
-
El comando
podman
, al igual que el comandodocker
, puede construir imágenes de contenedores desde un archivo Docker. -
El comando
podman
puede ser una herramienta útil para solucionar problemas cuando el servicioCRI-O
no está disponible. -
Las opciones del comando
docker
que no son soportadas porpodman
incluyen network, node, plugin (podman
no soporta plugins), rename (use rm y create para renombrar contenedores conpodman
), secret, service, stack, y swarm (podman
no soporta Docker Swarm). Las opciones de contenedor e imagen se utilizan para ejecutar subcomandos que se utilizan directamente enpodman
. - Para interactuar programáticamente con podman, puede utilizar la API RESTful de Podman v2.0, que funciona tanto en un entorno con raíces como sin ellas. Para más información, consulte el capítulo Uso de la API de herramientas de contenedores.
11.1.1. Uso de los comandos de podman
Si está acostumbrado a utilizar el comando docker
para trabajar con contenedores, encontrará que la mayoría de las funciones y opciones coinciden con las de podman
. La Tabla 1 muestra una lista de comandos que puedes utilizar con podman
(escribe podman -h
para ver esta lista):
comando podman | Descripción | comando podman | Descripción |
attach | Adjuntar a un contenedor en funcionamiento | commit | Crear una nueva imagen a partir de un contenedor modificado |
build | Construir una imagen utilizando las instrucciones de Dockerfile | create | Crear, pero no iniciar, un contenedor |
diff | Inspeccionar los cambios en los sistemas de archivos del contenedor | exec | Ejecutar un proceso en un contenedor en funcionamiento |
export | Exportar el contenido del sistema de archivos del contenedor como un archivo tar | help, h | Muestra una lista de comandos o la ayuda de un comando |
history | Mostrar el historial de una imagen especificada | images | Lista de imágenes en el almacenamiento local |
import | Importación de un tarball para crear una imagen del sistema de archivos | info | Mostrar información del sistema |
inspect | Mostrar la configuración de un contenedor o imagen | kill | Enviar una señal específica a uno o varios contenedores en funcionamiento |
load | Cargar una imagen desde un archivo | login | Acceder a un registro de contenedores |
logout | Cierre de sesión de un registro de contenedores | logs | Obtener los registros de un contenedor |
mount | Montar el sistema de archivos raíz de un contenedor en funcionamiento | pause | Pone en pausa todos los procesos de uno o varios contenedores |
ps | Lista de contenedores | port | Lista de mapeos de puertos o un mapeo específico para el contenedor |
pull | Sacar una imagen de un registro | push | Enviar una imagen a un destino especificado |
restart | Reiniciar uno o varios contenedores | rm |
Eliminar uno o más contenedores del host. Añadir |
rmi | elimina una o varias imágenes del almacenamiento local | run | ejecutar un comando en un nuevo contenedor |
save | Guardar la imagen en un archivo | search | buscar imagen en el registro |
start | Iniciar uno o más contenedores | stats | Mostrar el porcentaje de CPU, memoria, E/S de red, E/S de bloque y PIDs para uno o más contenedores |
stop | Detener uno o varios contenedores | tag | Añadir un nombre adicional a una imagen local |
top | Mostrar los procesos en ejecución de un contenedor | umount, unmount | Desmontar el sistema de archivos raíz de un contenedor en funcionamiento |
unpause | Desactivar los procesos de uno o varios contenedores | version | Mostrar la información de la versión de podman |
wait | Bloqueo en uno o varios contenedores |
11.1.2. Creación de políticas SELinux para contenedores
Para generar políticas SELinux para contenedores, utilice la herramienta UDICA. Para más información, consulte Introducción al generador de políticas SELinux udica.
11.1.3. Uso de podman con MPI
Puede utilizar Podman con Open MPI (Message Passing Interface) para ejecutar contenedores en un entorno de computación de alto rendimiento (HPC).
El ejemplo se basa en el programa ring.c tomado de Open MPI. En este ejemplo, un valor es pasado por todos los procesos en forma de anillo. Cada vez que el mensaje pasa por el rango 0, el valor se decrementa. Cuando cada proceso recibe el mensaje 0, lo pasa al siguiente proceso y luego sale. Al pasar el 0 primero, todos los procesos reciben el mensaje 0 y pueden salir normalmente.
Procedimiento
Instalar Open MPI:
$ sudo yum install openmpi
Para activar los módulos de entorno, escriba:
$ . /etc/profile.d/modules.sh
Cargue el módulo
mpi/openmpi-x86_64
:$ module load mpi/openmpi-x86_64
Opcionalmente, para cargar automáticamente el módulo
mpi/openmpi-x86_64
, añada esta línea al archivo.bashrc
:$ echo \ "module load mpi/openmpi-x86_64" >> .bashrc
Para combinar
mpirun
ypodman
, cree un contenedor con la siguiente definición:$ cat Containerfile FROM registry.access.redhat.com/ubi8/ubi RUN yum -y install openmpi-devel wget && \ yum clean all RUN wget https://raw.githubusercontent.com/open-mpi/ompi/master/test/simple/ring.c && \ /usr/lib64/openmpi/bin/mpicc ring.c -o /home/ring && \ rm -f ring.c
Construye el contenedor:
$ podman build --tag=mpi-ring .
Inicie el contenedor. En un sistema con 4 CPUs este comando inicia 4 contenedores:
$ mpirun \ --mca orte_tmpdir_base /tmp/podman-mpirun \ podman run --env-host \ -v /tmp/podman-mpirun:/tmp/podman-mpirun \ --userns=keep-id \ --net=host --pid=host --ipc=host \ mpi-ring /home/ring Rank 2 has cleared MPI_Init Rank 2 has completed ring Rank 2 has completed MPI_Barrier Rank 3 has cleared MPI_Init Rank 3 has completed ring Rank 3 has completed MPI_Barrier Rank 1 has cleared MPI_Init Rank 1 has completed ring Rank 1 has completed MPI_Barrier Rank 0 has cleared MPI_Init Rank 0 has completed ring Rank 0 has completed MPI_Barrier
Como resultado,
mpirun
inicia 4 contenedores Podman y cada contenedor está ejecutando una instancia del binarioring
. Los 4 procesos se comunican entre sí a través de MPI.Las siguientes opciones de
mpirun
se utilizan para iniciar el contenedor:-
la línea
--mca orte_tmpdir_base /tmp/podman-mpirun
indica a Open MPI que cree todos sus archivos temporales en/tmp/podman-mpirun
y no en/tmp
. Si se utiliza más de un nodo, este directorio tendrá un nombre diferente en los otros nodos. Esto requiere montar el directorio completo/tmp
en el contenedor, lo que es más complicado.
El comando
mpirun
especifica el comando a iniciar, el comandopodman
. Las siguientes opciones depodman
se utilizan para iniciar el contenedor:-
run
comando ejecuta un contenedor. -
--env-host
opción copia todas las variables de entorno del host en el contenedor. -
-v /tmp/podman-mpirun:/tmp/podman-mpirun
indica a Podman que monte el directorio donde Open MPI crea sus directorios y archivos temporales para que estén disponibles en el contenedor. -
la línea
--userns=keep-id
asegura el mapeo de la identificación del usuario dentro y fuera del contenedor. -
la línea
--net=host --pid=host --ipc=host
establece los mismos espacios de nombres de red, PID e IPC. -
mpi-ring
es el nombre del contenedor. -
/home/ring
es el programa MPI en el contenedor.
-
la línea
Para más información, véase el artículo Podman in HPC environments de Adrian Reber.
11.1.4. Creación y restauración de puntos de control de contenedores
Checkpoint/Restore In Userspace (CRIU) es un software que permite establecer un punto de control en un contenedor en ejecución o en una aplicación individual y almacenar su estado en el disco. Puedes utilizar los datos guardados para restaurar el contenedor después de un reinicio en el mismo punto en el que se hizo el checkpoint.
11.1.4.1. Creación y restauración de un punto de control del contenedor de forma local
Este ejemplo se basa en un servidor web basado en Python que devuelve un único número entero que se incrementa después de cada petición.
Procedimiento
Crear un servidor basado en Python:
# cat counter.py #!/usr/bin/python3 import http.server counter = 0 class handler(http.server.BaseHTTPRequestHandler): def do_GET(s): global counter s.send_response(200) s.send_header('Content-type', 'text/html') s.end_headers() s.wfile.write(b'%d\n' % counter) counter += 1 server = http.server.HTTPServer(('', 8088), handler) server.serve_forever()
Cree un contenedor con la siguiente definición:
# cat Containerfile FROM registry.access.redhat.com/ubi8/ubi COPY counter.py /home/counter.py RUN useradd -ms /bin/bash counter RUN yum -y install python3 && chmod 755 /home/counter.py USER counter ENTRYPOINT /home/counter.py
El contenedor está basado en la Imagen Base Universal (UBI 8) y utiliza un servidor basado en Python.
Construye el contenedor:
# podman build . --tag counter
Los archivos
counter.py
yContainerfile
son la entrada para el proceso de construcción del contenedor (podman build
). La imagen construida se almacena localmente y se etiqueta con la etiquetacounter
.Inicie el contenedor como root:
# podman run --name criu-test --detach counter
Para listar todos los contenedores en ejecución, introduzca:
# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e4f82fd84d48 localhost/counter:latest 5 seconds ago Up 4 seconds ago criu-test
Muestra la dirección IP del contenedor:
# podman inspect criu-test --format "{{.NetworkSettings.IPAddress}}" 10.88.0.247
Enviar solicitudes al contenedor:
# curl 10.88.0.247:8080 0 # curl 10.88.0.247:8080 1
Crear un punto de control para el contenedor:
# podman container checkpoint criu-test
- Reinicia el sistema.
Restaurar el contenedor:
# podman container restore --keep criu-test
Enviar solicitudes al contenedor:
# curl 10.88.0.247:8080 2 # curl 10.88.0.247:8080 3 # curl 10.88.0.247:8080 4
El resultado ahora no comienza de nuevo en
0
, sino que continúa en el valor anterior.
De este modo, puede guardar fácilmente el estado completo del contenedor mediante un reinicio.
Para más información, consulta el artículo Adding checkpoint/restore support to Podman de Adrian Reber.
11.1.4.2. Reducción del tiempo de arranque mediante la restauración de contenedores
Puede utilizar la migración de contenedores para reducir el tiempo de arranque de los contenedores que requieren un cierto tiempo para inicializarse. Utilizando un punto de control, puede restaurar el contenedor varias veces en el mismo host o en diferentes hosts. Este ejemplo se basa en el contenedor de la sección Crear y restaurar un punto de control del contenedor localmente.
Procedimiento
Cree un punto de control del contenedor y exporte la imagen del punto de control a un archivo
tar.gz
:# podman container checkpoint criu-test --export /tmp/chkpt.tar.gz
Restaurar el contenedor desde el archivo
tar.gz
:# podman container restore --import /tmp/chkpt.tar.gz --name counter1 # podman container restore --import /tmp/chkpt.tar.gz --name counter2 # podman container restore --import /tmp/chkpt.tar.gz --name counter3
La opción
--name
(-n
) especifica un nuevo nombre para los contenedores restaurados desde el punto de control exportado.Muestra el ID y el nombre de cada contenedor:
# podman ps -a --format "{{.ID}} {{.Names}}" a8b2e50d463c counter3 faabc5c27362 counter2 2ce648af11e5 counter1
Muestra la dirección IP de cada contenedor:
#️ podman inspect counter1 --format "{{.NetworkSettings.IPAddress}}" 10.88.0.248 #️ podman inspect counter2 --format "{{.NetworkSettings.IPAddress}}" 10.88.0.249 #️ podman inspect counter3 --format "{{.NetworkSettings.IPAddress}}" 10.88.0.250
Enviar solicitudes a cada contenedor:
#️ curl 10.88.0.248:8080 4 #️ curl 10.88.0.249:8080 4 #️ curl 10.88.0.250:8080 4
Tenga en cuenta que el resultado es
4
en todos los casos, porque está trabajando con diferentes contenedores restaurados desde el mismo punto de control.
Utilizando este enfoque, puede iniciar rápidamente réplicas con estado del contenedor inicialmente verificado.
Para más información, consulte el artículo Container migration with Podman on RHEL de Adrian Reber.
11.1.4.3. Migración de contenedores entre sistemas
Este procedimiento muestra la migración de contenedores en ejecución de un sistema a otro, sin perder el estado de las aplicaciones que se ejecutan en el contenedor. Este ejemplo se basa en el contenedor de la sección Crear y restaurar un punto de control del contenedor localmente etiquetado con counter
.
Requisitos previos
Los siguientes pasos no son necesarios si el contenedor es empujado a un registro ya que Podman descargará automáticamente el contenedor desde un registro si no está disponible localmente. En este ejemplo no se utiliza un registro, hay que exportar el contenedor previamente construido y etiquetado (ver sección Creación y restauración de un punto de control del contenedor localmente ) localmente e importar el contenedor en el sistema de destino de esta migración.
Exportar un contenedor previamente construido:
# podman save --output counter.tar counter
Copiar la imagen del contenedor exportado al sistema de destino (
other_host
):# scp contador.tar other_host:
Importar el contenedor exportado en el sistema de destino:
# ssh other_host podman load --input counter.tar
Ahora el sistema de destino de esta migración de contenedores tiene la misma imagen de contenedor almacenada en su almacenamiento local de contenedores.
Procedimiento
Inicie el contenedor como root:
# podman run --name criu-test --detach counter
Muestra la dirección IP del contenedor:
# podman inspect criu-test --format "{{.NetworkSettings.IPAddress}}" 10.88.0.247
Enviar solicitudes al contenedor:
# curl 10.88.0.247:8080 0 # curl 10.88.0.247:8080 1
Cree un punto de control del contenedor y exporte la imagen del punto de control a un archivo
tar.gz
:# podman container checkpoint criu-test --export /tmp/chkpt.tar.gz
Copie el archivo de puntos de control en el host de destino:
# scp /tmp/chkpt.tar.gz other_host:/tmp/
Restaurar el punto de control en el host de destino (
other_host
):# podman container restore --import /tmp/chkpt.tar.gz
Enviar una solicitud al contenedor en el host de destino (
other_host
):# curl 10.88.0.247:8080 2
Como resultado, el contenedor con estado se ha migrado de un sistema a otro sin perder su estado.
Para más información, consulte el artículo Container migration with Podman on RHEL de Adrian Reber.