Ejecutar contenedores con Podman

Este es uno de los capítulos del tutorial Tutorial de Podman. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.

Hasta el momento has podido ver mucha teoría y poca práctica, que si como gestionar imágenes con Podman, que si como gestionar contenedores, pero ha llegado el momento de la verdad, ha llegado el momento de comenzar a ejecutar contenedores con Podman. Es el momento de sacarle el partido a Podman, y comenzar a disfrutar sin límite.

El objeto de los capítulos anteriores era conocer básicamente el funcionamiento de Podman, y conseguir gestionar tanto imágenes como contenedores en tu equipo. De esta forma, podrás no solo descargar y ejecutar contenedores con Podman, sino que podrás limpiar o reutilizar todos aquellos contenedores e imágenes que no utilices. Algo realmente necesario.

Ejecutar contenedores con Podman

Ejecutar contenedores con Podman

Ayudas

Con el fin de que te resulte mas sencillo ejecutar contenedores con Podman, o en general gestionar contenedores e imágenes con Podman, te recomiendo que utilices Bash-it. Si no conoces, o no has oído hablar de este framework para Bash, te recomiendo la lectura del artículo potenciar el poder del terminal.

El contenedor de trabajo

Para este artículo vamos a crear una sencilla imagen que utilizaremos para demostrar gráficamente como trabajar con Podman. Soy consciente de que la parte de la creación de imágenes, todavía no la has visto, con lo que si quieres puedes saltarla, y ya volverás sobre esto mas adelante.

La razón para crear tu propia imagen es para asegurar que todo funcionará y no recurrir a una imagen que está en el repositorio, en el momento de escribir el artículo, y cuando lo pruebes tu, la hayan quitado o modificado, y te lleves una mala experiencia.

En este caso se trata de una sencillo servidor web que, dependiendo de si existe un determinado archivo, te mostrará el contenido del mismo o un simple Hola por defecto.

El script en Python

Así, el contenido del archivo Python es el siguiente, que llamarás app.py,

import os
from flask import Flask


app = Flask(__name__)

@app.route('/')
def get_hola():
    filename = "contenido/file.txt"
    if os.path.exists(filename):
        with open("contenido/file.txt", "r") as fr:
            return fr.read()
    else:
        return "Hola por defecto"

if __name__ == "__main__":
    app.run("0.0.0.0", 5000)

Es posible que necesites alguna dependencia para ejecutar este archivo en local. Para ello, simplemente ejecuta las siguientes instrucciones en un terminal,

sudo apt install python3-pip
pip3 install --user flask

Ahora ya lo puedes ejecutar,

python3 app.py

Abre un navegador y visita localhost:5000, si no ha pasado nada raro, debería ver Hola por defecto. Si es así, crea un directorio llamado contenido y dentro, pon un archivo file.txt. Dentro de este archivo escribe lo que quieras, por ejemplo Hola Mundo!!!. Es decir,

mkdir contenido
echo "Hola mundo!!!" > contenido/file.txt

La estructura debería ser la siguiente,

.
├── app.py
├── contenido
│   └── file.txt
└── Dockerfile

Si ahora visitas de nuevo en tu navegador localhost:5000 deberías ver un Hola mundo!!!, o el contenido que hayas puesto en ese archivo.

Con esto ya tenemos todo lo relativo a la aplicación que vas a poner en el contenedor. Ahora vamos a crear la imagen que contendrá tu aplicación.

La imagen para tu contenedor

El contenido del archivo Dockerfile para crear tu primera o segunda imagen, es el siguiente,

FROM alpine:3.13
ENV PYTHONUNBUFFERED=1
RUN apk add --no-cache python3 && \
    if [ ! -e /usr/bin/python ]; then ln -sf python3 /usr/bin/python ; fi && \
    python3 -m ensurepip && \
    pip3 install --no-cache --upgrade pip setuptools wheel && \
    if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi
RUN pip3 install --no-cache-dir \
    flask \
    itsdangerous \
    pyinotify \
    werkzeug
RUN adduser -D atareao
USER atareao
WORKDIR /app
COPY app.py /app/
ENTRYPOINT ["python3"]
CMD ["app.py"]

Ahora tienes que construir la imagen. Esto lo puedes hacer ejecutando la siguiente instrucción,

podman build -t sample .

A la imagen le he llamado sample en un derroche de imaginación, pero, evidentemente, tu le puedes llamar como mejor consideres.

Con esto ya lo tienes todo, tanto la aplicación que hiciste en el apartado anterior, como la imagen que acabas de hacer en este. Ahora te toca ejecutar el contenedor con Podman.

Ejecutar tu contenedor

Para iniciar el contenedor, tal y como viste en el capítulo de gestionar contenedores con Podman, solo tienes que ejecutar la siguiente instrucción,

podman run sample

Si todo ha ido bien, verás las siguientes líneas,

* Serving Flask app "app" (lazy loading)
* Environment: production
  WARNING: This is a development server. Do not use it in a production deployment.
  Use a production WSGI server instead.
* Debug mode: off
* Running on https://0.0.0.0:5000/ (Press CTRL+C to quit)

Si ahora visitas localhost:5000, no aparece nada, realmente si, verás un No se puede conectar como una catedral. Y en la ejecución del contenedor, es como si no se hubiera enterado de nada. ¿Que ha pasado?.

Mapeando puertos de tu contenedor

Lo que ha pasado es que no has mapeado el puerto del contenedor con el puerto de tu ordenador. Pulsa Ctrl+C para detener el contenedor y vuelve a lanzarlo con la siguiente instrucción,

podman run -p 8080:5000 sample

Ahora tienes que visitar la página localhost:8080. En este caso verás que en la ejecución del contenedor, al visitar la página que te he indicado han aparecido dos nuevas líneas,

10.0.2.100 - - [12/Apr/2021 05:21:25] "GET / HTTP/1.1" 200 -
10.0.2.100 - - [12/Apr/2021 05:21:25] "GET /favicon.ico HTTP/1.1" 404 -

Y que en el navegador ha aparecido el Hola por defecto que estabas esperando.

¿Porque has puesto -p 8080:5000?. Esto es porque has mapeado el puerto 8080 al puerto 5000 del contenedor. Desde luego que podías haber mapeado el 5000 de tu equipo al 5000 del contenedor. Queda mucho mas explicativo de esta forma, donde puedes distinguir muy claramente cual es el puerto de tu equipo y cual el del contenedor. Si ahora, lo quisieras hacer como antes, simplemente tienes que ejecutar,

podman run -p 5000:5000 sample

Mapeando directorios

Otra cuestión que te habrás dado cuenta al visitar localhost:8080 es que de nuevo aparece el Hola por defecto, en lugar del contenido del archivo file.txt. Esto es porque no has incluido ni el directorio ni el archivo en la imagen. Pero no creas que ha sido un descuido, ha sido algo intencionado.

Igual que en el apartado anterior, has mapeado los puertos, en este vas a mapear volúmenes. Lo que harás, será indicarle al contenedor que un directorio de tu equipo es un directorio del contenedor. En concreto el directorio contenido. Para hacer esto ejecuta la siguiente instrucción,

podman run -p 8080:5000 -v "$PWD/contenido:/app/contenido sample"

De esta forma consigues mapear el contenido del directorio contenido en el directorio /app/contenido. ¿Y ese $PWD? Esto es debido a que mapeas rutas absolutas, y $PWD hace referencia al directorio en curso.

Si ahora abres el navegador en localhost:8080 verás el contenido del archivo file.txt. Es mas, si modificas el contenido de este archivo y actualizas, observarás que lo que ves en el navegador se corresponde con lo que acabas de dejar en el archivo.

Dejar el contenedor en segundo plano

Hasta ahora el contenedor siempre ha quedado en funcionamiento en primer plano, de forma que la única forma de seguir utilizando el terminal desde el que lo has lanzado, es haciendo un Ctrl+c. Sin embargo, sería interesante que este contenedor quedara funcionando en segundo plano. Para esto, tienes que utilizar la opción -d, pero además te recomiendo que le pongas nombre al contenedor, para que sea mas sencillo gestionarlo. Para hacer esto tienes que utilizar la opción --name. De esta forma la instrucción completa para ejecutar tu contenedor tendrá el siguiente aspecto,

podman run -d --name nombre  -p 5000:5000 -v "$PWD/contenido":/app/contenido sample

Al contenedor le he puesto el nombre nombre, de nuevo, en un alarde de imaginación, pero creo que así queda algo mas claro.

Algunas operaciones básicas

Ahora ya puedes exprimir al máximo todo lo que viste en los capítulos anteriores, referente a la gestión de contenedores e imágenes. En este sentido, algunas instrucciones interesantes,

  • podman ps lista los contenedores en ejecución.
  • podman stop nombre detendrá el contenedor de nombre nombre. De aquí, lo interesante de ponerle nombre a los contenedores.
  • podman start nombre, inicias el contenedor que detuviste en el paso anterior.
  • podman exec -it nombre sh te permite entrar en el contenedor y ver su contenido. Aquí puedes visitar el directorio contenido que realmente tienes mapeado en tu equipo.

Como te digo, esto es un empezar, y no parar, aquí ya puedes entretenerte, con todo lo que viste en capítulos anteriores.


Imagen de portada Andrey Sharpilo en Unsplash

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *