495 - Docker multiplataforma y otras decepciones
Aprende las ventajas de utilizar #Docker y #Podman en #linux, enfocada a las imágenes multiplataforma y como se adaptan a diferentes arquitecturas
Lo cierto es que estoy bailando entre Docker y Podman, y una de las razones para este baile es precisamente las imágenes multiplataforma. Si bien, estoy realmente satisfecho con el uso de Podman, y cada vez me siento mas cómodo, con esta alternativa, lo cierto es que esto de las imágenes multiplataforma, me ha trastocado bastante. Llevo algunos meses con esto de los Docker multiplataforma. Es una quimera que vengo persiguiendo desde hace algún tiempo, y que todavía no tengo domesticada. Y no tengo domesticada desde el punto de vista de Rust, pero ya lo he conseguido en otros aspectos, como por ejemplo, en el caso de croni
si que lo he conseguido y esto es precisamente de lo que te quiero hablar en este episodio del podcast, de Docker multiplataforma y otras decepciones.
En mi búsqueda por encontrar la mejor solución entre Docker y Podman, las imágenes multiplataforma han sido un factor clave. Aunque me siento muy satisfecho utilizando Podman y me voy acostumbrando cada vez más a esta alternativa, las imágenes multiplataforma me han planteado ciertos desafíos. Durante varios meses he estado explorando Docker en diferentes plataformas, persiguiendo una quimera que aún no he logrado dominar por completo. Sin embargo, he tenido éxito en otros aspectos, como el caso de croni
. En este episodio del podcast, quiero hablar sobre mi experiencia con Docker multiplataforma y algunas decepciones adicionales.
Docker multiplataforma y otras decepciones
Docker multiplataforma
Una de las características que tienes que tener en cuenta con Docker, Podman y en general cualquier otro tipo de imagen de contenedores es que dependen de la plataforma en que crees esas imágenes. Es decir, hay imágenes para amd64, arm64, windows, etc
Realmente no es exactamente así, porque es posible crear imágenes desde tu equipo para otras plataformas, lo cual es realmente interesante.
Pero voy un paso mas allá, y es que resulta, que si entras en DockerHub, verás que hay imágenes que son para una sola plataforma, y otras imágenes que son multiplataforma. Esto lo distinguirás fácilmente, aparecen las distintas arquitecturas bajo una misma etiqueta.
Y este es precisamente mi objetivo, imágenes multiplataforma. Se pueden hacer imágenes para cada plataforma, pero ya tienes que ir diciendo a cada uno que imagen tiene que descargar en función de su arquitectura. La cuestión es facilitar la experiencia al usuario final.
Seguro que en mas de una ocasión has intentado instalar una imagen y no podías instalarla a pesar que estaba en DockerHub, esto es debido precisamente a que no estaba preparada para tu arquitectura.
Sobre croni
Hace algún tiempo que implementé un contenedor con un cron en su interior. Esto lo he utilizado para automatizar determinados procesos, como puede ser el caso particular de FireFlyIII.
¿Porque no utilizar el propio cron de la máquina? La verdad es que podía utilizar el propio cron de la máquina, pero en mi caso, tengo algunas razones para hacerlo de esta manera,
- Por organización. Si tienes dentro del docker compose de la aplicación que quieres automatizar, el propio cron, está todo mas organizado.
- Limpieza. El cron es algo oculto. Algo que no tienes a primera vista, algo que puedes olvidar. A mi se me olvida lo que tengo en el cron, y se quedan en marcha procesos durante años, procesos que no hacen nada o si.
En las últimas semanas he actualizado croni, primero por hacerlo mas seguro, y posteriormente porque no funcionaba, o al menos a un usuario del grupo de Telegram atareao con Linux, no le funcionaba.
Es justo en este punto de que no le funcionara, precisamente, donde pensé que uno de los motivos por los que posiblemente no le funcionaba era porque lo estaba utilizando desde otra arquitectura. En esto me decidí a crear una imagen multiplataforma.
Mejoras en croni
Como comenté en un artículo del tutorial sobre Docker de buenas prácticas con los contenedores, una de las mejores prácticas que puedes hacer cuando creas una imagen es que la aplicación no se ejecute con root. Esto es algo, que no tengo implementado en todos mis contenedores, pero que estoy cambiando progresivamente.
Sin embargo, esto lleva una pena asociada, los permisos. Como gestionar los permisos, como utilizar volúmenes, etc.
En este sentido, hace ya algún tiempo, que comencé a utilizar los named volumes de Docker, lo que me solucionaba en parte este problema. Sin embargo, en ocasiones, como por ejemplo, en esta, es necesario leer de algún archivo.
La solución que le he dado es copiar el archivo del host
al contenedor. Con esto he conseguido resolver por completo el problema de los permisos en este caso.
croni multiplataforma
Sin embargo, en este punto seguí empeñado en que esta imagen fuera multiplataforma, y así, y a pesar de los miedos que tenía por mis experiencias previas, no quería dejar esto aquí así que me puse manos a la obra.
Aquí es donde me encontré con el primer escollo. Intenté hacer las imágenes multiplataforma directamente con Podman, y a pesar de que creía que lo había logrado, lo cierto es que no era así. Cuando comencé a probar las imágenes en diferentes arquitecturas, me di cuenta que no funcionaba, que aunque aparentemente era para cada una de las arquitecturas, lo cierto es que todas eran la misma.
Esto me ha llevado a reinstalar de nuevo Docker en mi equipo, después de unas semanas que ha estado ausente en mi equipo. Así, finalmente lo he tenido que instalar y además con todas las de la ley….
sudo pacman -S docker docker-buildx docker-compose
sudo systemctl start docker
Y a partir de aquí, lo siguiente,
docker run --privileged --rm tonistiigi/binfmt --install all
docker buildx create --name builder --driver docker-container --bootstrap --use
Y para construir la imagen,
docker buildx build \
--progress=plain \
--platform=linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7 \
--tag atareao/croni:latest \
--tag atareao/croni:v1.4 \
--push .
Y con esto he conseguido tener la imagen de croni
funcionando a la primera, mas o menos. Luego tuve que hacer algunos cambios menores, pero a pesar de esto, ha sido sencillo.
Tengo que decirte que en otra ocasión cuando he querido realizar la compilación, he tenido que ejecutar el siguiente comando,
docker buildx use builder
No te puedes hacer una idea como lo tenía con Podman. Lo cierto es que he estado haciendo muchas pruebas y finalmente he tenido que desistir.
Con Rust
Mi problema precisamente está con Rust. Y es que todo este lío que estoy montando, simplemente es para tener u2vpodcast
, disponible, no solo en amd64
, sino que también lo quiero en el resto de plataformas. La razón de querer tener arm64
es la de dar la posibilidad de que se pueda utilizar en la Raspberry.
Sin embargo, aquí precisamente es donde me encuentro atascado. Existe un crate, en concreto ring v0.16.20
, que no consigo compilarlo para otras arquitecturas que no sea amd64
.
Y lo que mas me molesta, es que esto, en la Raspberry si que he conseguido compilarlo, lo que me hace pensar que hay algo que no he configurado correctamente.
También te tengo que decir, que si bien compila en la Raspberry, lo cierto es que tarda lo que no está escrito, y llega a ser hasta desesperante. Con lo que tendremos que esperar.