Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TICAR 2018 - De desarrollo a Producción usando Docker

TICAR 2018 - De desarrollo a Producción usando Docker

En el marco de TICAR, se presentan los flujos necesarios para implementar docker en desarrollo como producción

Christian Rodriguez

April 20, 2018
Tweet

More Decks by Christian Rodriguez

Other Decks in Technology

Transcript

  1. DE DESARROLLO A PRODUCCIÓN USANDO DE DESARROLLO A PRODUCCIÓN USANDO

    DOCKER DOCKER Christian A. Rodriguez https://github.com/chrodriguez @car_unlp 
  2. AGENDA AGENDA Docker: introducción rápida Consideraciones para trabajar con docker

    Volumenes Docker Compose Work ow de desarrollo Docker en producción Rancher Work ow completo
  3. ¿QUÉ ES DOCKER? ¿QUÉ ES DOCKER? Contenedores de software. Empaqueta

    aplicaciones en una unidad estándar de intercambio. Única pieza de software en un lesystem completo que contiene todo lo necesario para ejecutar una aplicación: código, librerías, herramientas, etc. Garantiza que el software siempre correrá de igual forma sin importar su ambiente.
  4. ¿POR QUÉ DOCKER? ¿POR QUÉ DOCKER? Rápida con guración de

    entornos de desarrollo. Favorece las arquitecturas de microservicios. Diferencias entre el ambiente de desarrollo, testing y producción. Instalación de una aplicación en diferentes plataformas. Deploy de aplicaciones complejas. Ejecución de código antiguo. Escalamiento horizontal.
  5. LA IDEA DETRÁS DE LOS CONTENEDORES LA IDEA DETRÁS DE

    LOS CONTENEDORES Sistema Operativo recortado. Un único proceso corriendo: buena práctica. No utilizan manejadores de procesos tipo systemd. Red privada bridgeada en los contenedores. Si se quiere exponer un puerto se debe realizar explícitamente. El lesystem utiliza Union File System ( ). Basado en capas. Al eliminar un contenedor, su lesystem desaparece. UFS
  6. IMÁGENES Y CONTENEDORES IMÁGENES Y CONTENEDORES Imagen: Filesystem y parámetros

    para utilizarla. No cambia nunca y no tiene estados. Contenedor: Instancia de una imagen (resultado de ejecutarla). Tiene una capa de RW volátil.
  7. COMANDOS BÁSICOS COMANDOS BÁSICOS # Más usados docker run docker

    ps docker build docker images docker logs docker inspect docker volume # Otros comandos comunes docker commit docker pull docker push docker tag
  8. UN EJEMPLO DE USO DE DOCKER UN EJEMPLO DE USO

    DE DOCKER El siguiente es un ejemplo interactivo $ docker run --rm -it ubuntu:14.04 Unable to find image 'ubuntu:14.04' locally 14.04: Pulling from library/ubuntu c2c80a08aa8c: Pull complete 6ace04d7a4a2: Pull complete f03114bcfb25: Pull complete 99df43987812: Pull complete 9c646cd4d155: Pull complete Digest: sha256:b92dc7814b2656da61a52a50020443223445fdc2caf1ea0c Status: Downloaded newer image for ubuntu:14.04 root@99a3403db59a:/# cat /etc/issue Ubuntu 14.04.5 LTS \n \l
  9. IMÁGENES A PARTIR DE UN CONTENEDOR IMÁGENES A PARTIR DE

    UN CONTENEDOR Como los contenedores establecen una capa volátil por encima de la pila de capas de una imagen origen, una vez editado todo lo necesario en un contenedor, los cambios pueden comitirse en una imagen. $ docker run -it ubuntu:14.04 root@7c78d0a777df:/# apt-get update \ && apt-get install -y nginx && apt-get clean root@7c78d0a777df:/# exit
  10. IMÁGENES A PARTIR DE UN CONTENEDOR IMÁGENES A PARTIR DE

    UN CONTENEDOR Veri camos el contenedor anterior CREAMOS LA IMAGEN CREAMOS LA IMAGEN A partir de ahora es posible utilizar la imagen chrodriguez/nginx:ubuntu-14.04 $ docker ps -a CONTAINER ID IMAGE COMMAND 7c78d0a777df ubuntu:14.04 "/bin/bash" $ docker commit 7c78d0a777df chrodriguez/nginx:ubuntu-14.04 $ docker run --rm -p 8080:80 chrodriguez/nginx:ubuntu-14.04 \ nginx -g "daemon off;"
  11. DOCKERFILE DOCKERFILE Archivo de texto plano para crear imágenes de

    Docker. Permite escribir instrucciones a ejecutar. Automatiza el proceso de la creación de imágenes. Permite repetir y modi car fácilmente una imagen. Generar de forma simple imágenes derivadas.
  12. DOCKERFILE DOCKERFILE CREAMOS LA IMAGEN CREAMOS LA IMAGEN FROM ubuntu:16.04

    # Instalar Nginx y configurar una página personalizada RUN apt-get update && apt-get install -y nginx RUN mkdir /var/www/html/ejemplo RUN echo "<html><h1>Nginx en Docker</h1></html>" > /var/www/html/ EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] docker build -f Dockerfile -t chrodriguez/nginx:ubuntu-16.04 .
  13. HISTORIA DE IMAGEN HISTORIA DE IMAGEN $ docker history chrodriguez/nginx:ubuntu-16.04

    IMAGE CREATED CREATED BY 8fd110f3364a 9 minutes ago /bin/sh -c #(nop) CMD ["nginx" df1abe4570d5 9 minutes ago /bin/sh -c #(nop) EXPOSE 80/tcp 4c9ad433769b 9 minutes ago /bin/sh -c echo "<html><h1>Nginx aff42d6aa899 9 minutes ago /bin/sh -c mkdir /var/www/html/e 136943551ea1 9 minutes ago /bin/sh -c apt-get update && apt f753707788c5 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/ba <missing> 4 weeks ago /bin/sh -c mkdir -p /run/systemd <missing> 4 weeks ago /bin/sh -c sed -i 's/^#\s*\(deb. <missing> 4 weeks ago /bin/sh -c rm -rf /var/lib/apt/l <missing> 4 weeks ago /bin/sh -c set -xe && echo '#! <missing> 4 weeks ago /bin/sh -c #(nop) ADD file:b1cd0
  14. LA REGISTRY LA REGISTRY Servicio para almacenar y distribuir imágenes

    de Docker. Disponible en forma local o usar servicios en la nube: Instalación local: Acceso local para mayor velocidad de descarga. Imágenes privadas en un ambiente controlado y gestionado por la organización. Servicios en la nube: Generalmente las registries privadas tienen costo.
  15. REGISTRY COMO SERVICIOS REGISTRY COMO SERVICIOS Gratis para imágenes públicas.

    Plan pago para imágenes privadas. Soporta builds automáticos. Cuentas para organizaciones. Gratis para imágenes públicas o privadas. Soporta builds automáticos. Cuentas para organizaciones. Docker Hub Gitlab Registry
  16. INTRODUCCIÓN INTRODUCCIÓN Ya sabemos que: Las imágenes Docker son inmutables.

    Los contenedores crean una capa con las diferencias correspondientes respecto de la imagen original. Entonces los contenedores deberían minimizar los cambios respecto de la imagen original. Optimizando el uso de espacio y evitando impactos de performance. Promoviendo la reusabilidad.
  17. INMUTABILIDAD EN LA INFRAESTRUCTURA INMUTABILIDAD EN LA INFRAESTRUCTURA Desplegar una

    actualización de una aplicación, consiste en crear nuevas intancias y destruir las anteriores, en vez de actualizarlas sobre la instancia productiva. Una vez que una aplicación está corriendo, ¡evitamos tocarla! promoviendo así: Repetibilidad. Reducir costos de mantenimiento. Simpli car rollbacks.
  18. LOGRAR INMUTABILIDAD LOGRAR INMUTABILIDAD Deben cumplirse los siguientes requerimientos: La

    aplicación debe ser stateless. Su estado debe almacenarse en un servicio por fuera del alcance de la infraestructura inmutable. Existe un template y/o conjunto de instrucciones que permiten desplegar una instancia de la aplicación desde cero. El segundo punto lo resuelve fácilmente Docker.
  19. ¿QUÉ ES DINÁMICO ENTONCES? ¿QUÉ ES DINÁMICO ENTONCES? Archivos que

    se generan por la aplicación. Uploads desde la aplicación. Logs. Spool.
  20. IMÁGENES MAL FORMADAS IMÁGENES MAL FORMADAS Un mal diseño de

    las imágenes impactará en la performance de los contenedores que generarán grandes capas con datos dinámicos. Ante la actualización del contenedor, estos datos se perderán.
  21. ¿CÓMO VERIFICAR UN MAL DISEÑO? ¿CÓMO VERIFICAR UN MAL DISEÑO?

    La opción -s visualiza el tamaño de la capa del contenedor. Su valor debe tender a cero $ docker ps -s docker ps -s CONTAINER ID IMAGE .... SIZE 6ce39ac62830 ubuntu:16.04 .... 0B (virtual 120MB) root@6ce39ac62830:/# echo "hola" > /tmp/prueba $ docker ps -s docker ps -s CONTAINER ID IMAGE .... SIZE 6ce39ac62830 ubuntu:16.04 .... 5B (virtual 120MB)
  22. ¿CÓMO VERIFICAR UN MAL DISEÑO? ¿CÓMO VERIFICAR UN MAL DISEÑO?

    El tamaño es lo que crece el contenedor respecto de la imagen. El tamaño virtual es lo que ocupa el contenedor sumado al tamaño de la imagen. root@6ce39ac62830:/# dd if=/dev/zero of=/tmp/lala.img bs=1M count 10+0 records in 10+0 records out 10485760 bytes (10 MB, 10 MiB) copied, 0.0127865 s, 820 MB/s $ docker ps -s docker ps -s CONTAINER ID IMAGE .... SIZE 6ce39ac62830 ubuntu:16.04 .... 10.5MB (virtual 13 $ docker diff 6ce39ac62830 C /tmp A /tmp/lala.img A /tmp/prueba
  23. BUENAS PRÁCTICAS BUENAS PRÁCTICAS Los contenedores deben ser efímeros: pararlos,

    destruirlos y volverlos a iniciar con una mínima con guración. Evitar paquetes innecesarios: las imágenes no deben incluir paquetes que no se utilicen. Un proceso por contenedor: en la mayoría de los casos, se debe correr un proceso por contenedor. La (in)necesidad de ssh: acceder a un contenedor es algo que debemos evitar.
  24. ¿CÓMO SE PERSISTEN LOS DATOS? ¿CÓMO SE PERSISTEN LOS DATOS?

    Los contenedores son volátiles e inmutables. Debemos preservar la información importante. ¿Dónde? En volúmenes de datos.
  25. CARACTERÍSTICAS DE LOS VOLÚMENES CARACTERÍSTICAS DE LOS VOLÚMENES No utilizan

    un sistema de archivos de unión (UFS). Pueden compartirse y reusarse entre contenedores. Los cambios se hacen directamente en el volumen. La información del volumen no se incluye en la imagen. Persisten aún cuando se eliminen todos los contenedores que los usan. Pueden quedar volúmenes sin referenciar.
  26. TIPOS DE VOLÚMENES TIPOS DE VOLÚMENES Al crear un volúmen

    anónimo o nombrado, la información que exista en el punto de montaje se copia al volumen. Con volúmenes desde el SO host o desde otro contenedor, se oculta la información que exista en el punto de montaje. Correspondencia con el comando mount.
  27. MANEJO DE VOLÚMENES MANEJO DE VOLÚMENES $ docker run -it

    -v /prueba ubuntu:16.04 /bin/bash root@a9c1a6e6c0ea:/# ls /prueba/ root@a9c1a6e6c0ea:/# echo "Prueba" > /prueba/archivo root@a9c1a6e6c0ea:/# exit $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS a9c1a6e6c0ea ubuntu "/bin/bash" 2 minutes ago Exited (0) A $ docker volume ls DRIVER VOLUME NAME local e9c7022b8c7bec55891ca44b8c40de1e5f41cf0fe9505a334bca0 $ ls /var/lib/docker/volumes/e9c7022b8c7bec55891ca44b8c40de1e5f41 archivo
  28. VOLÚMENES NOMBRADOS VOLÚMENES NOMBRADOS $ docker run -it -v test:/prueba

    ubuntu /bin/bash root@7def6f99f957:/# ls /prueba/ root@7def6f99f957:/# echo "Prueba" > /opt/archivo root@7def6f99f957:/# exit $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS 7def6f99f957 ubuntu "/bin/bash" 2 minutes ago Exited (0) $ docker volume ls DRIVER VOLUME NAME local test $ ls /var/lib/docker/volumes/test/_data archivo
  29. ¿QUÉ ES DOCKER COMPOSE? ¿QUÉ ES DOCKER COMPOSE? Herramienta que

    permite correr aplicaciones compuestas por múltiples contenedores. La arquitectura se de ne y con gura en un archivo de texto ( ). Simple e intuitivo. Se vale de un comando para: Iniciar, detener y reconstruir servicios. Ver el estado de los servicios, los logs, etc. YAML
  30. VERSIONES DE DOCKER COMPOSE VERSIONES DE DOCKER COMPOSE Hay tres

    versiones mayores diferentes, la 1, la 2 y la 3. Entre la 1 y la 2 no son compatibles entre sí, entre la 2 y la 3 comparten estructura, pero se quitan algunas opciones en la 3. Veremos la sintaxis de la versión 3.
  31. DOCKER COMPOSE: EJEMPLO DOCKER COMPOSE: EJEMPLO Instalación de Wordpress. Vamos

    a crear un archivo llamado docker- compose.yml. De niremos allí la arquitectura de la aplicación. Nos valdremos del comando docker-compose para levantar Wordpress e interactuar con los contenedores generados.
  32. DOCKER COMPOSE PARA WORDPRESS DOCKER COMPOSE PARA WORDPRESS Descargar version:

    '3' services: db: image: mysql:5.7 volumes: - dbdata:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: super_secret MYSQL_DATABASE: wordpress wordpress: depends_on: - db image: wordpress:4.9.5-php7.0-apache docker-compose.yml
  33. INICIANDO LOS SERVICIOS DE WORDPRESS INICIANDO LOS SERVICIOS DE WORDPRESS

    $ docker-compose up -d Creating network "wordpress_default" with the default driver Creating volume "wordpress_dbdata" with default driver Creating volume "wordpress_site" with default driver Creating wordpress_db_1 ... done Creating wordpress_wordpress_1 ... done $ docker-compose ps Name Command State ----------------------------------------------------------------- wordpress_db_1 docker-entrypoint.sh mysqld Up wordpress_wordpress_1 docker-entrypoint.sh apach ... Up
  34. USAMOS WORDPRESS USAMOS WORDPRESS $ docker-compose logs -f wordpress_1 |

    172.27.0.1 - - [18/Apr/2018:17:40:45 +0000] "GET / wordpress_1 | 172.27.0.1 - - [18/Apr/2018:17:40:45 +0000] "GET /w AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safar wordpress_1 | 172.27.0.1 - - [18/Apr/2018:17:40:47 +0000] "GET / Safari/537.36"
  35. INICIANDO Y DETENIENDO WORDPRESS INICIANDO Y DETENIENDO WORDPRESS Para detenerlo

    Para iniciarlo docker-compose down detiene y luego remueve los contenedores $ docker-compose stop Stopping wordpress_wordpress_1 ... done Stopping wordpress_db_1 ... done $ docker-compose start Starting db ... done Starting wordpress ... done
  36. LOS EQUIPOS DE DESARROLLO… LOS EQUIPOS DE DESARROLLO… Deben Versionar

    el código: SVN, GIT. . Deberían Aplicar Testing: TDD o mejor aún BDD. Revisión de código. Integración continua. Flujos claros de versionado de código: , , . Utilizar Versionado semántico git- ow GitLab Flow Github Flow
  37. LA INFRAESTRUCTURA… LA INFRAESTRUCTURA… Debe proveer ambientes diferentes para poder

    aplicar controles de calidad previos a la puesta en producción: Preproducción QA Pruebas Automatizar la creación y mantenimiento de estos ambientes
  38. EL VERSIONADO EL VERSIONADO Implementando un ujo para el uso

    del versionado de código, se realizan varios merge a la rama principal, generalmente master. Integración continua. Correr tests antes de cada merge. Revisión de código: simple con ujos propuestos por GitHub/Gitlab a través PR/MR.
  39. NUEVOS RELEASES NUEVOS RELEASES Un nuevo release respeta semver, entonces

    su nombre será X.Y.Z. Según el lenguaje, será necesario compilar y subir el binario a un repositorio: o . Con docker es el momento de crear una imagen docker y subirla a la registry Si automatizamos estas tareas estamos implementando Artifactory Nexus entrega continua
  40. DESPLIEGUE DE VERSIONES DESPLIEGUE DE VERSIONES No es lo mismo

    un despliegue de cero que una actualización Existe estrategias de actualización: Esta tarea es complicada si se realiza manual Sobre todo con aplicaciones que escalan horizontalmente Docker es una gran simpli cación a este problema Canary deployment Blue Green deployment
  41. DOS ENFOQUES DOS ENFOQUES Usar Docker para iniciar servicios de

    forma aislada. Usar un cluster de Docker.
  42. DOCKER EN FORMA AISLADA DOCKER EN FORMA AISLADA Cada servidor

    Linux corre el servicio de Docker. Los contenedores pueden iniciarse automáticamente durante el booteo usando: Manejadores de procesos: , o , etc A través de políticas de reinicio (Docker >= 1.2). upstart systemd supervisor
  43. CLUSTERS DOCKER CLUSTERS DOCKER Un cluster dispone de nodos corriendo

    Docker Engine de tal forma de poder utilizarlos para correr contenedores. Estos nodos pueden usar SO muy pequeños (~ 50MB) dado que su única razón de ser es la de proveer un kernel con docker engine:
  44. CARACTERÍSTICAS DE TODOS LOS CARACTERÍSTICAS DE TODOS LOS CLUSTERS CLUSTERS

    Diseño descentralizado. Servicios, pods o stacks en vez de contenedores. Posibilidad de escalar. Conciliación para alcanzar el estado deseado. Service discovery. Load balancing. Actualizaciones en caliente.
  45. CONSIDERACIONES CONSIDERACIONES El scheduler es el encargado de determinar dónde

    se inicia cada contenedor. Asociado al scheduler trabajan los health checks que garantizan la conciliación de un estado deseado: que haya N contenedores para el servicio X. La distribución mágica del scheduler complica el manejo de volúmenes. Los volúmenes pertenecen a un nodo. Si el nodo cambia, se pierden los datos.
  46. VOLÚMENES DISTRIBUIDOS VOLÚMENES DISTRIBUIDOS Necesidad de compartir datos entre los

    nodos del cluster. Aparecen diferentes implementaciones de volúmenes compartidos. Las más populares son: NFS Flocker
  47. RANCHER RANCHER Interfaz web amigable para gestionar un cluster de

    Docker. Incluye una API que permite administrar el cluster. Utilidades de línea de comandos. Soporta múltiples plataformas de clustering para Docker: Cattle Kubernetes Swarm Apache Mesos Windows
  48. EL PROYECTO EN DESARROLLO EL PROYECTO EN DESARROLLO Según el

    readme, corremos: Notar que pasamos 2 docker-compose.yml En esta modalidad podemos trabajar sin instalar nada en nuestra PC, editando el archivo php de la raíz del proyecto cd docker docker-compose -p demo-lb-dev \ -f docker-compose.yml -f docker-compose.dev.yml up
  49. ENTREGA CONTINUA ENTREGA CONTINUA El archivo .gitlab-ci.yml Un nuevo tag

    equivale a una nueva imagen docker image: docker:latest services: - docker:dind stages: - build before_script: - export IMAGE_TAG="$CI_BUILD_REF_NAME" - docker login -u "gitlab-ci-token" -p "$CI_BUILD_TOKEN" $CI_RE build-docker-image: stage: build script: - docker build --pull -f docker/Dockerfile -t "$CI REGISTRY I
  50. LA APLICACIÓN EN RANCHER LA APLICACIÓN EN RANCHER Usaremos rancher-cli

    con el siguiente docker- compose.yml Con guraremos el load balancer a partir del label seteado rancher-cli utiliza variables de ambiente que lo con guran version: '2' services: web: image: registry.gitlab.com/chrodriguez/demo-lb:0.0.1 labels: application: demo-lb $ rancher up
  51. LAS PREGUNTAS… LAS PREGUNTAS… ¿Y los logs? ¿Y el monitoreo?

    ¿Y las bases de datos? ¿Y los backups? Todas tienen respuesta
  52. LAS BASES DE DATOS Y BACKUPS LAS BASES DE DATOS

    Y BACKUPS Las bases de datos pueden dockerizarse o no Los backups deben hacerse sólo de los volúmenes En mi caso, es una excelente alternativa Backupeando la base de datos de rancher, podemos recuperar nuestra infra completa rsnapshot
  53. ALGUNAS PERLITAS ALGUNAS PERLITAS Correr una aplicación X11: Compilar sin

    compilador: Bases de datos para desarrollo $ xhost + $ docker run -it --rm -e HOME=$HOME -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix -v $HOME:$HOME --user `id -u` jarfil/gimp-git $ docker run --rm -v "$PWD":/usr/src/myapp \ -w /usr/src/myapp gcc:4.9 gcc -o app *c -Wall docker run --name=mysql-5.6 -d \ -e MYSQL_ALLOW_EMPTY_PASSWORD=true -p 3307:3306 \ --restart=always -v mysql-5.6:/var/lib/mysql \ mysql:5.6