- Se incorporó
- 11 Febrero 2007
- Mensajes
- 846
Hola a todos, hace unos meses me había hecho un documento sobre lo que es Docker, su arquitectura, sobre las imágenes y todo lo relacionado a contenedores (volumenes, redes ,etc) y sus comandos, mas lo que era docker-compose.... lo comparto para ver si a mas de aguno le sirve o si tienen dudas vayamos en este mismo hilo compartiendo y ayudándonos.
Que es Docker
Docker por definición es una herramienta que permite desplegar aplicaciones en contenedores de forma rápida y portable, en otras palabras Docker es capaz de generar “aplicaciones de bolsillo” debido a que su arquitectura utiliza contenedores e imagines, en una imagen se definen toda la configuración que necesita la aplicación para funcionar y en un contenedor se vuelve realidad.
Eso mismo permite desplegar y escalar las aplicaciones, porque todos van a tener la misma configuración que esta definida en la imagen, adicional permite destruir o recrear las imágenes o contenedores de una manera muy fácil ya que todo esta basado en las imágenes y esto permite que todo sea muy rápido.
Eso mismo permite desplegar y escalar las aplicaciones, porque todos van a tener la misma configuración que esta definida en la imagen, adicional permite destruir o recrear las imágenes o contenedores de una manera muy fácil ya que todo esta basado en las imágenes y esto permite que todo sea muy rápido.
- Aplicaciones de bolsillo
- Desplegar y escalar aplicaciones
- Destruir y recrear
Por Ejemplo: Crear un contenedor de apache
run= para crear un contenedor por primera vez
-d = Para que lo corra en el fondo
-p = definir el puerto que tendrá abierto y por el que escuchara
--name = Nombre que se le dará al contenedor
Ahora si se quiere destruir:
-d = Para que lo corra en el fondo
-p = definir el puerto que tendrá abierto y por el que escuchara
--name = Nombre que se le dará al contenedor
Ahora si se quiere destruir:
$ docker rm -fv web
rm = Para eliminar el contenedores
-fv = Para forzar la eliminación y para eliminar el volumen
Arquitectura de Docker
Docker para funcionar necesita de un Host y en el Host se instala el servicio de Docker llamado “Docker Deamon” el cual presta todo el servicio.
También existe un Docker CLI, que son comando que se escriben en la terminal, escribiendo “docker” nos conectamos por medio de la API hacia el servidor y por medio del servidor utilizando la API para contestarle al cliente.
La API es el canal de comunicación entre el docker client y el docker server, server y client están en el docker host, osea en la misma maquina, pero el server e un servicio que esta corriendo.
Docker CLI es el cliente que se comunica con la API a través de la API.
Con el Client podemos manejar:
También existe un Docker CLI, que son comando que se escriben en la terminal, escribiendo “docker” nos conectamos por medio de la API hacia el servidor y por medio del servidor utilizando la API para contestarle al cliente.
La API es el canal de comunicación entre el docker client y el docker server, server y client están en el docker host, osea en la misma maquina, pero el server e un servicio que esta corriendo.
Docker CLI es el cliente que se comunica con la API a través de la API.
Con el Client podemos manejar:
- Contenedores
- Imágenes
- Volumen
- Redes
Que es una imagenLas imágenes se encuentran dentro del Docker Host, se pueden pensar como paquetes que contienen toda la configuración necesaria para que funcione la aplicación.
Las imágenes se componen por capas, pueden tener “N” capas y serán de SOLO LECTURA.
Este ejemplo tiene 3:
Capa 1 – FROM → Indicar que Sistema Operativo tendrá
Capa 2 – RUN → Que viene luego del sistema operativo, por ejemplo apache
Capa 3 – CMD → Es lo que levantara el servicio de la capa 2
Las capas se crean utilizando un archivo llamado “Dockerfile”.
Dockerfile: Puede llamarse de otras maneras pero este nombre de archivo es el que busca docker
Las imágenes se componen por capas, pueden tener “N” capas y serán de SOLO LECTURA.
Este ejemplo tiene 3:
Capa 1 – FROM → Indicar que Sistema Operativo tendrá
Capa 2 – RUN → Que viene luego del sistema operativo, por ejemplo apache
Capa 3 – CMD → Es lo que levantara el servicio de la capa 2
Las capas se crean utilizando un archivo llamado “Dockerfile”.
Dockerfile: Puede llamarse de otras maneras pero este nombre de archivo es el que busca docker
Código:
FROM centos:7
RUN yum -t httpd
CMD [“apachectl”, “-DFOREGROUND]
Código:
Es importante que la linea del CMD ejecute un servicio en primer plano, osea que se quede pegado en la consola, ya que de esta manera el contenedor se mantendrá “vivo”, si el CMD muere la aplicación también.
Es una capa adicional que traerá una ejecución en tiempo real de las capas anteriores(imágenes), esta capa si es de escritura ya que es de ejecución. Todos los cambios que hagamos en la capa 4 sera temporales ya que son modificaciones realizadas en el contenedor y no en la imagen y es por eso que no se recomienda modificar la capa 4 ya que es temporal y si eliminamos el contenedor toda la configuración se perderá.
El contenedor además de contener las capas anteriores también tiene:
Volúmenes → Sirve para persistir la data
Redes → Para lograr comunicar contenedores entre si
Contenedor V/S Maquina Virtual
Los contenedores son instancia en ejecución de una imagen, se crea a partir de una imagen, es un proceso mas del sistema, osea utilizará la misma RAM, el mismo disco y la misma CPU del Host. Al ser un proceso esto significa que utilizará una mínima cantidad de memoria al contrario de una MV.
Si se compara con una MV, el peso es mucho mayor ya que se instala el software para virtualizar, tener la ISO del S.O crear un disco virtual, luego instalar el S.O , agregar memoria y CPU y todo eso ya no es un proceso dentro del Host, si no mas bien una nueva maquina completa dentro del host.
Por ejemplo si uno quiere instalar apache y utiliza la tecnología de virtualizar e instalamos ubuntu, este además instala una serie de cosas como por ejemplo un firewall, en ocasiones entorno gráfico, navegadores, librerías, actualizaciones y muchos otros servicios… si lo único que se requiere es apache.
Una VM puede pesar quizás 40GB, poner el computador o el servidor lento porque consume demasiada memoria o CPU, en cambio un contenedor es un proceso aislado que corre en nuestro host consumiendo muy poco recursos y con una instalación muy rápida ya que se tendrá la imagen con todo lo necesario, en cambio una VM se tendrá que volver a instalar todo el S.O nuevamente y luego todas las aplicaciones necesarias.
En definitiva eso es en parte lo que resuelven los contenedores, un proceso mucho mas liviano, ya que solo se levanta el servicio que se necesita, una instalación mucho mas rápida ya que todo esta en la imagen y el contenedor se crea en base a ella, pudiendo tener una imagen de apache y otra de mysql y entre los 2 servicios consumir a lo mas 500mb de memoria v/s 3gb de una VM.
El contenedor además de contener las capas anteriores también tiene:
Volúmenes → Sirve para persistir la data
Redes → Para lograr comunicar contenedores entre si
Contenedor V/S Maquina Virtual
Los contenedores son instancia en ejecución de una imagen, se crea a partir de una imagen, es un proceso mas del sistema, osea utilizará la misma RAM, el mismo disco y la misma CPU del Host. Al ser un proceso esto significa que utilizará una mínima cantidad de memoria al contrario de una MV.
Si se compara con una MV, el peso es mucho mayor ya que se instala el software para virtualizar, tener la ISO del S.O crear un disco virtual, luego instalar el S.O , agregar memoria y CPU y todo eso ya no es un proceso dentro del Host, si no mas bien una nueva maquina completa dentro del host.
Por ejemplo si uno quiere instalar apache y utiliza la tecnología de virtualizar e instalamos ubuntu, este además instala una serie de cosas como por ejemplo un firewall, en ocasiones entorno gráfico, navegadores, librerías, actualizaciones y muchos otros servicios… si lo único que se requiere es apache.
Una VM puede pesar quizás 40GB, poner el computador o el servidor lento porque consume demasiada memoria o CPU, en cambio un contenedor es un proceso aislado que corre en nuestro host consumiendo muy poco recursos y con una instalación muy rápida ya que se tendrá la imagen con todo lo necesario, en cambio una VM se tendrá que volver a instalar todo el S.O nuevamente y luego todas las aplicaciones necesarias.
En definitiva eso es en parte lo que resuelven los contenedores, un proceso mucho mas liviano, ya que solo se levanta el servicio que se necesita, una instalación mucho mas rápida ya que todo esta en la imagen y el contenedor se crea en base a ella, pudiendo tener una imagen de apache y otra de mysql y entre los 2 servicios consumir a lo mas 500mb de memoria v/s 3gb de una VM.
IMAGENES
Imágenes OficialesHay mucho software libre como por ejemplo apache, jenkins, mongo, php, mysql, etc. La gente que creo estos software son los que crean las imágenes oficiales de sus softwares y en estas imágenes oficiales vienen toda la configuración que necesita un contenedor para funcionar.
Hay una web oficial donde se almacenan todas las imágenes llamada https://hub.docker.com , y es desde acá donde se podrán descargar las imágenes que uno necesite.
Con el siguiente comando se descargara la imagen de mongo:
$ docker pull mongo |
se podrá observar que se descarga la ultima versión con el nombre “tag: latest”, los tag son etiquetas que indican la versión de la imagen, sirven para versionar la aplicación. Si al momento de descargar la imagen no se le define un tag, por defecto se descargará la ultima versión que la gente de mongo haya subido a docker hub. Si por el contrario se le define un tag, se descargará esa versión especifica de la aplicación con esa configuraron especifica.
$ docker pull mongo:7.0.0-rc6-jammy |
Todas las versiones de las imágenes se encuentran en la pagina dockerhub (NO se pueden inventar tag) si hay una versión que no existe, entonces recién uno podría crear imágenes personalizadas, pero si existe lo mejor es descargarla, ya que en teoría cuenta con todo lo necesario para que funcione de forma correcta pues esta mejor optimizada, tiene las mejores practicas y fue creada por la misma gente de la mongo (o de mysql, apache, etc).
Cuando uno hace un pull comienza el proceso de descarga de la imagen y este proceso va descarando capa por capa, por ejemplo si uno descarga la versión httpd:2.4 descargara 10 capas y si luego descargamos la versión httpd:2.4.5 docker se dará cuenta que ya tenemos la versión anterior y solo descargara las capas distintas de apache, osea las que hacen falta.
Con el siguiente comando podremos ver las imagenes descargadas:
$ docker images |
Con este comando se listaran todas las imágenes que se han descargado con el comando “pull” y mostrara también los tag de cada una de ellas.
*** Si tratamos de descargar una versión de imagen que ya tenemos, docker nos dirá que ya la tenemos y no la descargará nuevamente.
Imágenes dangling
Si se descargo por ejemplo la versión mysql , esto descargará la ultima versión automáticamente y quedará almacenada en el servidor, si al tiempo después se hace otro pull a mysql y existe una nueva versión, entonces docker descagará solamente las capas faltantes y creará una nueva versión con el tag de “latest” y dejará la versión antigua sin tag (<none>) quedando como “huérfana”, ya que no pueden haber 2 imágenes con el mismo tag.
Creación de Imágenes
En caso de no encontrar una imagen que necesitemos se podrá crear una imagen personalizada, por ejemplo crear una imagen que contenga Apache y PHP:
Para esto se creara un archivo llamado Dockerfile:
FROM centos:7 RUN yum -y install httpd php CMD apachectl -DFOREGROUND |
Para construir una imagen tomando como referencia el Dockerfile:
$ docker build --tag apache-centos . |
Con la primera capa se instalara Centos versión 7 y luego con el comando RUN se comenzará a instalar los paquetes que necesitamos (dentro de Centos), si la instalación solicita intervención humana para instalar los paquetes docker arrojará un error, por lo tanto se agrega el comando “-y” en el install.
Luego con el CMD mantenemos el servicio de apache corriendo en primer plano, si no lo hacemos el contenedor se creará y se “morirá” de manera inmediata.
Y con el siguiente comando se podrá ver la historia de la imagen:
$ docker history -H apache-centos --no-trunc |
Donde se podrán visualizar las capas de la imagen, donde se observaran las capas que traía la imagen de Centos mas la que le agregamos nosotros.
Creación de un contenedor en base a la imagen anterior
Para crear el contenedor:
$ docker run -d --name -p 80:80 apache apache-centos |
Para poder ver los contenedores que se están ejecutando es con el siguiente comando:
# docker ps |
Y para ver todos los contenedores, (ejecutándose y detenidos):
$ docker ps -a |
Para eliminar un contenedor:
$ docker rm -fv apache-centos |
De esta manera de manera simple podemos crear una imagen personalizada llamada “apache-centos” y luego levantar un contenedor llamado “apache”.
Para probar y visualizar la web simplemente hay que ingresar a http://localhost del servidor
Introducción Dockerfile
Es el archivo donde se define la configuración de la imagen y se verán todos los conceptos para entender como se construye una imagen.
FROM →Sistema Operativo que queremos
RUN → Instrucciones que se ejecutan en la terminal, cualquier comando que este disponible en linux(touch, mkdir, rm, adduser, etc)
COPY/ADD → Copiar archivosEs el archivo donde se define la configuración de la imagen y se verán todos los conceptos para entender como se construye una imagen.
FROM →Sistema Operativo que queremos
RUN → Instrucciones que se ejecutan en la terminal, cualquier comando que este disponible en linux(touch, mkdir, rm, adduser, etc)
ENV → Variables de entorno
WORKDIR → Directorio de trabajo
LABEL → Etiquetas
USER → que usuarios ejecutara la tarea
VOLUME → Para persistir la data
CMD →
Dockerfile – FROM / RUN/COPY / ADD
Se creará una imagen utilizando estos 3 argumentos:
Se creara un archivo llamado index.html (con el texto PRUEBA en el interior) al mismo nivel de donde se encuentra el archivo Dockerfile
WORKDIR → Directorio de trabajo
LABEL → Etiquetas
USER → que usuarios ejecutara la tarea
VOLUME → Para persistir la data
CMD →
Dockerfile – FROM / RUN/COPY / ADD
Se creará una imagen utilizando estos 3 argumentos:
Se creara un archivo llamado index.html (con el texto PRUEBA en el interior) al mismo nivel de donde se encuentra el archivo Dockerfile
FROM centos:7 RUN yum install httpd -y COPY index.html /var/www/html # ADD index.tar /var/www/html CMD apachectl -DFOREGROUND |
Se construirá la imagen:$ docker build -t apache2 . |
Levantar el contenedor:
$ docker run -d --name apache2 -p 80:80 apache2 |
Luego se ingresara a http://localhost y la pagina a cargar debería estar el texto “PRUEBA”. De esta manera podemos meter archivos o toda una web dentro de la imagen y una vez levantemos el contenedor estará todo listo.
El comando ADD nos permite agregar URL, entonces descargara el archivo y lo dejara dentro del contenedor, también se puede copiar un archivo .tar y el contenido sera extraído automáticamente dentro del contenedor en la ruta especificada.
*** ADD tiene cierta lógica para descargar archivos remotos y extraer archivos
Aunque también cumple la función de agregar el archivo local dentro de la imagen pero para copiar del local al contenedor se recomienda utilizar COPY.
Dockerfile ENV / WORKDIR
Agregaremos nuevos argumentos al mismo Dockerfile creado anteriormente:
- ENV hace referencia a la opción que permite definir variables de entorno que pueden utilizarse en el interior de los contenedores.
FROM centos:7 RUN yum install httpd -y WORKDIR /var/www/html COPY index.html . ENV palabra Prueba_Docker_WORKDIR RUN echo “$palabra” > /var/www/html/prueba.html CMD apachectl -DFOREGROUND |
Se construirá la imagen:$ docker build -t apache3 . |
Levantar el contenedor:
$ docker run -d --name apache3 -p 80:80 apache3 |
Luego se ingresara a http://localhost/prueba.html y la pagina a cargar debería estar el texto “Prueba_DOCKER”.
La variable llamada “palabra” tomará el texto “Prueba_Docker” y luego en la linea de RUN se esta pasando el contenido de la variable “palabra” al archivo “prueba.html”.
Además con el comando WORKDIR se podrá indicar en que directorio de trabajo se estará trabajando dentro del contenedor, entonces luego en el COPY se puede poner un “.”
Dockerfile LABEL / USER / VOLUME
- LABEL es una etiqueta que normalmente va al inicio.
- USER sirve para indicar quien ejecutara la siguiente tarea.
- VOLUME sirve para mantener la data al momento de eliminar el contenedor y así no perderla.
FROM centos:7 LABEL version=1.0 RUN yum install httpd -y WORKDIR /var/www/html COPY index.html . RUN echo “$(whoami)” > /var/www/html/user1.html RUN useradd test USER test RUN echo “$(whoami)” > /tmp/user2.html USER root RUN cp /tmp/user2.html /var/www/html/user2.html ENV palabra Prueba_Docker_WORKDIR RUN echo “$palabra” > /var/www/html/prueba.html CMD apachectl -DFOREGROUND |
Se construirá la imagen:
$ docker build -t apache4 . |
Levantar el contenedor:$ docker run -d --name apache4 -p 80:80 apache4 |
El usuario root deja un archivo de user1.html en “/var/www/html” y luego se crea el usuario test, nos cambiamos al usuario test y creamos el archivo user2.html en “/tmp/user2.html”, luego volvemos a ser root y copiamos el archivo “user2.html” a “/var/www/html” (porque el usuario test no puede escribir en este directorio).
Luego se ingresara a http://localhost/user1.html y la pagina a cargar debería estar el texto “root” y en http://localhost/user2.html el contenido deberá ser “test”.
Los VOLUME se verán mas adelante, en el capitulo de Contenedores.
Dockerfile CMD / dockerignore
- CMD se utiliza para mantener vivo al contenedor, puede ser un comando o un script
- dockerignore es un archivo oculto y sirve para ignorar cualquier cosa que tenga el directorio de trabajo actual y que no queramos incluir en la imagen.
$ nano run.sh
#!/bin/bash echo “Iniciando contenedor…” apachectl -DFOREGROUND |
FROM centos:7 LABEL version=1.0 RUN yum install httpd -y WORKDIR /var/www/html COPY index.html . RUN echo “$(whoami)” > /var/www/html/user1.html RUN useradd test USER test RUN echo “$(whoami)” > /tmp/user2.html USER root RUN cp /tmp/user2.html /var/www/html/user2.html ENV palabra Prueba_Docker_WORKDIR RUN echo “$palabra” > /var/www/html/prueba.html COPY run.sh /run.sh CMD sh /run.sh |
Se construirá la imagen:
$ docker build -t apache5 . |
Levantar el contenedor:
$ docker run -d --name apache5 -p 80:80 apache5 |
Para ver si el contenedor esta corriendo y validar el “COMMAND”$ docker ps --no-trunc |
Si revisamos los logs del contenedor también se observara la linea que se agrego en el script “Iniciando contenedor...”
$ docker logs apache5 |
Cuando trabajamos con el archivo dockerignore, lo primero que debemos hacer es crearlo con un “.” al comienzo ya que es un archivo oculto y en su interior escribir el nombre de los archivos o carpetas que no queremos que estén en nuestra imagen.$ nano .dockerignore
.git/ node_modules/ dist/ */prueba* |
De esta manera creamos una imagen mas liviana dejando solo lo necesario para nuestra aplicación.Una imagen con todos los argumentos
En esta ocasión se trabajará con una imagen directamente de nginx
FROM nginx LABEL version=1 RUN useradd test WORKDIR /usr/share/nginx/html COPY index.html . ENV archivo docker RUN echo “$archivo” > ./env.hmtl EXPOSE 90 USER test RUN echo “Soy el usuario $(whoami)” > /tmp/yo.html USER root RUN cp /tmp/yo.html . VOLUME /var/log/nginx CMD nginx -g 'daemon off;' |
Ahora se construirá la imagen en base a la información del Dockerfile$ docker build -t nginx1 . |
Ahora se ejecutara un contenedor en base a la imagen creada.$ docker run -d -p 80:80 --name nginx nginx1 |
http://localhost → Debería mostrar el contenido del archivo index.htmlhttp://localhost/env.html → Debería decir “docker”
http://localhost/yo.html → Debería decir “Soy el usuario test”
Eliminar Imágenes
http://localhost/yo.html → Debería decir “Soy el usuario test”
Eliminar Imágenes
$ docker tmi <nombre de la imagen> <nombre imagen> <nombre imagen> |
Cambia de nombre el Dockerfile
Por defecto al construir una imagen docker buscar el archivo Dockerfile, pero en ocasiones podríamos cambiarle el nombre y para que docker lo encuentre se le agrega al comando el “-f”
$ docker build -t test -f mydockerfile . |
Multi-Stage Build
Existe una características que permite utilizar varios FROM dentro del mismo dockerfile para construir imágenes diferentes por tema de dependencias. Por ejemplo:
FROM centos:7 as test RUN fallocate -l 10M /opt/file1 RUN fallocate -l 20M /opt/file2 RUN fallocate -l 30M /opt/file3 FROM alpine COPY --from=test /opt/file1 /opt/myfile |
Este ejemplo es muy básico, pero para que se logre entender la idea del multi-stage, se construye la primera imagen en base a Centos 7 y se le asigna un alias llamado “test”, luego se utiliza el comando “fallocate” para crear archivos de distintos tamaños en diferentes rutas. Si solamente creamos la imagen con la primera parte(Color verde) tendremos como resultado una imagen de aproximadamente 260MB ya que centos pesa 200mb mas los 3 archivos sumarían en total 60 mb aprox.
Si luego agregamos el segundo from y creamos la imagen no daremos cuenta que solamente se creara una imagen de unos 17MB ya que la imagen de alpine es 7mb mas el archivo “file1” de 10mb quedaría una imagen resultante de unos 17MB.
Con esto nos damos cuenta que la imagen final es la del segundo FROM, donde en el primer FROM se puede hacer todo el trabajo de instalar dependencias, desempaquetar archivos e instalar para que luego se copie el resultado final al segundo FROM y la imagen quede con el mínimo de características.
Buenas Practicas
Las buenas practicas para construir un contenedor serian las siguientes:
- Efímero: Hay que pensar que la idea de docker es que el contenedor se pueda destruir, lo que significa que el servicio que esta corriendo se debe poder destruir con facilidad y luego poder volver a levantarlo rápidamente.
- Un solo servicio: En teoría debe haber un solo servicio instalado por contenedores, por ejemplo un contenedor con nginx y otro contenedor con mysql… nunca juntos.
- dockerignore: Utilizar el archivo de .dockerignore para evitar meter archivos innecesarios dentro de nuestra imagen.
- Pocas Capas: Es importante en lo posible reducir el numero de capas que tiene la imagen, la idea es que sea una imagen pequeña con pocas capas.
- Multi Linea: Cuando una sola linea es demasiado larga se recomienda sdividilar en diferentes lineas finalizándola con “\” y continuando abajo.
- No instalar paquetes innecesarios, por ejemplo no instalar ssh, nano, vim, etc. las imágenes están dedicadas a un solo servicio.
- Es recomendable utilizar LABEL para detallar versiones, descripciones, etc.
FROM nginx ENV dir /usr/share/nginx/html/test.txt RUN \ echo “1” » $dir & \ echo “2” » $dir & \ echo “3” » $dir |
En este ejemplo estamos utilizando una sola capa para ejecutar los 3 echo y al mismo tiempo utilizamos Multi lineas separadas por el símbolo “\” y para finalizar utilizamos una variable de entorno para simplificar la linea del directorio.
Archivo adjunto
Última modificación por un moderador: