Docker para Desarrolladores

Webinar UNLu - Septiembre 2020

Quienes Somos

Como contactarnos

@tdelvechio - tdelvechio@unlu.edu.ar

agustinrodriguez206@gmail.com

Antes de arrancar

El webinar dura 2 días

 

Hoy y mañana de 17 a 18:30

Antes de arrancar

No es TALLER

 

Conviene prestar atención y hacer preguntas

Antes de arrancar

Todo el material esta online...

...o va a estar (eventualmente)

Antes de arrancar

Motivación de la charla

Es una introducción

No alcanza para salir usando Docker en proyectos

Pero esperamos que ayude a romper la inercia a la hora de arrancar

Como tecnologia, a veces Docker esta subvalorado (por complejo)

A veces esta sobrevalorado (proyectos chicos que no necesiten un entorno complejo)

La idea es que se pregunte al final de cada dia

Introducción

Virtualización

Proceso donde se crea, vía software, algún recurso tecnológico que no existía previamente

Virtualización

Como concepto es casi tan antiguo como la computación en si

Virtualización

En las últimas 2 décadas la industria adoptó diversos mecanismos de virtualización para proveer servicios

 

Cloud Computing como caso paradigmático

Virtualización

2 tipos de virtualización

Contenedores

Hipervisores

Virtualización

2 tipos de virtualización

Contenedores

Hipervisores

Maquinas

Virtuales

Linux

Containers

Virtualización

Contenedores

Tecnología de virtualización ligera

 

Funciona por medio del aislamiento (isolation)

Contenedores

No son mutuamente excluyentes VMs y Containers

Ventajas de virtualizar

Aislamiento (seguridad)

Portabilidad

Eficiencia (Caso de Containers)

Docker

Tecnología de contenedores Open Source

 

Estándar (casi sinónimo de containers)

 

Despliegue de entornos de muy bajo costo (no solo económico)

Docker

Docker

Alguna terminología asociada

Engine

Build File

Imagen

Contenedor

Red y Almacenamiento

Docker

Primeros Pasos

Docker

Instalación

Primeros comandos

 

Comenzar a interactuar con docker

Objetivos

 

correr un contenedor y conocer su estado

docker ps
docker run
docker run hello-world
docker ps
docker ps -a

Inicio

docker ps
CONTAINER ID - IMAGE - COMMAND - CREATED - STATUS - PORTS

docker ps -a
CONTAINER ID	IMAGE			COMMAND	    	CREATED	        STATUS                      PORTS	NAMES
78523e4c21ff    hello-world		"/hello"	3 seconds ago	Exited (0) 2 seconds ago                                                    jovial_snyder

docker run kodekloud/simple-webapp

Ejecutar en segundo plano

docker run -d kodekloud/simple-webapp
docker ps
docker ps -a

Ejecutar en segundo plano

cat /etc/*release*
docker run -it ubuntu bash 
cat /etc/*release*

Ejecutar dentro del contenedor

Frenar y eliminar Contenedores

 

 

 

Frenar y eliminar un contenedor

eliminar una imagen

¿Cómo Freno todo esto?

docker stop
docker rm
docker rmi

Detener contenedores

docker ps
CONTAINER ID        IMAGE	COMMAND		CREATED             STATUS              PORTS	NAMES
5c2f46fc8f0c        ubuntu	"sleep 300"  7 seconds ago       Up 7 seconds               stupefied_hodgkin4
docker stop 5c2f46fc8f0c
docker run -d  ubuntu sleep 300

Eliminar contenedores

docker ps
CONTAINER ID        IMAGE	COMMAND		CREATED             STATUS              PORTS	NAMES
5c2f46fc8f0c        ubuntu	"sleep 30"  7 seconds ago       Up 7 seconds               stupefied_hodgkin4
docker stop stupefied_hodgkin4
docker rm stupefied_hodgkin4

Eliminar imagenes

docker ps
CONTAINER ID        IMAGE	COMMAND		CREATED             STATUS              PORTS	NAMES
5c2f46fc8f0c        ubuntu	"sleep 30"  7 seconds ago       Up 7 seconds               stupefied_hodgkin4
docker stop stupefied_hodgkin4
docker rm stupefied_hodgkin4
docker rmi ubuntu
docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
ubuntu                          latest              adafef2e596e        3 seconds ago         73.9MB

Demo

Objetivo

 

Mostrar como vincular un puerto en el host con uno en el contenedor

Ejemplo 3

Configuración de puertos

docker run -p 
docker run -p 5050:8080  -d kodekloud/simple-webapp
docker run -p 5051:8080 -d kodekloud/simple-webapp
docker run -p 5052:8080 -d kodekloud/simple-webapp

Puertos

crear múltiples contenedores

docker ps

CONTAINER ID    IMAGE                       COMMAND             PORTS                       NAMES
6516cc6a267a    kodekloud/simple-webapp     "python app.py"     0.0.0.0:5050->8080/tcp      cool_feynman
47d8534db6fa    kodekloud/simple-webapp     "python app.py"     0.0.0.0:5051->8080/tcp      pedantic_zhukovsky
2800dda57efd    kodekloud/simple-webapp     "python app.py"     0.0.0.0:5052->8080/tcp      competent_diffie

ip:puerto(host)->puerto(contenedor)

Configuración Volumenes

docker run -v 

Objetivo

 

Mostrar como vincular un directorio en el host con uno en el contenedor

docker run -v scripts:/home/ ubuntu

Directorio(host):Directorio(contenedor)

HOST

CONTENEDOR

Configuracion de Volumenes

¿Preguntas?

Final primer dia

Repaso primer día 

Se usa el CLI para generar containers, los cuales se construyen desde las imagenes

Repaso primer día 

Los containers corren procesos (idealmente uno solo)

Repaso primer día 

Se pueden usar imágenes pre-armadas

o generar propias (hoy veremos como)

 

(en lo cotidiano se da una mezcla de ambos enfoques)

Repaso primer día 

Usando Docker

Ejemplo 1

 

Construir una imagen de Docker (y usarla)

Ejemplo 1 - Objetivo

Ejecutar un script php con el CLI del lenguaje sin tenerlo instalado en el Host. Para ello se creara una imagen que ejecute dicho contenedor

Ejemplo 1 - Inicio

mkdir -p ~/webinar/construir-imagen/
cd ~/webinar/construir-imagen/
nano Dockerfile

Ejemplo 1 - Dockerfile

FROM php:7-cli
COPY . /tmp/app
WORKDIR /tmp/app
CMD [ "php", "./script.php" ]

FROM indica desde que imagen base se construirá la nueva imagen que estamos definiendo

COPY copia los archivos indicados al momento de generar la imagen

source: https://docs.docker.com/engine/reference/builder/

WORKDIR establece el directorio actual (equivalente a cd)

CMD define el comando que se ejecutara por default al generar un contenedor

Ejemplo 1 - Dockerfile

echo '<?php echo "Hola Mundo desde PHP\n";' > script.php
docker build --tag webinar/ejemplo-1 .
docker run webinar/ejemplo-1

Se crea el script de ejemplo

Se construye la imagen a partir del Dockerfile

Se genera un contenedor a partir de la imagen construida

Ejemplo 1 - Demo

Ciclo de Vida de un Contenedor

(o como ver que los contenedores son efímeros)

Ejemplo 2

Ejemplo 2 - Objetivo

Entender que el ciclo de vida de los contenedores es efímero. Existen mientras dura un proceso ejecutado "en el" y luego se eliminan completamente. Se borra todo. No solo se borra lo que se hizo mientras estaba “vivo”. También se borran los datos generados en él

Ejemplo 2 - Inicio

docker run -it alpine sh

Comando run en Docker CLI

Ejemplo 2 - Inicio

docker run -it alpine sh

Comando CLI

Ejemplo 2 - Inicio

docker run -it alpine sh

Imagen base

Ejemplo 2 - Inicio

docker run -it alpine sh

opciones

Ejemplo 2 - Inicio

docker run -it alpine sh

comando a ejecutar dentro

Ejemplo 2 - Dentro del container

curl www.google.com
# Error!!!!!!
apk add curl
curl www.google.com
# Exito
exit

Ejemplo 2 - De nuevo run

docker run -it alpine sh

¿Que es lo que hace el CLI de Docker?

Ejemplo 2 - Demo

El Bueno, El Malo y El Feo

Malas prácticas

Buenas prácticas

FROM alpine:latest
RUN apk add --no-cache curl
CMD curl www.google.com
docker run --rm curlimages/curl:7.72.0 www.google.com

Mejores prácticas!!!

Ejemplo 3

Ejecución de servicios

Ejemplo 3 - Explicación

Uno de los usos más populares de Docker es en el contexto de ejecutar servicios. Para Docker es un proceso más, con la diferencia que solo será detenido en caso de que el administrador lo haga explicito (vía comando stop).

Ejemplo 3 - Comandos

docker run -d busybox /bin/sh -c "while true; do echo hello world; sleep 2; done"

Ejemplo 3 - Comandos

docker run -d busybox /bin/sh -c "while true; do echo hello world; sleep 2; done"

comando

Ejemplo 3 - Comandos

docker run -d busybox /bin/sh -c "while true; do echo hello world; sleep 2; done"

imagen

Ejemplo 3 - Comandos

docker run -d busybox /bin/sh -c "while true; do echo hello world; sleep 2; done"

comando dentro del contenedor

Ejemplo 3 - Comandos

docker run -d busybox /bin/sh -c "while true; do echo hello world; sleep 2; done"

opción

Ejemplo 3 - Gestión

docker ps
docker logs <container_id>
docker logs -f <container_id>
docker stop <container_id>
docker rm <container_id>

Ejemplo 3 - Demo

Docker compose

Docker compose

¿Que limitaciones tiene Docker?

¿Porque Docker Compose?

Docker compose

Entornos multi-containers aislados entre si

Docker compose

LAMP: Linux, Apache, MySQL, PHP

MEAN: MongoDB, Express.js, Angular, Node.js

ELK: ElasticSearch, Logstash, Kibana

 

O lo que sea necesario

Docker compose

¿Como funciona?

Selección de

Imágenes

Propias

(Dockerfile)

Terceros

(Hub)

Definición del entorno

version: '2.0'
services:
  web:
    build: .
    ports:
    - "5000:5000"
    volumes:
    - .:/code
    - logvolume01:/var/log
    links:
    - redis
  redis:
    image: redis
volumes:
  logvolume01: {}
docker-compose.yml

Build and

Run!!

Definición del entorno

version: '2.0'
services:
  web:
    build: .
    ports:
    - "5000:5000"
    volumes:
    - .:/code
    - logvolume01:/var/log
    links:
    - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

Formato yaml

Referencia y versiones

Versiona toda una pila de servicios...

... y sus interacciones

Puedo publicar mi app y que el resto la levanten sin mucho esfuerzo (salvo instalar Docker Compose)

Ejemplo 1

Construir un entorno LAMP

Ejemplo 1 - Inicio

mkdir -p ~/webinar/docker-compose/ejemplo-1
cd ~/webinar/docker-compose/ejemplo-1
echo "<?php phpinfo();" > index.php
vim docker-compose.yml

Ejemplo 1 - Definición

version: '3'

services:
    web:
        image: php:7.4.9-apache
        ports:
            - 8888:80
        volumes:
            - .:/var/www/html
        links:
            - 'db'
    db:
        image: mysql:8.0
        volumes:
            - mysql_volume:/var/lib/mysql
        environment:
            TZ: "Argentina/Buenos_Aires"
            MYSQL_ALLOW_EMPTY_PASSWORD: "no"
            MYSQL_ROOT_PASSWORD: "webinar-root-pass"
            MYSQL_USER: 'webinar-user'
            MYSQL_PASSWORD: 'webinar-pass'
            MYSQL_DATABASE: 'webinar-db'

    adminer:
        image: adminer
        ports:
          - 8889:8080

volumes:
    mysql_volume:

Ejemplo 1 - Ejecución

docker-compose up

Ejemplo 1 - Demo

Ejemplo 2

Adaptar un entorno a necesidades propias

Ejemplo 2

Se quiere incorporar en la imagen del contenedor de PHP del ejemplo 1, una libreria de PHP conocida como PDO. Esto cuenta como una personalización de un contenedor, y es lo que mostraremos en este ejemplo 2

Ejemplo 2 - Modificación

version: '3'

services:
    web:
        image: php:7.4.9-apache
        ports:
            - 8888:80
        volumes:
            - .:/var/www/html
        links:
            - 'db'
...
version: '3'

services:
    web:
        build: .
        ports:
            - 8888:80
        volumes:
            - .:/var/www/html
        links:
            - 'db'
...

docker-compose.yml (ejemplo 1)

docker-compose.yml (ejemplo 2)

Ejemplo 2 - Imagen

version: '3'

services:
    web:
        build: .
        ports:
            - 8888:80
        volumes:
            - .:/var/www/html
        links:
            - 'db'
...

docker-compose.yml

FROM php:7.4.9-apache
RUN docker-php-ext-install pdo pdo_mysql

Dockerfile

¿Que es docker-php-ext-install?

Ejemplo 2 - Build & Up!

docker-compose build
docker-compose up

Ejemplo 2 - Demo

Ejemplo 3

Despliegue completo del CMS Wordpress

Ejemplo 3 - Objetivo

Instalación de un software de tercero usando Docker Compose

Ejemplo 3 - Entorno

version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8888:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress

volumes:
    db_data: {}

Ejemplo 3 - Run

docker-compose up -d

detached from process

Ejemplo 3 - Demo

Ejemplo 3 - Demo

docker-compose logs
docker-compose logs -f
docker-compose top
docker-compose ps
docker-compose stop
docker-compose start
docker-compose down
docker-compose down --volumes

Infraestructura como código

Viejo modelo de administración de servidores

Viejo modelo de administración de servidores

¿Que lo caracterizaba?

Administradores que son los que conocen la infraestructura y los entornos

Los entornos se instalaron una vez y se van "actualizando", se los "cuida", tienen "nombre"

Si ocurre un problema o se rompe un server, generar el mismo entorno lleva tiempo

Que plantea IaC?

Los entornos no son "mascotas"

Son mas parecidos a "ganado"

Infraestructura como Código

Reproducibles en velocidad

Reproducibles en cantidad

Efimeros

Portables

Versionables

Herramientas y Ecosistema

Kubernetes (k8s)

VS Code Docker Plugin

Otras herramientas

Temas Avanzados

¿Preguntas?

Bibliografía y Recursos

Bibliografía

[1] T. Erl, R. Puttini, and Z. Mahmood, Cloud Computing: Concepts, Technology & Architecture, Edición: 1. Prentice Hall, 2013.

[2] J. Turnbull, The Docker Book: Containerization is the new virtualization, Edición: 18092. James Turnbull, 2014.

[3] Y. Brikman, Terraform: Up & Running: Writing Infrastructure as Code, Edición: 2. O’Reilly Media, 2019.

[4] O. Lamtzidis, “An IoT Edge-as-a-service (Eaas) Distributed Architecture & Reference Implementation,” 2019

Recursos

Webinar Docker

By agustin Rodriguez

Webinar Docker

  • 1,221