Docker cheats

December 2, 2018 • ☕️☕️☕️ 13 minutos de lectura

INTRODUCCIÓN DOCKER Y CHEATS

Descargar e instalar docker

En linux es mejor no instalarlo con apt-get puede que el paquete no esté actualizado Descagamos el script wget https://get.docker.com

Muestra los datos de la máquina y sobre el cual está corriendo el deamon. docker-machine ls

La IP, la necesitaremos para interactuar con los contenedores.

Información sobre la instalación docker info

Contenedores e imágenes Docker se divide en dos, imágenes y contenedores.

Imágenes: Se añade el sistema base y se le pueden añadir capas: Ej, debian, apache…

docker run -it [imagen] [comando] Esto nos abrirá un terminal y estaremos dentro

Contenedores

Los contenedores son objetos inmutables, no pueden cambiar. Debes de tener un contenedor por cada servicio. Por ejemplo puedo tener dos mysql, cada uno en un contenedor.

Si hago un update cambio el contenedor por otro, como le hice un update el creo otro contenedor y debemos tenerlo en cuenta.

Para persistir la información se presenta un volumen, una carpeta del disco, por si borramos el contenedor tendremos la información en el volumen

Contenedor:

  1. Los contenedores tienen dos ciclos de vida.
  2. Siempre se crean a partir de una imagen
  3. siempre se ejecuta un proceso detenerminado Un ciclo de vida básico: ejecuto contenedor ejecuto proceso este proceso puede tener tiempo de vida util como un script o algo duradero, pero cuando termina el contenedor se detiene. Puedo volver a lanzarlo si quiero.

Ciclo de vida avanzado:

se crea contenedor se ejecuta proceso ejecutamos acciones dentro del contenedor (siempre y cuando se pueda)

Crear contenedor

  • La bandera -i le indica a docker utilizar el STDIN del contenedor, vamos a enviar informacion al contendor
  • La bandera -t indica que se requiere de una pseudo terminal, el contendor puede recibir parámatros (para esto debe tener shell o algo similar). Los contenedores básicos, suelen usar bash o sh.

Imágenes

Las imágenes son la base para crearlas contenedores

DESCARGAR IMÁGENES

docker pull
docker pull ubuntu

Creación de imágenes

  1. hacer ‘commit’ de los contenidos de un contenedor
  2. Construir una imagen basándonos en un Dockerfile
  3. Importar un archivo Tar a docker con el contenido de de una imagen

Crear imagen a partir de una contedor

docker commit [hash contenedor] [nombre imagen que vamos a crear]

DESCARGAR CONTENEDOR

docker pull mysql

EJECUTAR CONTENEDOR

docker run -p 3306:3306 --name mysql_default -v ~/Docker/mysql/:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret -d mysql --character-set-server=utf8

docker run -p 27017:27017 --name mongo_default -v ~/Docker/mongo/:/var/lib/docker/volumes/myvol2/_data
 -e -t hash

docker run -p 5432:5432 --name postgres_default -v ~/Docker/postgresql/:/var/lib/postgresql/ -e POSTGRES_PASSWORD=secret -d gatoflaco

Parar todos los containers

docker kill $(docker ps -q)

Borrar todos los contenedores

docker rm $(docker ps -a -q)

Borrar todos las imágenes

docker rmi $(docker images -q)

Arrancar imagen

docker build -f /path/to/a/Dockerfile .
  • hacer accesible desde el puerto 8080 docker run -d -p 8080:80 nimmis/apache-php5
  • Contenido externo en /home/nimmis/html docker run -d -p 8080:80 -v /home/nimmis/html:/var/www/html nimmis/apache-php5

Esto corre la imagen y crea un contenedor.

docker run -p 8080:80 -d -v ~/Docker/www:/var/www  php56

Logs

docker logs -f hash --until=2s

Copiar ficheros de local a docker

docker cp src/. mycontainer:/target

Copiar dicheros de container docker a local

docker cp mycontainer:/src/. target

Montar directorio en imagen

docker run -ti -v $(pwd):/var/www/html tutum/lamp bash

MOSTRAR CONTENEDORES

docker ps
docker ps -a

ELIMINAR CONTENEDOR

docker rm mysql_default

ELIMINAR TODOS LOS CONTENEDORES.

docker container prune

ARRANCAR UNA IMAGEN

docker run -i -t ubuntu:12.04 /bin/bash

docker run -it debian /bin/bash

docker run -it 5839f391506f /bin/bash

RESET TODO

docker  system  prune

ELIMINAR VOLÚMENES

docker volume rm $(docker volume ls -q -f "dangling=true")

ELIMINAR CONTENEDORES DE LOS QUE HAS SALIDO

docker rm $(docker ps -q -f "status=exited")

REMOVER IMÁGENES COLGADAS

docker rmi $(docker images -q -f "dangling=true")

AUTO ELIMINAR CONTENEDORES INTERACTIVOS

docker run -it --rm alpine sh

INSPECCIONAR LOS ELEMENTOS DEL DOCKER

Mostrar toda la información de Docker

$ docker info --format "{{json .}}" | jq .

Mostrar solo plugins

$ docker info --format "{{json .Plugins}}" | jq .

listar las direcciones IP para todos los contenedores conectados a la red ‘puente’

$ docker network inspect bridge -f '{{json .Containers}}' | jq '.[] | {cont: .Name, ip: .IPv4Address}'

Mostrar una tabla con ‘ID Image Status’ para contenedores activos y actualizarlo cada 2 segundos

watch -n 2 'docker ps --format "table {{.ID}}\t {{.Image}}\t {{.Status}}"'

ENTRAR EN DOCKER HOT

docker run --rm -it --privileged --pid=host walkerlee/nsenter -t 1 -m -u -i -n sh

INGRESAR EN CUALQUIER CONTENEDOR

get a shell into ‘redis’ container namespace

$ docker run --rm -it --privileged --pid=container:redis walkerlee/nsenter -t 1 -m -u -i -n sh

REINICIAR SIEMPRE

docker run --restart=always redis

RESETEAR CONTENEDOR FALLIDO

docker run --restart=on-failure:10 redis

Ejectar Dockerfile

docker build -f Dockerfile .  
docker build -t <image_name> .

Arrancar imagen y decir el directorio local y el puerto.

docker run -p 8080:80 -d -v ~/Docker/www:/var/www  <image_name>

Ejecutar consola shell

docker exec -it <container_name> bash

Saber cual es la ip del contenedor

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_name>

Trucos

Cierra el contedor, sin salir de el, hacemos docker ps veremos que sigue corriendo COMANDO + P +Q

Volver a acceder a un contenedor

docker attach [hash]

Ejecutar en segundo plano Añadir flag -d al comando docker run

Demonios en Docker Podemos activar el servicio mediante service start | stop | status También podemos usar docker daemon

sudo docker daemon &

con el comando fg volvemos a segundo plano y lo detenemos con control + c

Ver si el demonio está corriendo con ps

ps -efa | grep docker

Muestra los logs del proceso en segundo plano a tiempo real

docker logs -f [hash]

Si con docker run no especidiamos comando, normalmente las imágenes traen un comando por defecto

docker run -P -d tomcat

Vincular a un contenedor que está corriendo

docker run -it ubuntu bash

El contenedor ya está corriendo… y volvemos a entrar por otro comando

docker exec -it [hash] bash

Si queremos más información

docker inspect [hash]

Mostrar solo has con bandera -q

docker ps -a -q

Borrar todos los contenedores

docker rm $(docker ps -a -q)

Para mostrar los logs de Docker en systemd usamos:

journalctl -u docker

Confuguración docker para upstart

vim -u NONE /etc/default/docker .

Para ver más información del demonio docker Debemos editar el fichero y en DOCKER_OPTS=‘—log-level=debug’

service docker restart
tail -f /var/log/upstart/docker.log

Confuguración docker para systemctl

service docker status
nano /lib/systemd/system/docker.service
EnviromentFile=-/etc/default/docker
ExecStart=/usr/bin/docker daemon $OPTIONS -H fd://
vi /etc/default/docker
OPTIONS='--log-level=debug'

para gestionar los logs

journalctl

Arrancer docker como deminio de manera interactiva

docker deamon --log-level=debug -H tcp://0.0.0.0:2375"

Para indicar al cliente que se conecte a tcp

docker -H tcp://0.0.0.0:2375 images

Para agilizar, podemos crear una variable de entorno

export DOCKER_HOST
$ docker -H tcp://0.0.0.0:2375 ps 
$ export DOCKER_HOST="tcp://0.0.0.0:2375" 
$ docker ps

Para ver las variables de entorno seteadas:

env |grep docker

DOCKERFILE

  • Provee una forma más efectiva de generar imágenes en vez de utilizar docker coomit
  • Se integra de manera automática en el flujo de desarrollo y de integración continua
  • Las instrucciones más utilizadas son FROM y RUN
  • Una vez contruido el Dockerfile, utilizar ‘docker build’ (-t) para genera la nueva imagen

Es una buena práctica añadir && para concatenar los RUN. Así reducimos el número de capas creadas

Ejemplo de un comentario

FROM ubuntu:14.04
RUN apt-get install -y vim && apt-get install curl

Docker history

  • El comando docker history muestra las capas de las cuales se encuentra creada la imagen.
  • Se puede observar cada capa, cuando fue creada, su tamaño y el comando el cual la generó

La instrucción CMD

  • CMD define el comando por defecto a ejecutar cuando se crea el contenedor.
  • Se puede usar tanto en formato Shellcomo Exac
  • Solo puede especificarse una vez en el dockerfile (Si se especifica varias, solo la última será válida)
  • Puede ser anulado por el cliente

Ejemplo de CMD

FROM ubuntu:14.04
CMD ping -c 10 www.google.com
FROM ubuntu:14.04
CMD ["ping", "-c", "5", "www.google.com"]
docker run ubuntu_ping
docker -ti ubuntu_ping bash

Ejemplo de CMD

FROM ubuntu:14.04
CMD echo $HOME
docker build -t ubuntu_echo .
docker run ubuntu_echo
docker run -ti ubuntu_echo bash

La instrucción ENTRYPOINT

  • Define el punto de entrada con el comando que el contenedor correrá cuando sea creado
  • Los argumentos de runtime son enviados como parámetros a la instrucción ENTRYPOINT
  • También posee la forma EXEC y Shell
  • El contenedor funciona a modo de ejecutable

Ejemplo de ENTRYPOINT

FROM ubuntu:14.04
ENTRYPOINT ping www.google.com -c 2
docker build -t ubuntu_ping .
docker run ubuntu_ping
FROM ubuntu:14.04
CMD ["ping", "-c", "5", "www.google.com"]
docker build -t ubuntu_ping .
docker run ubuntu_ping

¿Diferencias entre CMD y ENTRYPOINT?

Permite usar el contenedor como una app interactiva, permite que se le pasen argumentos. Podremos pasarles parámretros por docker run, por cmd al poner docker run … no interpretaba los comandos, lo interpretaba como uno nuevo.

En el 90 % de los casos deberemos usar el CMD para ejecutar la app de forma homogénea, pero si necesitamos poder ejecutarlo con parámetros dinámicos, deberemos usar ENTRYPOINT.

FROM ubuntu
CMD ["-c", "2", "www.google.com"]
ENTRYPOINT ["ping"]
docker build -t ubuntu_ping .
docker run ubuntu_ping
//obvia el CMD
docker run ubuntu_ping -c 1 www.yahoo.com

Copiar Archivos

  • Cuando creamos imágenes generalmente necesitamos hacer m´s cosas que instalar paquetes
  • Ejemplos

    • Compilar nuestro código y ejecutar nuestra aplicación
    • copiar archivos de configuración
    • copiar otro contenido
  • Para eso utilizamos la instrucción COPY
FROM UBUNTU
	COPY test.txt /tmp/holamundo
CMD cat /tmp/holamundo
echo "hola mundo" > test.txt

Dockerizando nuestra aplicación

  • Utilizar Dockerfiles resulta esencial para lograr que nuestra aplicación se ejecute en contenedores
  • Ej: Nuestra app, para ejecutarla necesitamos lo siguiente:

    • Python
    • Librerías accesorias
    • Archivos adiccionales
  • Qué sucede cuando queremos llevar nuestra aplicación a otro entorno?
  • Podemos hacer un docker container y utilizarlo de igual manera en todos nuestros ambientes

    FROM python:2.7
    COPY app.py requeriments.txt /app/
    RUN pip install -r /app/requeriments.txt
    CMD python /app/app.py
    EXPOSE 5000
    docker run app // No tenemos control sobre terminal, debemos matarlo docker kill [hash]
    docker run -d -P app // Lo ejecutamos como demonio, tenemos control sobre la shell

Especificando un directorio de trabajo

  • La instrucción WORKDIR permite setear el directorio de trabajo para el cual las instruccions RUN, CMD, ENTRYPINT Y COPY pueden utilizar
  • Sintáxis: WORKDIR /ruta/a/directorio
  • La ruta puede ser tanto absoluta como relativa dentro del contenedor
  • La instrucción puede utilizarse más de una vez.

La instrucción ADD

  • Posee el mismo formato que COPY y ambos operan de manera muy similar.
  • ADD tiene la habilidad de descomprimir archivos automáticamente
  • ADD puede obtener archivos de una URL (no descomprime en este caso)
  • Ambas instrucciones realizan un checksum de los archivos añadidos para calcular la caché.
FROM ubuntu
RUN apt-get update && apt-get install -y jp2a
ADD http://cdn.meme.am/instances/66627195.jpg /tmp/img.jpg
ENV TERM xterm-256color
CMD jp2a --size=60x40 /tmp/img.jpg

Otras instrucciones

  • MANTEINER agrega metadata al dockerfile sobre el dueño de la imagen
  • ENV permite añadir variables de entorno al contenedor
  • LABEL permie agregar etiquetas al contenedor

Consejos y buenas prácticas

  • Importante: Cada linea del dockerfile crea una imagen nueva si se modifica el estado de la imagen. Es importante buscar el balance entre la cantidad de capas creadas y la legibilidad del dockerfile
  • No instalar paquetes inneesarios
  • Utilizar ENTRYPOINT por dockerfile
  • Combinar comandos similares usando ”&&” y ””
  • Utilizar el sistema de caché de manera inteligente
  • https://docs.docker.com/engine/reference/builder/

Compartir imágenes

  • Para compartir nuestras imágenes tenemos las siguientes opciones

    • Utilizar docker hub
    • Utilizar nuestro propio servidor interno
    • Los comandos docker export y docker import
  • Las imágenes en docker hub pueden ser públicas o privadas
  • https://hub.docker.com

Debemos añadir tag para subirlo a docker hub

docker tag add usuariodockerhub/neodocker

Subir imagen a docker hub

docker push usuariodockerhub/neodocker

Borrando imágenes

  • Utilizar el domando docker rmi

    dock rmi [id imagen]
    docker rmi [repo:tag]

Instrucciones que podría contener un archivo Dockerfile:

FROM [imagen]:[tag]
    MAINTAINER enmaska @gmail.com
    LABEL"[clave]": "[valor]"
WORKDIR/[directorio raíz del proyecto]
COPY[ruta-relativa-del-archivo/carpeta] [destino-del-archivo/carpeta] ./
ADD[URL del archivo ha descargar]
RUN[comando] && [comando] && ... && \
    CMD [comando]
ENTRYPOINT[comando]
EXPOSE [puerto]
    ENV [variable de entorno]

Los comandos a continuación permiten la construcción y configuración de una imagen a partir de un documento Dockerfile:

  • docker build [ruta del dockerfile] Inicializa la constricción de una imagen a partir de un archivo Dockerfile.
  • docker build -t [nombre-de-la-imagen:tag] [ruta…] Permite establecer un nombre y un tag a la imagen a generar.
  • docker run -ti [hash] bash para acceder

Crear Servidor Mysql

Mysql

MySQL

Arrancar contenedor docker

docker run -p 3306:3306 --name mysql_default -v ~/Docker/mysql/:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret -d mysql:5.7.24 --character-set-server=utf

Crear base de datos

CREATE DATABASE nombre_db;

Cambiar password a usuario root

ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpassword'

Conectar a mysql

docker exec -it mysql_default mysql -u root -p

backups & restore

Backup
 docker exec mysql_default /usr/bin/mysqldump -u root --password=secret DATABASE > backup.sql
Restore
cat backup.sql | docker exec -i mysql_default /usr/bin/mysql -u root --password=secret DATABASE

EXPORTAR MONGO A LOCAL

backup

$ docker exec -it mongo_default mongodump --out /data/hotel-backup-$(date +'%Y%m%d%H%M%S') --db hotel
$ docker exec -it mongo_default ls -lrt /data
$ docker cp mongo_default:/data/hotel-backup-20180215142035 ~/Docker/mongo/

restaurar

$ docker cp ~/Docker/mongo/hotel-backup-20160831103407 mongo_default:/data
$ docker exec -it mongo_default mongorestore /data/hotel-backup-20160831103407

SCRIPT BACKUP MONGO

#!/bin/sh
export DATABASE_NAME="planets"
export TIMESTAMP=$(date +'%Y%m%d%H%M%S')
docker exec -t mongodb-${DATABASE_NAME} mongodump --out /data/${DATABASE_NAME}-backup-${TIMESTAMP} --db ${DATABASE_NAME}
docker cp mongodb-${DATABASE_NAME}:/data/${DATABASE_NAME}-backup-${TIMESTAMP} .

Si deseas ejecutar la consola de mongo…

docker exec -it mongo_default /bin/sh