• Inicio
  • Temas
    • Docker
Con tecnología de Blogger.

Camila Eyzaguirre

Qué es una imagen


Una imagen es una especie de plantilla, una captura del estado de un contenedor. Está compuesta por un conjunto de capas.

Explorando imágenes

  • docker images = Lista todas las imágenes 
  • docker image ls = Lista todas las imágenes 
  • docker image prune = Elimina todas las imágenes no usadas (que no estén enlazadas a container).
  • docker image prune -a = Elimina todas las imágenes
  • docker pull nombreimagen = Descarga la imagen especificada en el host. Ej: docker pull redis Ej: docker pull ubuntu:18.04 descargando una version en particular
  • docker rmi nombreimagen:version/idimagen = Eliminar una sola imagen 
  • docker rmi $(docker images -qf "dangling=true") = Eliminar todas las imágenes 

Docker hub

Es un repositorio de imágenes. La url es https://hub.docker.com
Cuando vemos por ejemplo las versiones de una imagen, a la izquierda vemos la versión y a la derecha los alias que responden a esta versión:


Más que el nombre, lo que importa es el IMAGE ID al momento de hacer docker image ls.
Al mismo tiempo, si hay 2 imágenes con mismo IMAGE ID, y ambas pesan 100 megas, el espacio que ocuparán no son 200 megas, sino que 100 megas, ya que reutiliza las capas. Lo mismo ocurre con imágenes con distinto IMAGE ID donde las capas se repiten.

Dockerfile


Es la receta de docker para crear nuestras propias imágenes.
Pasos:
  • Crear el archivo Dockerfile (receta)
  • El dockerfile siempre debe empezar con el FROM le indicamos cual va a ser nuestra imagen base para empezar 
  • RUN para correr un comando. Creamos un archivo touch /usr/src/hola-mundo 
  • Construimos el dockerfile (con -t asignamos el tag): 
docker build -t <imagen>:<tag de la imagen> <path de donde obtener el contexto build>

Ej. de archivo Dockerfile:

FROM -> Todo Dockerfile comienzan con un FROM
RUN touch /usr/src/hola -> RUN para ejecutar un comando.
COPY . /src -> Copia el . del contexto del build a /src del contenedor
WORKDIR /src -> Indico donde trabajaré y me pararé ahí para los comandos que vienen
EXPOSE 3000 -> puerto que expone el contenedor para luego usarlo con -p
CMD ["node", "index.js"] -> Comando por default cuando finalizan las capas de dockerfile


  • docker build -t ubuntu:versionx .
  • docker push tagcontenedor = Hacer push a un contenedor. Debo tener permisos. Si no especifico usuario, intentará subir a /library de dockerhub, donde no tendremos permisos. Deberíamos cambiarlo a nuestro usuario o a otro con permisos. Los repositorios pueden ser públicos o privados.
  • Ej: docker push <user>/ubuntu:versionx 
  • docker tag tagactualcontenedor nuevotagcontenedor = Cambiar el tag de un contenedor. Ej: docker tag ubuntu:versionx camila/ubuntu:versiony

Por default tomará el dockerfile de la ruta actual. Si queremos especificar qué dockerfile usar, usar el tag -f
  • docker build -f docker/DockerFile -t ubuntu:versionz .

Capas de una imagen

  • docker history ubuntu:versionx = Para ver las capas de una imagen con el peso respectivo de cada una.
  • Al bajar cada capa de una imagen, puede descargarse paralelamente cada capa, no así extraerse, esa debe ser secuencial, ya que una depende de la otra.
  • Para optimizar la ejecución usando el caché de las capas, podemos solo copiar package.json y package-lock.json a la carpeta que ejecutaremos npm install, y luego de instalar, copiar los fuentes. Así no vuelve a ocupar tiempo en instalar todo de nuevo.

Redes en Docker

Por default docker tiene 3 redes:

  • bridge
  • host
  • none

docker network rm nombredelared  = Borrar una red en docker
Ej: docker network rm redcamila

docker network create --attachable nombredelared = Crear una red en docker
--attachable es para que otros contenedores se puedan unir a esta red
Ej: docker network create --attachable redcamila

docker network ls = Ver redes disponibles docker
bridge red por defecto y se conectan con un keyword link esta deprecada, compatibilidad.
host simula la red del computador que corre docker (no usar)
none hacer que tenga el network desabilitado

docker network inspect nombredelared = Ver contenedores en un red. Podemos ver la IP.
Ej: docker network inspect redcamila

docker network connect nombredelared nombredelcontenedor = Unir un contenedor a la red creada
Ej: docker network connect redcamila db docker run -d --name app -p 3000:3000 --env MONGO_URL=mongodb://db:27017/test appcamila
-env variable de entorno
db es el nombre del contenedor sin necesidad de pasar la ip del contenedor para la conexión

Podemos ahorrarnos un paso e iniciar el contenedor ya con la red que necesitamos: docker run -d --name app -p 3000:3000 --env MONGO_URL=mongodb://db:27017/test --net= redcamila appcamila Con esto ya levantamos el contenedor conectado a la red redcamila.

docker-compose.yml

Con Docker Compose puedes crear diferentes contenedores y al mismo tiempo, en cada contenedor, diferentes servicios.

  • Dockerfile = describe de manera imperativa (paso a paso) la arquitectura de nuestra aplicación
  • docker-compose.yml = describir de forma declarativa la arquitectura de nuestra aplicación
Podemos bajar todos los servicios levantados con docker-compose con docker-compose down

Podemos escalar (replicar) un servicio con docker compose

  • docker-compose scale nombreservicio=5

Podemos ver los servicios que sean solo de docker-compose con

  • docker-compose ps


Dockerignore

Podemos decirle a docker que ignore ciertos archivos con .dockerignore. Tiene un uso muy similar a .gitignore. Ej, archivos que queremos hacer COPY pero no genemos que incluya docker al usar


  • COPY . /user/server





Share
Tweet
Pin
Share
No comentarios

Exponiendo contenedores


Los contenedores están aislados del sistema y a nivel de red. Cada contenedor tiene su propia stack de red y sus propios puertos. Debemos redirigir los puertos del contenedor a los de la computadora y lo podemos hacer al utilizar este comando: 
  • docker run -d --name nombrecontenedor -p 8080:8080 imagen
Ej: 
  • docker run -d --name servidor -p 8080:8080 nginx
-d , -detach = Ejecuta indicando que la salida no la voy a esperar, así puedo seguir usando la consola.
--name : asignamos explícitamente el nombre del contenedor
-p portinterno:portexterno = Indicamos explícitamente por cual puerto de la máquina expondremos el puerto del contenedor.
imagen : la imagen que usaremos para el contenedor. ej nginx

Hay que considerar que en la máquina solo tenemos 1 puerto 8080, por lo que no podemos asignar a 2 container el mismo puerto de salida. Nos dará error "port is already allocated".

Permanencia de datos


Existen tres maneras de hacer permanencia de datos: 
  • Bind mount: Se da parte del sistema de archivo del host al contenedor.
  • Volume (nuevo):  Parecido a bind bound pero en un espacio solo manejado por docker.
  • tmpfs mount (temporal file system): el almacenamiento solo se mantiene en memoria en el contenendor. Si el contenedor se borra, el almacenamiento se pierde.

Bind mount:

  • docker run -d --name nombrecontenedor  -v pathcarpetahost:carpetacontenedor imagen 
Ej: 
  • docker run -d --name bd  -v /Users/camila/Projects/nuevacarpeta:/data/db mongo 
Si el volumen se modifica en el host cliente, se sincronizará automáticamente con el contenedor y viceversa.
Esto resulta de utilidad cuando desarrollamos con node, y queremos probar los cambios sin necesidad de reiniciar el contenedor, usando nodemon.

Volume:

  • docker volume create nombrevolumen 
  • docker run -d --name nombrecontenedor --mount src=nombrevolumen,dst=carpetacontenedor img
Ej: 
  • docker volume create dbdata 
  • docker run -d --name mongo-db --mount src=dbdata,dst=/data/db mongo
Podemos usar almacenamiento en la nube en lugar de este almacenamiento.

tmpfs mount:

Usan la RAM del equipo y su contenido desaparecerá al parar el contenedor. 
En caso de tener poca RAM, los ficheros se parasán al SWAP del equipo real. 

Ej:
docker run -d -it --name ubu3 --tmpfs /var/html/tempo ubuntu:17.10 

Salvo que indiquemos una limitación de espacio usando el modificador tmpfs-size=999bytes, el espacio que pueden ocupar los ficheros es ilimitado (o limitado por el espacio disponible de RAM) Este tipo de almacenamiento puede ser usado para almacenar ficheros de sesiones web, temporales o contenido que nos interese que se borre en cada rearranque del contenedor.

Utilidad: 

  • docker volume ls = Lista los volúmenes existentes.
  • docker volume prune = Elimina volúmenes no usados
  • Podemos verificar el volumen usado por el contenedor con docker inspect nombrecontenedor.

Share
Tweet
Pin
Share
No comentarios

Ejecutar un contenedor

Ejemplo: docker run hello-world
1- Buscará imagen “hello-world” localmente. Si no la encuentra…
2- Buscará imagen en hub.docker.com. Es necesario estar logueado.
Docker funciona como cliente-servidor
Cliente docker (comando docker) le habla al daemon docker que le habla a los contenedores
El daemon puede estar en mi máquina o en una máquina/servidor remoto.
  • Un contenedor es una entidad lógica, una agrupación de procesos que se ejecutan de forma nativa como cualquier otra aplicación en la máquina host.
  • Un contenedor es el estado en ejecución de una imagen.
  • A partir de una imagen, pueden ejecutarse uno o varios contenedores. Los mismos pueden agregarse o quitarse dinámicamente.
  • Se pueden realizar cambios sobre un contenedor y guardar los cambios realizando un “commit” en el repositorio de docker, el que asignará un nuevo nro de versión y creará una imagen con estos cambios.
  • Cada contenedor tiene un ID único y un nombre aleatorio si es que no se asigna uno explícitamente. El ID se asigna como hostname del contenedor (ej cuando se ingresa en modo interactivo, se ingresará como root@iddelcontenedor).
  • Docker está hecho en Go.
  • Cada contenedor tiene un "root command" que es el comando con el que se inicia. Este siempre se guarda en el PID 1 de la lista de procesos.
  • Siempre que un contenedor corra un comando, el contenedor estará vivo, sino se apagará.

Explorando contenedores

  • docker ps = Lista todos los contenedores que estén en ejecución
  • docker ps -a = Lista todos los contenedores.
  • docker ps -aq = Lista solo los IDs de todos los contenedores
  • docker inspect idcontenedor_o_nombrecontenedor = Inspeccionar un contenedor específico 
  • docker inspect -f {{variable}} idcontenedor_o_nombrecontenedor = Filtra una variable específica del contenedor. Ej docker inspect -f {{json .Config.Env}} micontenedor
  • docker logs idcontenedor_o_nombrecontenedor = Muestra el output de un contenedor.

     Modificando contenedores

    • docker run -it idcontenedor_o_nombrecontenedor = Ejecuta en modo interactivo, ejecutando el command ej /bin/bash. Al salir con exit se apaga el contenedor ya que el proceso no tiene nada más que hacer.
    • docker run --name nombreexplicitoparacontenedor nombreimagen = Ejecuta un contenedor en base a la imagen nombreimagen asignándole un nombre explícito. OJO: No podemos repetir los nombres.
    • docker run ubuntu tail -f /dev/null =  Truco para dejar contenedor corriendo, ya que siempre estará esperando algo.
    • docker run --detach nginx = Ejecuta indicando que la salida no la voy a voy a esperar, así puedo seguir usando la consola.
    • docker run --rm ... = con --rm indico que elimine el contenedor cuando se termine de ejecutar.
    • docker exec -it nombre_contenedor bash = Para ejecutar un comando en un contenedor existente (entramos al bash).
    • docker kill idcontenedor_o_nombrecontenedor = Mata el proceso completo
    • docker rm idcontenedor_o_nombrecontenedor = Elimina un contenedor. Si se le agrega -f lo elimina independiente si está o no en ejecución)
    • docker rm $(ps -aq) = Elimina todos los contenedores que no estén en ejecución. Símil a docker container prune. 
    • docker rm -f $(ps -aq) = Elimina todos los contenedores, independiente si están o no en ejecución (-f).
    • docker rename nombreantiguo nombrenuevo = Renombra un contenedor

    Extra: Refresco de comandos linux

    • ls -la = Muestra el listado de carpetas y archivos del directorio actual
    • pwd = Muestra la ruta del directorio actual
    • uname -a = Muestra información sobre el sistema. Ej en un ubuntu podría mostrar:
      Linux 061b1743cb6f 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
    • algúncomando tail = Muestra las últimas (por default 10) líneas de salida de un comando o archivo. Si se le agrega -f (-follow) la cola se repetirá por siempre, mostrando nuevos datos. Si se agrega -n nro, mostrará las nro Ãºltimas líneas.
    • ps = Lista de procesos. Se pueden agregar los parámetros -a, -fea.
    Share
    Tweet
    Pin
    Share
    No comentarios

    Problemáticas de desarrollo de software:

    Construir → Distribuir → Ejecutar

    Problemas al construir:
    • Dependencias de desarrollo
    • Versiones de entornos de ejecución
    • Equivalencia de entornos de desarrollo y producción
    Problemas al distribuir:
    • Generaciones del build diferentes
    • Acceso a servidores de producción
    Problemas al ejecutar:
    • Dependencias de aplicación
    • Compatibilidad de sistema operativo
    • Disponibilidad de servicios externos
    • Recursos de hardware
    Docker resuelve estas problemáticas, construyendo, distribuyendo y ejecutando en diferentes plataformas.

    Diferencias entre containarization y virtualization

    Containarization: Estandar para llevar algo dentro. Agrupadores de procesos.
    Versátiles:
    • En orden de los MB.
    • Tienen todas las dependencias que necesitan para funcionar.
    • Funcionan igual en todos lados.
    Eficientes:
    • Comparten archivos simultáneos con otros contenedores.
    • Solo se ejecutan procesos, no un SO completo.
    Aislados:
    • Lo que pasa en el contenedor queda en el contenedor.
    • No pueden alterar su entorno de ejecución (a menos que sea explícito).
    Virtualization: Imagen o archivo que contiene información dentro. Por lo general son pesadas, de administración costosa y lentas.
    Pesadas:
    • En el orden de los GB.
    • Muchas VMs en el mismo host suelen repetir contenido.
    • Administración costosa, ya que una VM debe ser administrada como cualquier otro computador.
    Lentas:
    • Correr nuestro código en una VM implica no solo arrancar aplicaciones sino también esperar el boot de la VM en si.

    Instalación (para Mac)

    • Ir a docker.com > Products > Docker Desktop
    • Descargar dmg. Se instalará y en barra superior aparecerá el ícono . 
    • En preferencias, podemos escoger hardware máximo, si se iniciará apenas inicie la mac, uso de disco, entre otros.
    • En caso de emergencia, en preferencias existe un “reset” que iniciará todo desde cero.
    • Para ver que esté instalado correctamente, se recomienda ejecutar “docker -v” y se espera ver la versión.
    • Se recomienda crear cuenta en hub.docker.com, y posteriormente loguearse con esta cuenta en Docker Desktop con ayuda del cliente con “docker login”
    • Dato extra: docker está escrito en Go (https://golang.org/)
    Share
    Tweet
    Pin
    Share
    No comentarios
    Newer Posts

    Etiquetas

    desarrollo docker informatica

    Redes sociales

    • Facebook
    • Twitter
    • Email

    Archivo

    • mayo 2019 (4)

    Perfil Blogger

    Mi foto
    Camila Eyzaguirre
    Santiago, Santiago, Chile
    Ver mi perfil completo

    Created with by ThemeXpose | Distributed by Blogger Templates