Skip to content

Instantly share code, notes, and snippets.

@Whistler092
Last active May 24, 2017 20:59
Show Gist options
  • Save Whistler092/2e0d29471ab3d0bf5f660e380acff6bd to your computer and use it in GitHub Desktop.
Save Whistler092/2e0d29471ab3d0bf5f660e380acff6bd to your computer and use it in GitHub Desktop.
Notas comunes sobre docker.
### Componentes de Docker
* Docker Engine
    - Demonio docker, tiene api para gestion de los contenedores, Volúmenes o redes virtuales
* Docker Client
- Hace uso de la Api de Docker Engine, se puede configurar para ingresar a un Docker Local O Docker Remoto
- Docker Info: Info de Docker en general, contenedores actuales, memoria disponible, etc
- Docker Images: Info de las imágenes instaladas en la maquina
- Docker Build: Es la creación de una imagen desde un `Dockerfile`
- Docker pull: Descarga en la máquina actual la versión de la imagen indicada.
- Docker push: Sube la versión indicacda a un Registro de Docker, permitiendo su distribución a otras máquinas
- Docker rmi: Elimina una imagen de la máquina actual.
- Docker run: crea un contenedor a partir de una imagen
    - Docker ps: muestra contenedores que están corriendo en la maquina. -a (Mostrar los que están detenidos)
    - Docker inspect: Información detallada del contenedor.
- Docker stop/ start: detiene y reanuda un contenedor.
    - Docker rm: Elimina el cotnenedor. Para borrar todo se ejecuta `docker rm -fv $(docker ps -aq)`
- Docker Logs: Muestra los logs del contenedor.
    - Docker stats: Muentra las estadisticas de ejecución del contenedor. Memoria, CPU, disco
- Docker exec: Ejecuta un comando dentro del contenedor.
    - Docker volume ls: lista los volumenes existentes en la máquina. `Docker volume --help`
    - Docker network ls: lista las redes existentes en la máquina. `Docker network --help`
  * Docker Registry
    - Servidor donde se publican las imágenes que genera el Docker Engine. Para que estén disponibles en cualquier maquina
- Docker Hub.
-
Docker Compose
https://github.com/docker/compose
Compose is a tool for defining and running multi-container Docker applications.
With Compose, you use a Compose file to configure your application's services.
Then, using a single command, you create and start all the services from your configuration.
docker-compose up -d levanta la aplicación en modo demonio, docker-compose up la levanta en primer plano,
mostrando los logs de los distintos contenedores.
La ejecución sucesiva del comando docker-compose up -d sólo recrea los contenedores que hayan cambiado su imagen o su definición.
docker-compose up -d no hace el build de las imágenes locales.
Si deseas actualizar tu aplicación en base a los últimos cambios de tu código, necesitarás hacer docker-compose build antes de ejecutar docker-compose up -d nuevamente.
Un truco para mejorar este proceso es montar tu código como un volumen en el fichero docker-compose.yml,
de tal manera que tu container siempre ve los últimos cambios en tu código fuente.
Compose command-line reference
https://docs.docker.com/compose/reference/
Compose file https://docs.docker.com/compose/compose-file/
Comandos Comunes
docker-compose permite definir prácticamente todos los flags que soporta el comando docker run,
pero docker-compose es mucho más fácil de utilizar. Las opciones más comunes son:
build: para indicar que el container se construye desde un Dockerfile local.
image: para indicar que el container corre un imagen remota.
command: para redefinir el comando que ejecuta el container en lugar del comando definido en la imagen.
environment: para definir variables de entorno en el contenedor.
Se pueden pasar haciendo referencia a un fichero usando la propiedad env_file.
Si la variable no tiene un valor dado, su valor se cogerá del entorno de shell que ejecuta el docker-compose up,
lo que puede ser útil para pasar claves, por ejemplo.
links: para definir relaciones entre contenedores.
ports: para mapear los puertos donde el contenedor acepta conexiones.
volumes: para definirir volúmes en el contenedor.
volumes_from: para reusar los volúmenes de otro contenedor.
La manera recomendada de construir una imagen es utilizar un fichero Dockerfile, un fichero con un conjunto de instrucciones que indican cómo construir una imagen de Docker.
Las instrucciones principales que pueden utilizarse en un Dockerfile son: https://docs.docker.com/engine/reference/builder/
FROM image: para definir la imagen base de nuestro contenedor.
RUN comando: para ejecutar un comando en el contexto de la imagen.
CMD comando: para definir el comando que ejecuta el container al arrancar.
EXPOSE puerto: para definir puertos donde el contenedor acepta conexiones
ENV var=value: para definir variables de entorno.
COPY origen destino: para copiar ficheros dentro de la imagen.
VOLUME path: para definir volúmenes en el contenedor.
La cache de Docker
La construcción de una imagen de Docker dado un Dockerfile puede ser un proceso costoso ya que puede implicar la instalación de un número elevado de librarías, y al mismo tiempo es un proceso bastante repetitivo porque sucesivos builds del mismo Dockerfile suele ser similares entre sí. Es por eso que Docker introduce el concepto de la cache para optimizar el proceso de construcción de imágenes.
Estructura de las imagenes Docker
Una imagen de Docker tiene una estructura interna bastante parecida a un repositorio de git.
Lo que conocemos como commits en git lo denominamos capas de una imagen en Docker.
Por lo tanto, una imagen (o repositorio) es una sucesión de capas en un Registro de Docker, donde cada capa almacena un diff respecto de la capa anterior.
Esto es importante de cara a optimizar nuestros Dockerfiles, por lo tanto cada instrucción de nuestro Dockerfile creara una y sólo una capa de nuestra imagen.
Así mismo, la cache de Docker funciona a nivel de instrucción. En otras palabras, si una línea del Dockerfile no cambia, en lugar de recomputarla, Docker asume que la capa que genera esa instrucción es la misma que la ejecución anterior del Dockerfile.
Por lo tanto, si tenemos una instrucción tal como:
RUN apt-get update && apt-get install -y git
que no ha cambiado entre 2 build sucesivos, los comandos apt-get no se ejecutarán, sino que se reusará la capa que generó el primer build.
Por tanto, aunque antes de ejecutar el segundo build haya una nueva versión del paquete git, la imagen construida a partir de este Dockerfile tendrá la versión de git anterior, la que se instaló en el primer build de este Dockerfile.
Instrucciones AND y COPY
El comportamiento de las instrucciones ADD y COPY es distinto en cuanto al comportamiento de la cache.
Aunque estas instrucciones no cambien, invalidan la caché si el contenido de los ficheros que se están copiando ha sido modificado.
Consejos para escribir un Dockerfile
1. Usa .dockerignore
El build de una image se ejecuta a partir de un Dockerfile y de un directorio, que se conoce con el nombre de contexto. Este directorio suele ser el mismo que el directorio donde se encuentra el Dockerfile, por lo que si ejecutamos la instrucción:
ADD app.py /app/app.py
Estamos añadiendo a la imagen el fichero app.py del contexto, es decir, el fichero app.py que se encuentra en el directorio donde está el Dockerfile. Dicho directorio se comprime y se manda al Docker Engine para construir la imagen, pero puede que tenga ficheros que no son necesarios. Es por eso que este directorio puede tener un fichero .dockerignore, que de una manera similar a fichero .gitignore, indica los ficheros que no deben ser considerados como parte del contexto del build.
2. Reduce el tamaño de tus imágenes al mínimo
Tu imagen Docker sólo debe contener lo estrictamente necesario para ejecutar tu aplicación. Con el objetivo de reducir complejidad, dependencias, tamaño de las imágenes, tiempos de build de una imagen, debes evitar la instalación de paquetes sólo por el hecho de que puedan ser útiles para depurar un contenedor. Como ejemplo, no incluyas editores de texto en tus imágenes.
3. Ejecuta sólo un proceso por contenedor
Salvo raras excepciones, es recomendable correr sólo un proceso por contenedor. Esto permite reutilizar contenedores más fácilmente, que sean más fáciles de escalar, y da lugar a sistemas más desacoplados. Por ejemplo saca tu lógica de logging a un contenedor independiente.
4. Minimiza el número de capas de tu imagen.
Como hemos dicho anteriormente, cada capa de una imagen se corresponde con una instrucción del Dockerfile. Compare el Dockerfile:
RUN apt-get update
RUN apt-get install -y bzr
RUN apt-get install -y cvs
RUN apt-get install -y git
RUN apt-get install -y mercurial
con este otro:
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
apt-get clean
Ambos son igualmente legibles, pero el primero genera 5 capas, y el segunda sólo una, que además ejecuta un apt-get clean que reduce el tamaño de dicha capa.
5. Optimiza el uso de la cache.
Optimiza el uso de la cache añadiendo al principio de tu Dockerfile las instrucciones que menos cambian (como la instalación de librerías), y dejando para el final las que más cambian (como el copiado del código fuente). Como ejemplo compare el Dockerfile:
FROM python:2.7
WORKDIR /app
ADD requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
ADD * /app
CMD ["python", "app.py"]
con este otro:
FROM python:2.7
WORKDIR /app
ADD * /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
El primero cachea la instalaciones de las dependencias pip siempre que no añadamos nuevas dependencias al fichero requirements.txt, antes de añadir el código fuente. Sin embargo, el segundo, aunque genere menos capas, no reusa la instalación de las dependencias porque ADD * /app invalida la cache en cuanto hay un cambio en nuestro código fuente.
6. Parametriza tus Dockerfiles usando argumentos
Aumenta la reusabilidad de tus Dockerfiles entre distintos entornos y aplicaciones parametrizando tus Dockerfiles con argumentos. Los argumentos son valores que se pasan como parámetros a cada build (aunque pueden tener valores por defecto), y que puedes utilizar en las instrucciones de tu Dockerfile. Por ejemplo, el Dockerfile:
FROM ubuntu
ARG user=root
ARG password
RUN echo $user $password
puede ser parametrizado de la siguiente manera:
docker build -t imagen --build-arg password=secret .
https://docs.docker.com/engine/installation/linux/ubuntu/#install-using-the-repository
https://docs.docker.com/engine/installation/linux/linux-postinstall/#configure-docker-to-start-on-boot
### Configurar socket de ubuntu.
- docker -v
- Se verifica que Docker no esté corriendo en los puertos
netstat -tlp
- service docker stop
- docker -H 192.168.80.54:2375 -d &
### Jenkins
```
docker run -p 8080:8080 -p 50000:50000 jenkins
$ docker exec -it ubuntu_bash bash
```
#### Links
* https://docs.docker.com/engine/reference/commandline/logs/#description
* https://wiki.jenkins-ci.org/display/JENKINS/Logging
* https://docs.docker.com/engine/reference/commandline/exec/#examples
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment