Docker implementado en unas 100 líneas de Bash: Bocker (2015)
(github.com/p8952)- Bocker es un proyecto que implementa Docker en unas 100 líneas de Bash y ofrece un flujo similar a Docker, como hacer pull de imágenes, ejecutar contenedores, consultar logs, hacer commit y eliminar
- Para ejecutarlo se requieren btrfs-progs, curl, iproute2, iptables, libcgroup-tools, util-linux 2.25.2 o superior y coreutils 7.5 o superior; además, se necesita un sistema de archivos btrfs bajo
/var/bockery una configuración de redbridge0 - El ejemplo del README muestra un flujo en el que se hace pull de la imagen
centos:7, luego se ejecutan comandos en un contenedor y se hace commit del resultado deyum install -y wgetpara verificar/usr/bin/wgeten ejecuciones posteriores - Bocker se ejecuta como root y modifica interfaces de red, tablas de ruteo y reglas de firewall, por lo que se recomienda ejecutarlo en una máquina virtual; no hay garantías sobre posibles daños al sistema
- Actualmente implementa
docker pull,images,ps,run,exec,logs,commit,rm/rmi, networking y cuotas basadas en CGroups, pero aún no implementa volúmenes de datos, contenedores de volúmenes de datos ni port forwarding
Objetivo y alcance de Bocker
- Bocker es un proyecto que implementa Docker en unas 100 líneas de Bash
- El README muestra un flujo de comandos similar al de Docker basado en Bash, e incluye funciones como gestión de imágenes, ejecución de contenedores, consulta de logs, commit de cambios y límites de recursos
Requisitos de ejecución
- Los paquetes necesarios para ejecutarlo son los siguientes
-
btrfs-progs
- curl
- iproute2
- iptables
- libcgroup-tools
- util-linux 2.25.2 o superior
- coreutils 7.5 o superior
- Como la mayoría de las distribuciones no incluye una versión suficientemente reciente de util-linux, es posible que sea necesario descargar el código fuente de util-linux 2.25 y compilarlo manualmente
- El sistema necesita la siguiente configuración
- Un sistema de archivos btrfs montado bajo
/var/bocker - Un bridge de red llamado
bridge0con la IP10.0.0.1/24 - IP forwarding habilitado en
/proc/sys/net/ipv4/ip_forward - Configuración de firewall que rutee el tráfico desde
bridge0hacia la interfaz física - Se incluye un Vagrantfile para crear fácilmente el entorno necesario
-
Precauciones al ejecutarlo
- Aunque se cumplan los requisitos, se recomienda ejecutar Bocker en una máquina virtual
- Bocker se ejecuta como root y debe modificar los siguientes elementos
- Interfaces de red
- Tablas de ruteo
- Reglas de firewall
- El README indica explícitamente que no puede garantizarse que Bocker no rompa el sistema
Flujo de uso de ejemplo
- Al traer la imagen
centos:7conbocker pull centos 7, se genera un ID de imagen comoimg_42150 bocker imagesmuestra el ID de la imagen y su origen- Salida de ejemplo:
img_42150,centos:7
- Salida de ejemplo:
bocker run img_42150 cat /etc/centos-releaseimprime la información de la versión de CentOS dentro del contenedor- Salida de ejemplo:
CentOS Linux release 7.1.1503 (Core)
- Salida de ejemplo:
bocker psmuestra el ID del contenedor ejecutado y el comandobocker logs ps_42045muestra los logs de salida de ese contenedorbocker rm ps_42045elimina el contenedor- Al ejecutar
bocker run img_42150 which wget, inicialmente el resultado indica quewgetno existe - Después de instalar
wgetconbocker run img_42150 yum install -y wget, los cambios se reflejan en la imagen conbocker commit ps_42018 img_42150 - Luego,
bocker run img_42150 which wgetimprime/usr/bin/wget
Límites de recursos y CGroups
- El ejemplo de ejecución de Bocker muestra que los contenedores se colocan bajo CGroups
- En
/proc/1/cgroupaparecen entradas comomemory:/ps_42152ycpuacct,cpu:/ps_42152
- En
- Los ejemplos de CPU share y límite de memoria predeterminados son los siguientes
/sys/fs/cgroup/cpu/ps_42152/cpu.shares:512/sys/fs/cgroup/memory/ps_42152/memory.limit_in_bytes:512000000
- Los límites de recursos se pueden cambiar mediante variables de entorno
BOCKER_CPU_SHARE=1024BOCKER_MEM_LIMIT=1024
- El ejemplo posterior al cambio muestra los siguientes valores
- CPU shares:
1024 - límite de memoria:
1024000000
- CPU shares:
Funciones implementadas y no implementadas
- Las funciones actualmente implementadas son las siguientes
docker build†docker pulldocker imagesdocker psdocker rundocker execdocker logsdocker commitdocker rm/docker rmi-
Networking
- Soporte de cuotas / CGroups
- †
bocker initofrece una implementación muy limitada dedocker build - Las funciones aún no implementadas son las siguientes
- Contenedores de volúmenes de datos
- Volúmenes de datos
- Port forwarding
Licencia
- Bocker es software libre que puede redistribuirse y modificarse bajo los términos de la GNU General Public License
- La versión de la licencia puede ser GPL v3 publicada por la Free Software Foundation, o cualquier versión posterior
- El programa se distribuye con la esperanza de que sea útil, pero sin ninguna garantía implícita de comerciabilidad o adecuación para un propósito particular
1 comentarios
Opiniones de Hacker News
Una vez hice algo parecido con proot; se llamaba Bag [1] y no creo haberlo descrito como una alternativa a Docker.
No tenía relación con cgroups, y la interfaz de línea de comandos también era distinta a la de Docker. El contexto era que, para evadir la censura en internet y la inspección profunda de paquetes, hice una cadena de proxies que parecía tráfico HTML normal; necesitaba que siguiera ejecutándose en cualquier lugar, pero no quería portarla como app nativa de Android.
Quería correrla en Termux, pero en ese momento Termux no tenía JDK/JRE, y si levantaba un entorno Arch Linux con proot podía usar el JDK. El entorno Arch dentro de Termux era en general más útil, y también era fácil automatizar con scripts la creación y eliminación de entornos desechables con distintas configuraciones, para luego entrar con proot y ejecutar solo un comando. Por eso lo llamé bag.sh, con la idea de que era una forma mucho más pequeña que un contenedor de carga.
Curiosamente, bag.sh todavía conserva un roadmap/TODO que no he tocado en 5 años. Como lo escribí en una pantalla móvil y quería verlo sin hacer scroll, la mayor parte está alineada a 40 columnas.
[1]: https://github.com/hkoosha/bag
Armé un Debian pequeño dentro de /opt con el software necesario y dependencias como MySQL, y funcionó bastante bien; se usó hasta que la empresa para la que lo hice fue adquirida, alrededor de 2016. Más en general, creo que implementar por cuenta propia una versión rudimentaria de una aplicación grande es una de las mejores formas de aprender cómo funciona por dentro.
mkdir -p $(dirname "$2")Combinada con un teclado Bluetooth de unas 10 pulgadas que cabe cómodamente en el bolsillo interior de una chaqueta de cuero, puedes salir de casa sin mochila, sentarte en un rincón de un biergarten cercano y escribir código. Sorprendentemente también puede ser productivo: quizá porque hay un poco más de fricción que en una laptop para cambiar a las distracciones habituales, uno termina mirando fijamente el código mientras da un sorbo de cerveza.
Me gustan estas cosas. Siempre me han gustado las cosas hechas con Bash mínimo.
También hay una prueba de concepto de balanceador de carga interno de clúster en 40 líneas de Bash que hicimos en un hackatón organizado hace unos 10 años para promover infraestructura distribuida como Docker y Mesos: https://github.com/cell-os/metal-cell/blob/master/discovery/...
Probablemente lo perdí, pero también tenía una herramienta de transferencia de colo a cloud basada en túneles SSH inversos, con redundancia y distribución. En sitios como Shell Fu hay buenas colecciones de este tipo: https://www.shell-fu.org/
El hecho de que se pueda reimplementar de forma tan simple una gran parte de Docker es el mayor problema que enfrentó, y sigue enfrentando, Docker como empresa. En el fondo, se parece más a código pegamento que conecta funcionalidades del kernel.
Donde Docker realmente agrega valor no es solo Docker Hub, sino Docker for Windows y Mac. La experiencia integrada es mucho mejor que tener que lidiar uno mismo con VirtualBox y Vagrant para correr Docker en una máquina de desarrollo.
Personalmente, creo que la verdadera magia de Docker fue el formato de imágenes Docker/OCI. Maneja muy bien el caching y la distribución de imágenes de contenedores, y sigue siendo la pieza clave que lo diferencia de las VM “completas” y sus flujos de trabajo.
En Windows puedes usar Docker en WSL y funciona muy bien. Me cuesta entender por qué alguien usaría Docker Desktop.
En cambio, hizo un Docker Swarm flojo que no funcionaba de manera confiable, y Kubernetes lo desplazó rápidamente.
La única forma en que yo lo usé fue para traerme el entorno virtual de build de otra persona y compilar software hace algunos años.
Me gusta ver frases como “aún no implementado”, “TODO” o “en progreso” en un repositorio cuando el último commit fue hace años.
Me hace sentir un poco mejor por no volver a revisar los TODO que dejé regados en mi código. No es que quiera menospreciar al autor; simplemente me consuela.
Si en código no remunerado, voluntario o de hobby uno siente la presión de tener que hacerlo solo porque está publicado, programar se vuelve menos divertido y quizá uno termine no publicando código que originalmente habría publicado.
Si siempre hay una idea siguiente, por definición siempre quedarán TODO sin terminar. De hecho, ese debería ser el estado normal de todos los proyectos.
Está perfectamente bien, y a menudo ayuda, poner límites claros al alcance. Así evitas perseguir desvíos y terminar con la sensación de que el proyecto nunca está “terminado”.
Me sorprende que todavía no se haya mencionado lazydocker como una excelente alternativa a Docker Desktop. Se puede usar en Linux/macOS/Windows [1]
Es una interfaz de terminal bastante completa, y además tiene la ventaja de poder ejecutarse a través de SSH.
[1] https://github.com/jesseduffield/lazydocker
Al menos yo nunca había visto algo así. También me pregunto si ese tipo de anuncios está permitido por los términos de servicio o la política de uso aceptable de GitHub.
Me pregunto por qué Bocker llega tan seguido a la portada. ¿Docker sigue siendo tan polémico en 2024?
No entiendo por qué no se reconoce que Docker trajo cosas realmente útiles, principalmente distribución de software y “ejecutar fácilmente en cualquier lugar”.
Docker es una combinación de tecnologías del kernel que ya existían: namespaces, cgroups, sistemas de archivos union y probablemente algunas más.
Por eso resulta interesante y, en la práctica, es una historia perfecta para HN.
Recién después de mostrárselo a varias personas me di cuenta de que podrían haber usado simplemente
/, o de que yo también podría haberles llevado Docker.Como una especie de hermano de otra madre, está https://bastillebsd.org/
Bastille usa muchas estructuras que uno esperaría ver en Docker, implementadas en shell, para administrar jails de FreeBSD. Tiene muy pocas dependencias, por eso me gusta más que otro software de administración de jails en BSD.
Aunque, aun siendo una herramienta basada en CLI/TUI, es una solución casi de “máximo exceso”. Últimamente estoy pasando por los pasos de crear y administrar jails solo con la configuración básica de FreeBSD, pero esto es apenas una etapa temporal.
Lo haré solo hasta que tenga lo bastante grabado en la cabeza cómo encaja todo como para sentirme seguro depurando; después, como una persona sensata, dejaré de golpear piedras entre sí y volveré a herramientas de más alto nivel.
Pero me tomó un tiempo entender por qué se llama Bastille. La Bastilla fue una fortaleza construida para defender París de los ataques ingleses durante la Guerra de los Cien Años, y más tarde se convirtió en prisión.
Hay que tener cuidado con la parte que dice: “la mayoría de las distribuciones no ofrecen una versión suficientemente reciente de util-linux, así que probablemente tendrás que obtener el código fuente de aquí y compilarlo tú mismo”.
El prefijo de instalación predeterminado es
/usr/bin, así que el proceso de instalación puede sobrescribir el comando mount existente con una versión que requiere bibliotecas que no existen. Entonces, en el siguiente arranque, el kernel montará el sistema de archivos en modo solo lectura./usr/local/bin.No es bueno para uso diario, pero da una idea de qué es Docker y cómo funciona.
En Linux, Docker es básicamente un chroot sofisticado.
Dato curioso: Docker empezó en Bash, luego pasó a Python y finalmente se asentó en Go.
Además, en un meetup de Docker en 2013, alguien escribió un clon de Docker en Bash. La gente quiere aprender, y ojalá estas cosas ayuden.