El fin de semana pasado, tuve la fortuna de poder asistir al meetup de Docker, donde nos dieron un curso de Docker para principiantes. A pesar de las dificultades presentadas, ya que al ser un curso totalmente gratuito, a base del esfuerzo de la comunidad se logró bastante bien.
En este primer post, les compartiré mis notas del curso.
En el #SysArmyMxTalks previo, el buen Iván Chavero, nos habló de los fundamentos de los contenedores, si quieren revisar el material, lo encuentran en los enlaces:
Durante el curso, nos dieron una breve introducción a docker, además de ver un fragmento del vídeo de la presentación de Jessie Frazell:
Después de esto, iniciamos con la parte práctica:
Comandos básicos
1. Después de instalar docker, es necesario habilitarlo e iniciarlo
sudo systemctl status docker [sudo] password for alex.callejas: ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: dis Active: inactive (dead) Docs: http://docs.docker.com $ sudo systemctl enable docker Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service. $ sudo systemctl start docker
2. Para correr un contenedor mediante docker con nginx, ejecutamos
sudo docker run nginx Unable to find image 'nginx:latest' locally Trying to pull repository registry.fedoraproject.org/nginx ... Trying to pull repository registry.access.redhat.com/nginx ... Trying to pull repository docker.io/library/nginx ... sha256:788fa27763db6d69ad3444e8ba72f947df9e7e163bad7c1f5614f8fd27a311c3: Pulling from docker.io/library/nginx 94ed0c431eb5: Pull complete 9406c100a1c3: Pull complete aa74daafd50c: Pull complete Digest: sha256:788fa27763db6d69ad3444e8ba72f947df9e7e163bad7c1f5614f8fd27a311c3 Status: Downloaded newer image for docker.io/nginx:latest $
Como es una imagen que no tenemos en un repositorio local, la descarga del repositorio oficial de docker.
3. Si abrimos una terminal alterna, podemos observar que el contenedor se esta ejecutando
sudo docker ps [sudo] password for alex.callejas: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2127ad18758a nginx "nginx -g 'daemon ..." 30 seconds ago Up 29 seconds 80/tcp cocky_joliot $
Se observa que, por default, docker nombra el contenedor como cocky_joliot, esto es debido a que si no especificamos un nombre del contenedor, docker por convención utilizará un adjetivo y el apellido de algún científico (según el código fuente de docker)
4. También podemos ejecutar un contenedor de forma interactiva con una TTY
sudo docker run ubuntu bash Unable to find image 'ubuntu:latest' locally Trying to pull repository registry.fedoraproject.org/ubuntu ... Trying to pull repository registry.access.redhat.com/ubuntu ... Trying to pull repository docker.io/library/ubuntu ... sha256:34471448724419596ca4e890496d375801de21b0e67b81a77fd6155ce001edad: Pulling from docker.io/library/ubuntu d5c6f90da05d: Pull complete 1300883d87d5: Pull complete c220aa3cfc1b: Pull complete 2e9398f099dc: Pull complete dc27a084064f: Pull complete Digest: sha256:34471448724419596ca4e890496d375801de21b0e67b81a77fd6155ce001edad Status: Downloaded newer image for docker.io/ubuntu:latest $ sudo docker run -it ubuntu bash root@a656df585428:/# root@a656df585428:/# ps PID TTY TIME CMD 1 ? 00:00:00 bash 11 ? 00:00:00 ps root@51728d60a8a8:/# pwd / root@51728d60a8a8:/# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr root@51728d60a8a8:/# exit exit $
Se observa que, dentro del contenedor, solamente existe el proceso de bash que ejecutamos, además de contar con toda la estructura de directorios del sistema.
5. En la terminal alterna, podemos observar la ejecución del contenedor
sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a656df585428 ubuntu "bash" 45 seconds ago Exited (0) 28 seconds agonifty_payne 2127ad18758a nginx "nginx -g 'daemon ..." 3 minutes ago Exited (0) 2 minutes ago cocky_joliot $
Con la opción -a, podemos ver todos los contenedores que hemos ejecutado, por default solo se muestran los que se encuentran en ejecución actualmente.
6. Si queremos eliminar un contenedor, utilizamos su CONTAINER ID, de la salida del ps ejecutando
sudo docker rm 2127ad18758a 2127ad18758a $ sudo docker rm a656df585428 a656df585428 $
Al revisar en la terminal alterna, ya no se observa dicho contenedor
sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $
7. Se le puede indicar al contenedor que se ejecute en background y que utilice un puerto local en particular
sudo docker run -d -p 80:80 nginx c81ee76d8cd0b3180b4d543c9d266d13dc1302d396207412eab80d10b091d269 $
Se observa en la terminal alterna, que el proceso se ejecute en el puerto asignado
sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c81ee76d8cd0 nginx "nginx -g 'daemon ..." 5 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp tender_montalcini $
Podemos revisar con el navegador o con curl que el contenedor nos muestre la página de prueba de nginx en el puerto local configurado
Para detener el contenedor, sin eliminarlo, utilizamos su CONTAINER ID o su nombre
sudo docker stop tender_montalcini tender_montalcini $
8. Si lo deseamos, podemos ejecutar un contenedor con un nombre en particular
sudo docker run --name test -d -p 80:80 nginx a13f3e75ea522646ca6b1b6a926cdf680b636924bdbf2c2942b7249acff0e513 $
Lo revisamos en la terminal alterna
sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a13f3e75ea52 nginx "nginx -g 'daemon ..." 3 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp test $
También podemos obtener estadísticas ejecutando
sudo docker stats CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS a13f3e75ea52 0.01% 1.969 MiB / 7.493 GiB 0.03% 7.68 kB / 936 B 0 B / 0 B 2
Estas se muestran en tiempo real.
9. Con el contenedor ejecutándose, también podemos indicarle que corra algún comando en particular, por ejemplo
sudo docker exec -it test bash [sudo] password for alex.callejas: root@a13f3e75ea52:/# root@a13f3e75ea52:/# ps bash: ps: command not found root@a13f3e75ea52:/# exit exit $
En este caso en particular, le indicamos que ejecutara, de forma interactiva bash, sin embargo se observa que la imagen del contenedor no tiene el comando ps. Esto puede ser debido a que cuando se creo la imagen, no se le incluyó dicho comando o comandos; esto se puede realizar para que la imagen del contenedor tenga una característica de seguridad en caso de ser necesario.
El proceso para generar la imagen de esta forma se profundizará en una sesión posterior.
10. Para revisar la configuración general del contenedor, ejecutamos
sudo docker inspect test [ { "Id": "a13f3e75ea522646ca6b1b6a926cdf680b636924bdbf2c2942b7249acff0e513", "Created": "2017-08-12T15:37:29.101171417Z", "Path": "nginx", "Args": [ "-g", "daemon off;" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 6912, "ExitCode": 0, "Error": "", "StartedAt": "2017-08-12T15:37:29.606735048Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:b8efb18f159bd948486f18bd8940b56fd2298b438229f5bd2bcf4cedcf037448", "ResolvConfPath": "/var/lib/docker/containers/a13f3e75ea522646ca6b1b6a926cdf680b636924bdbf2c2942b7249acff0e513/resolv.conf", ...
Salida completa de la inspección: inspect_test.txt
También podemos obtener información de la inspección en formato de Go
sudo docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' test 172.17.0.2 $ sudo docker inspect --format='{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}' test 172.17.0.1 $
11. Para listar las imágenes que hemos utilizado, ejecutamos
sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/ubuntu latest ccc7a11d65b1 43 hours ago 120 MB docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB $
Creación de imágenes
12. La primer opción, aunque no la mejor nos comentaron, es utilizar una imagen básica de algún Sistema Operativo y adecuarla a nuestras necesidades. Por ejemplo, si queremos una imagen de vim, primeramente ejecutamos de forma interactiva una imagen base, para nuestro caso, de fedora e instalamos el paquete de forma tradicional
sudo docker run -it fedora bash [root@057ce3fd873e /]# dnf install vim Fedora 25 - x86_64 2.7 MB/s | 50 MB 00:18 Fedora 25 - x86_64 - Updates 3.8 MB/s | 25 MB 00:06 Last metadata expiration check: 0:00:06 ago on Sat Aug 12 15:51:37 2017. Dependencies resolved. ======================================================================================= Package Arch Version Repository Size ======================================================================================= Installing: gpm-libs x86_64 1.20.7-9.fc24 fedora 36 k perl-Carp noarch 1.40-365.fc25 fedora 29 k perl-Exporter noarch 5.72-366.fc25 fedora 33 k perl-libs x86_64 4:5.24.2-387.fc25 updates 1.5 M vim-common x86_64 2:8.0.823-1.fc25 updates 6.7 M vim-enhanced x86_64 2:8.0.823-1.fc25 updates 1.3 M vim-filesystem x86_64 2:8.0.823-1.fc25 updates 35 k which x86_64 2.21-1.fc25 fedora 46 k Transaction Summary ======================================================================================= Install 8 Packages Total download size: 9.6 M Installed size: 37 M Is this ok [y/N]: y Downloading Packages: (1/8): which-2.21-1.fc25.x86_64.rpm 71 kB/s | 46 kB 00:00 (2/8): gpm-libs-1.20.7-9.fc24.x86_64.rpm 56 kB/s | 36 kB 00:00 (3/8): perl-libs-5.24.2-387.fc25.x86_64.rpm 1.0 MB/s | 1.5 MB 00:01 (4/8): perl-Carp-1.40-365.fc25.noarch.rpm 213 kB/s | 29 kB 00:00 (5/8): perl-Exporter-5.72-366.fc25.noarch.rpm 244 kB/s | 33 kB 00:00 (6/8): vim-enhanced-8.0.823-1.fc25.x86_64.rpm 524 kB/s | 1.3 MB 00:02 (7/8): vim-filesystem-8.0.823-1.fc25.x86_64.rpm 249 kB/s | 35 kB 00:00 (8/8): vim-common-8.0.823-1.fc25.x86_64.rpm 1.3 MB/s | 6.7 MB 00:05 --------------------------------------------------------------------------------------- Total 1.3 MB/s | 9.6 MB 00:07 warning: /var/cache/dnf/updates-87ad44ec2dc11249/packages/vim-enhanced-8.0.823-1.fc25.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID fdb19c98: NOKEY Importing GPG key 0xFDB19C98: Userid : "Fedora 25 Primary (25) <fedora-25-primary@fedoraproject.org>" Fingerprint: C437 DCCD 558A 66A3 7D6F 4372 4089 D8F2 FDB1 9C98 From : /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-25-x86_64 Is this ok [y/N]: y Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Installing : perl-Carp-1.40-365.fc25.noarch 1/8 Installing : perl-Exporter-5.72-366.fc25.noarch 2/8 Installing : perl-libs-4:5.24.2-387.fc25.x86_64 3/8 Installing : vim-filesystem-2:8.0.823-1.fc25.x86_64 4/8 Installing : vim-common-2:8.0.823-1.fc25.x86_64 5/8 Installing : which-2.21-1.fc25.x86_64 6/8 Installing : gpm-libs-1.20.7-9.fc24.x86_64 7/8 Installing : vim-enhanced-2:8.0.823-1.fc25.x86_64 8/8 Verifying : vim-enhanced-2:8.0.823-1.fc25.x86_64 1/8 Verifying : gpm-libs-1.20.7-9.fc24.x86_64 2/8 Verifying : which-2.21-1.fc25.x86_64 3/8 Verifying : vim-common-2:8.0.823-1.fc25.x86_64 4/8 Verifying : perl-libs-4:5.24.2-387.fc25.x86_64 5/8 Verifying : perl-Carp-1.40-365.fc25.noarch 6/8 Verifying : perl-Exporter-5.72-366.fc25.noarch 7/8 Verifying : vim-filesystem-2:8.0.823-1.fc25.x86_64 8/8 Installed: gpm-libs.x86_64 1.20.7-9.fc24 perl-Carp.noarch 1.40-365.fc25 perl-Exporter.noarch 5.72-366.fc25 perl-libs.x86_64 4:5.24.2-387.fc25 vim-common.x86_64 2:8.0.823-1.fc25 vim-enhanced.x86_64 2:8.0.823-1.fc25 vim-filesystem.x86_64 2:8.0.823-1.fc25 which.x86_64 2.21-1.fc25 Complete! [root@057ce3fd873e /]# exit exit $
Identificamos el nombre del contenedor, con ayuda de la terminal alterna
sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 057ce3fd873e fedora "bash" 2 minutes ago Exited (0) About a minute ago infallible_fermat a13f3e75ea52 nginx "nginx -g 'daemon ..." 16 minutes ago Up 16 minutes 0.0.0.0:80->80/tcp test $
Y hacemos commit al cambio en la imagen, identificándola con un mensaje descriptivo y un nuevo nombre
sudo docker commit -m "testvim" infallible_fermat imagenvim sha256:663643920fdd5323b62b0e088a3233a4c95affd91b98b23e5ec25e8cddfd12c3 $
Al revisar las imágenes observamos
sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
imagenvim latest 663643920fdd 12 seconds ago 452 MB
docker.io/ubuntu latest ccc7a11d65b1 43 hours ago 120 MB
docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB
registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB
$
Existe una importante diferencia en el tamaño de la imagen base contra la imagen que creamos, esto depende de los paquetes que instalamos.
Al ejecutar vim dentro del contenedor, funciona correctamente
sudo docker run -it imagenvim [root@c4e11a2ac378 /]# vim ~ ~ ~ ~ ~ VIM - Vi IMproved ~ ~ version 8.0.885 ~ by Bram Moolenaar et al. ~ Modified by <bugzilla@redhat.com> ~ Vim is open source and freely distributable ~ ~ Become a registered Vim user! ~ type :help register<Enter> for information ~ ~ type :q<Enter> to exit ~ type :help<Enter> or <F1> for on-line help ~ type :help version8<Enter> for version info ~ ~ :q! [root@c4e11a2ac378 /]# exit exit $
Podemos revisar la diferencia de imágenes usando el id del contenedor:
sudo docker ps -a [sudo] password for alex.callejas: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c4e11a2ac378 imagenvim "bash" 41 minutes ago Exited (0) 40 minutes ago clever_meitner 057ce3fd873e fedora "bash" 44 minutes ago Exited (0) 42 minutes ago infallible_fermat $ $ sudo docker diff c4e11a2ac378 C /root C /root/.bash_history A /root/.viminfo $ sudo docker diff 057ce3fd873e C /etc C /etc/ld.so.cache C /etc/pki/nssdb C /etc/pki/nssdb/cert9.db C /etc/pki/nssdb/key4.db C /etc/profile.d A /etc/profile.d/vim.csh A /etc/profile.d/vim.sh A /etc/profile.d/which2.csh A /etc/profile.d/which2.sh A /etc/vimrc C /root A /root/.bash_history D /root/.pki ...
Salida completa de la diferencia: diff_imagenvim.txt
13. La otra forma de crear una imagen, es generando un archivo Dockerfile con las instrucciones de personalización del contenedor. Utilizando el mismo ejemplo, creamos el archivo Dockerfile (por convención, así debe llamarse) con la información necesaria
vim Dockerfile FROM fedora RUN dnf update -y && dnf install -y vim $
Y ejecutamos la construcción de la imagen
sudo docker build -t imagenvim:2 . Sending build context to Docker daemon 2.048 kB Step 1/2 : FROM fedora ---> 7f17e6b4a386 Step 2/2 : RUN dnf update -y && dnf install -y vim ---> Running in 8b8e9e66ca8a Last metadata expiration check: 0:00:18 ago on Sat Aug 12 16:01:33 2017. Dependencies resolved. ================================================================================ Package Arch Version Repository Size ================================================================================ Upgrading: curl x86_64 7.51.0-8.fc25 updates 307 k dbus x86_64 1:1.11.16-1.fc25 updates 255 k dbus-libs x86_64 1:1.11.16-1.fc25 updates 175 k emacs-filesystem noarch 1:25.2-3.fc25 updates 66 k expat x86_64 2.2.3-1.fc25 updates 86 k file-libs x86_64 5.29-7.fc25 updates 497 k glibc x86_64 2.24-9.fc25 updates 3.3 M glibc-common x86_64 2.24-9.fc25 updates 879 k glibc-langpack-en x86_64 2.24-9.fc25 updates 282 k gnutls x86_64 3.5.14-1.fc25 updates 754 k krb5-libs x86_64 1.14.4-8.fc25 updates 741 k libcrypt-nss x86_64 2.24-9.fc25 updates 44 k libcurl x86_64 7.51.0-8.fc25 updates 267 k libdb x86_64 5.3.28-24.fc25 updates 750 k libdb-utils x86_64 5.3.28-24.fc25 updates 139 k libgcc x86_64 6.4.1-1.fc25 updates 95 k libgcrypt x86_64 1.7.8-1.fc25 updates 435 k libidn2 x86_64 2.0.3-1.fc25 updates 97 k libsolv x86_64 0.6.28-5.fc25 updates 366 k libsss_idmap x86_64 1.15.3-1.fc25 updates 83 k libsss_nss_idmap x86_64 1.15.3-1.fc25 updates 81 k nspr x86_64 4.15.0-1.fc25 updates 137 k nss x86_64 3.31.0-1.1.fc25 updates 862 k nss-softokn x86_64 3.31.0-1.0.fc25 updates 385 k nss-softokn-freebl x86_64 3.31.0-1.0.fc25 updates 224 k nss-sysinit x86_64 3.31.0-1.1.fc25 updates 61 k nss-tools x86_64 3.31.0-1.1.fc25 updates 504 k nss-util x86_64 3.31.0-1.0.fc25 updates 87 k openldap x86_64 2.4.44-11.fc25 updates 352 k pcre x86_64 8.41-1.fc25 updates 199 k sqlite-libs x86_64 3.14.2-2.fc25 updates 454 k sssd-client x86_64 1.15.3-1.fc25 updates 134 k systemd x86_64 231-17.fc25 updates 2.8 M systemd-libs x86_64 231-17.fc25 updates 421 k systemd-pam x86_64 231-17.fc25 updates 178 k tar x86_64 2:1.29-4.fc25 updates 814 k vim-minimal x86_64 2:8.0.823-1.fc25 updates 525 k Transaction Summary ================================================================================ Upgrade 37 Packages Total download size: 18 M Downloading Packages: /usr/share/doc/file-libs/ChangeLog: No such file or directory cannot reconstruct rpm from disk files ... Verifying : vim-filesystem-2:8.0.823-1.fc25.x86_64 8/8 Installed: gpm-libs.x86_64 1.20.7-9.fc24 perl-Carp.noarch 1.40-365.fc25 perl-Exporter.noarch 5.72-366.fc25 perl-libs.x86_64 4:5.24.2-387.fc25 vim-common.x86_64 2:8.0.823-1.fc25 vim-enhanced.x86_64 2:8.0.823-1.fc25 vim-filesystem.x86_64 2:8.0.823-1.fc25 which.x86_64 2.21-1.fc25 Complete! ---> 6306acd85190 Removing intermediate container 8b8e9e66ca8a Successfully built 6306acd85190 $
Salida completa de la construcción de la imagen: build_imagenvim2.txt
Al ejecutar vim dentro del contenedor, funciona correctamente
sudo docker run -it imagenvim:2 [root@aa039e84b63b /]# vim ~ ~ ~ ~ ~ VIM - Vi IMproved ~ ~ version 8.0.885 ~ by Bram Moolenaar et al. ~ Modified by <bugzilla@redhat.com> ~ Vim is open source and freely distributable ~ ~ Become a registered Vim user! ~ type :help register<Enter> for information ~ ~ type :q<Enter> to exit ~ type :help<Enter> or <F1> for on-line help ~ type :help version8<Enter> for version info ~ ~ :q! [root@aa039e84b63b /]# [root@aa039e84b63b /]# uname -a Linux aa039e84b63b 4.11.11-300.fc26.x86_64 #1 SMP Mon Jul 17 16:32:11 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux [root@aa039e84b63b /]# exit exit $
Al listar las imágenes, observamos
sudo docker images [sudo] password for alex.callejas: REPOSITORY TAG IMAGE ID CREATED SIZE imagenvim 2 6306acd85190 26 minutes ago 519 MB imagenvim latest 663643920fdd 35 minutes ago 452 MB docker.io/ubuntu latest ccc7a11d65b1 44 hours ago 120 MB docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB $
A esta nueva imagen, le podemos asignar una etiqueta diferente para poder diferenciarla
sudo docker tag imagenvim:2 axl/imagenvim2 $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE axl/imagenvim2 latest 6306acd85190 28 minutes ago 519 MB imagenvim 2 6306acd85190 28 minutes ago 519 MB imagenvim latest 663643920fdd 37 minutes ago 452 MB docker.io/ubuntu latest ccc7a11d65b1 44 hours ago 120 MB docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB $
Podemos, además, guardar esta imagen como archivo
sudo docker save -o imagenvim2 axl/imagenvim2
$ ls
Dockerfile imagenvim2
$ sudo file imagenvim2
imagenvim: POSIX tar archive
$ du -sh imagenvim2
509M imagenvim2
$
Con lo cual, podríamos portar la imagen a algún lugar, incluso por USB y exportarla. Para este ejemplo, primero eliminamos la imagen
sudo docker rmi axl/imagenvim2 Untagged: axl/imagenvim2:latest $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE imagenvim 2 6306acd85190 2 days ago 519 MB imagenvim latest 663643920fdd 2 days ago 452 MB docker.io/ubuntu latest ccc7a11d65b1 4 days ago 120 MB docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB $
Para cargar esta imagen en algún otro equipo, después de transferir dicha imagen, utilizamos el comando
sudo docker load -i imagenvim2 Loaded image: axl/imagenvim2:latest $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE cosasaxl latest 2b76fbb9ebba 2 days ago 147 MB axl/imagenvim2 latest 6306acd85190 2 days ago 519 MB docker.io/ubuntu latest ccc7a11d65b1 4 days ago 120 MB docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB docker.io/debian latest a20fd0d59cf1 3 weeks ago 100 MB registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB $
Volúmenes
La información de los contenedores es efímera, pero si requerimos que se monte algún directorio en particular o que los datos sean persistentes, utilizamos volúmenes.
14. Si requerimos que nuestro contenedor incluya algún directorio en particular, ejecutamos
sudo docker run -it -v /directorio ubuntu bash
[sudo] password for alex.callejas:
root@46e6e1cc5fc1:/# ls
bin boot dev directorio etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@46e6e1cc5fc1:/# ls directorio/
root@46e6e1cc5fc1:/# touch directorio/hola
root@46e6e1cc5fc1:/# ls directorio/
hola
root@46e6e1cc5fc1:/# mkdir -p directorio/test
root@46e6e1cc5fc1:/# touch directorio/test/hola
root@46e6e1cc5fc1:/#
root@46e6e1cc5fc1:/# ls -l directorio/*
-rw-r--r--. 1 root root 0 Aug 12 02:24 directorio/hola
directorio/test:
total 0
-rw-r--r--. 1 root root 0 Aug 12 02:25 hola
root@46e6e1cc5fc1:/# exit
exit
$
En la terminal alterna, inspeccionamos el contenedor, para revisar los montajes
sudo docker ps [sudo] password for alex.callejas: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 540ee1c3cc95 ubuntu "bash" 25 seconds ago Up 24 seconds gracious_lamarr $ sudo docker inspect --format='{{range .Mounts}}{{.Destination}}{{end}}' gracious_lamarr /directorio $ sudo docker inspect --format='{{range .Mounts}}{{.Source}}{{end}}' gracious_lamarr /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data $
Por default, docker crea un directorio en el host para poder montarlo en el contenedor. Esto lo podemos revisar,como root, directamente en el host
# ls -ld /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data drwxr-xr-x. 2 root root 4096 Aug 12 21:32 /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data # ls /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data hola test # ls /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data/* /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data/hola /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data/test: hola #
15. Si queremos que el contenedor utilice algún directorio del host en particular, ejecutamos
mkdir directorio
$ ls
directorio Dockerfile imagenvim2
$ sudo docker run -it -v $PWD/directorio:/directorio ubuntu bash
root@4230a22ebcd5:/# ls
bin boot dev directorio etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@4230a22ebcd5:/# ls directorio/
ls: cannot open directory 'directorio/': Permission denied
root@4230a22ebcd5:/# touch directorio/hola
touch: cannot touch 'directorio/hola': Permission denied
root@4230a22ebcd5:/#
Se montó correctamente el directorio dentro del contenedor, pero no tenemos permiso de escritura debido a que el daemon de docker lo monta como root, como se observo en la inspección anterior. Para poder escribir, necesitamos indicarle al contenedor los permisos que requerimos, ejecutando
sudo docker run -it -v $PWD/test:/prueba:ro ubuntu bash root@59c188463618:/# ls bin boot dev etc home lib lib64 media mnt opt proc prueba root run sbin srv sys tmp usr var root@59c188463618:/# ls prueba/ ls: cannot open directory 'prueba/': Permission denied root@59c188463618:/# cd prueba root@59c188463618:/prueba# ls ls: cannot open directory '.': Permission denied root@59c188463618:/prueba# touch hola touch: cannot touch 'hola': Read-only file system root@59c188463618:/prueba# exit exit $
En la inspección se observa
sudo docker inspect --format='{{range .Mounts}}{{.Source}}{{end}}' dazzling_franklin /home/alex.callejas/Devel/docker/test $ sudo docker inspect --format='{{range .Mounts}}{{.Destination}}{{end}}' dazzling_franklin /prueba $ sudo docker inspect --format='{{range .Mounts}}{{.Mode}}{{end}}' dazzling_franklin rw $ sudo docker inspect --format='{{range .Mounts}}{{.RW}}{{end}}' dazzling_franklin true $
16. Los volúmenes los podemos crear antes de usarlos, ejecutando
sudo docker volume create --name myvol myvol $ sudo docker volume ls DRIVER VOLUME NAME local 4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323 local 5e76c5028ea86b1671837372c914d1603944dbf7d4676d0ee49740920756da24 local a909d99c5b8cab582d7c7a5c8e8dc21ed75f0a0ff8df15040906ab34fc67f142 local d840fde43be8d06fa06448478755f414de20c00705d27928ac5a8e0bba140d02 local myvol $
Para asignarlo al contenedor, ejecutamos
sudo docker run -it -v myvol:/stuff ubuntu bash
root@6b2116af2431:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv stuff sys tmp usr var
root@6b2116af2431:/# cd stuff/
root@6b2116af2431:/stuff# touch test{1..7}
root@6b2116af2431:/stuff# ls
test1 test2 test3 test4 test5 test6 test7
root@6b2116af2431:/stuff#
En la inspección observamos donde se creo el volumen y los archivos creados
sudo docker inspect distracted_franklin | grep Mounts -A 11 "Mounts": [ { "Type": "volume", "Name": "myvol", "Source": "/var/lib/docker/volumes/myvol/_data", "Destination": "/stuff", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" } ], $ # ls /var/lib/docker/volumes/myvol/_data test1 test2 test3 test4 test5 test6 test7 #
17. Para eliminar el volumen, después de eliminar el contenedor, ejecutamos
sudo docker volume rm myvol myvol $ sudo docker volume ls DRIVER VOLUME NAME local 4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323 local 5e76c5028ea86b1671837372c914d1603944dbf7d4676d0ee49740920756da24 local a909d99c5b8cab582d7c7a5c8e8dc21ed75f0a0ff8df15040906ab34fc67f142 local d840fde43be8d06fa06448478755f414de20c00705d27928ac5a8e0bba140d02 $
18. Si se requiere copiar archivos del host al contenedor, la mejor práctica es realizarlo desde su creación mediante Dockerfile, suponiendo que en el host tenemos un directorio archivos que deseamos tener en el contenedor dentro del directorio stuff, ejecutamos
ls archivos/ notas1.txt notas2.txt $ cat Dockerfile FROM debian RUN apt-get update && apt-get install vim -qqy COPY ./archivos/ /stuff $ sudo docker build -t cosasaxl . [sudo] password for alex.callejas: Sending build context to Docker daemon 556 kB Step 1/3 : FROM debian ---> a20fd0d59cf1 Step 2/3 : RUN apt-get update && apt-get install vim -qqy ---> Running in d095c62569fa Ign:1 http://deb.debian.org/debian stretch InRelease Get:2 http://deb.debian.org/debian stretch-updates InRelease [88.5 kB] Get:3 http://security.debian.org stretch/updates InRelease [62.9 kB] Get:4 http://deb.debian.org/debian stretch Release [118 kB] Get:5 http://deb.debian.org/debian stretch Release.gpg [2373 B] Get:6 http://security.debian.org stretch/updates/main amd64 Packages [169 kB] Get:7 http://deb.debian.org/debian stretch/main amd64 Packages [9497 kB] Fetched 9938 kB in 5s (1799 kB/s) Reading package lists... debconf: delaying package configuration, since apt-utils is not installed ... update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in auto mode ---> 56193462f153 Removing intermediate container d095c62569fa Step 3/3 : COPY ./archivos/ /stuff ---> 83e969244bce Removing intermediate container 0a687e1b1998 Successfully built 83e969244bce $ sudo docker run -it cosasaxl bash root@7f3d34dfa53a:/# ls bin dev home lib32 libx32 mnt proc run srv sys usr boot etc lib lib64 media opt root sbin stuff tmp var root@7f3d34dfa53a:/# ls stuff/ notas1.txt notas2.txt root@7f3d34dfa53a:/# exit exit $
19. Suponiendo que necesitamos que el contenedor ejecute un script al arrancarlo, lo construimos con la opción ENTRYPOINT
cat entrypoint.sh #!/bin/bash ls -la echo "Hola desde entrypoint" $ cat Dockerfile FROM debian RUN apt-get update && apt-get install vim -qqy COPY ./archivos/ /stuff COPY entrypoint.sh /entrypoint.sh ENTRYPOINT /entrypoint.sh $ ls archivos Dockerfile entrypoint.sh $ sudo docker build -t cosasaxl . [sudo] password for alex.callejas: Sending build context to Docker daemon 557.1 kB Step 1/5 : FROM debian ---> a20fd0d59cf1 Step 2/5 : RUN apt-get update && apt-get install vim -qqy ---> Using cache ---> 56193462f153 Step 3/5 : COPY ./archivos/ /stuff ---> Using cache ---> 83e969244bce Step 4/5 : COPY entrypoint.sh /entrypoint.sh ---> e403afe2511c Removing intermediate container b0c28c21c8ff Step 5/5 : ENTRYPOINT /entrypoint.sh ---> Running in 4ad3f139001d ---> 2b76fbb9ebba Removing intermediate container 4ad3f139001d Successfully built 2b76fbb9ebba $ sudo docker run -it cosasaxl bash total 68 drwxr-xr-x. 1 root root 4096 Aug 12 17:18 . drwxr-xr-x. 1 root root 4096 Aug 12 17:18 .. -rwxr-xr-x. 1 root root 0 Aug 12 17:18 .dockerenv lrwxrwxrwx. 1 root root 7 Jul 23 00:00 bin -> usr/bin drwxr-xr-x. 2 root root 4096 Jul 13 13:04 boot drwxr-xr-x. 5 root root 360 Aug 12 17:18 dev -rwxrwxr-x. 1 root root 49 Aug 12 17:14 entrypoint.sh drwxr-xr-x. 1 root root 4096 Aug 12 17:18 etc drwxr-xr-x. 2 root root 4096 Jul 13 13:04 home lrwxrwxrwx. 1 root root 7 Jul 23 00:00 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Jul 23 00:00 lib32 -> usr/lib32 lrwxrwxrwx. 1 root root 9 Jul 23 00:00 lib64 -> usr/lib64 lrwxrwxrwx. 1 root root 10 Jul 23 00:00 libx32 -> usr/libx32 drwxr-xr-x. 2 root root 4096 Jul 23 00:00 media drwxr-xr-x. 2 root root 4096 Jul 23 00:00 mnt drwxr-xr-x. 2 root root 4096 Jul 23 00:00 opt dr-xr-xr-x. 337 root root 0 Aug 12 17:18 proc drwx------. 2 root root 4096 Jul 23 00:00 root drwxr-xr-x. 4 root root 4096 Jul 23 00:00 run lrwxrwxrwx. 1 root root 8 Jul 23 00:00 sbin -> usr/sbin drwxr-xr-x. 2 root root 4096 Jul 23 00:00 srv drwxr-xr-x. 2 root root 4096 Aug 12 17:09 stuff dr-xr-xr-x. 13 root root 0 Aug 12 14:27 sys drwxrwxrwt. 1 root root 4096 Aug 12 17:09 tmp drwxr-xr-x. 1 root root 4096 Jul 23 00:00 usr drwxr-xr-x. 1 root root 4096 Jul 23 00:00 var Hola desde entrypoint $
En un siguiente post, cuando nos den la segunda parte del curso: Intermedio, les compartiré de igual forma mis notas.
P.D.: Hace ya algún tiempo, aquí en el blog, había publicado una muy buena introducción a docker [ver] 😉
Espero les sirva…