Curso de docker desde cero y para todos.
- https://docs.docker.com/install/linux/docker-ce/ubuntu/
- https://docs.docker.com/compose/
- https://docs.docker.com/machine/
- https://docs.docker.com/engine/reference/commandline/docker/
Las im谩genes en Docker, es el n煤cleo de un contenedor, es decir, sin la imagen el contenedor no puede existir. Las im谩genes albergan un sistema operativo, una aplicaci贸n, un sandbox, etc. Las im谩genes se pueden personalizar para crear desarrollos personalizados a nuestras necesidades. Dentro de una imagen podemos indicarle que puerto usar as铆 como la ejecuci贸n de un script de requerirse. Multi-stage (Significado: Ejecuci贸n de un n煤mero determinado de im谩genes para obtener una imagen como resultado)
docker search [Nombre_imagen]
Es el repositorio publico que usa Docker para poder descargar im谩genes, no obstante tambi茅n se puede disponer de un registry propio (dockerhub.hi.inet)
- Descargar imagen.
docker pull [Nombre_imagen]
- Listar im谩genes descargadas.
docker image ls [Nombre_imagen]
- Borrar im谩genes descargadas.
docker image rmi [Nombre_imagen]
- Subir im谩genes repositorio.
docker push [Nombre_imagen]
Los contenedores son "espacios" donde una aplicaci贸n puede "existir" mediante una imagen predeterminada o pre-definida que ha sido llamada para su ejecuci贸n como contenedor. Se puede asignar recursos definidos como el % de CPU, el % de RAM a los contenedores es decir, el n煤mero m铆nimo de recursos y m谩ximo.
- Para iniciar un contenedor:
docker run [Nombre_imagen]
- Para ver el estado de un contenedor:
docker ps -a // docker container ls -a // docker container ps -a
- Para detener un contenedor:
docker stop [ID_CONTAINER]
- Para arrancar un contenedor detenido:
docker start [ID_CONTAINER]
- Para iniciar un contenedor en base a un nombre:
docker run --name [Nombre_que_queremos_del_Contenedor] [Nombre_imagen]
- Para iniciar un contenedor en background:
docker run -dit --name [Nombre_que_queremos_del_Contenedor] [Nombre_imagen]
- Para ver el log de un contenedor:
docker logs [ID_CONTAINER]
- Para acceder a un contenedor corriendo en background:
docker exec -it [ID_CONTAINER]
- Para ejecutar comandos en un contenedor sin llegar a entrar en 茅l:
docker exec [ID_CONTAINER] mkdir -p /tmp/prueba-epg
docker exec [ID_CONTAINER] ls -lta /tmp
- En una 煤nica linea las dos anteriores:
docker exec [ID_CONTAINER] mkdir -p /tmp/prueba-epg || docker exec [ID_CONTAINER] ls -lta /tmp
- Para eliminar un contenedor:
docker rm -fv [ID_CONTAINER]
- Para borrar contenedores en una sola linea:
docker rm -fv $(docker ps -aq)
- Para ver el detalle de un contenedor:
docker inspect [ID_CONTAINER]
- Conectarse al contenedor por un puerto local del equipo anfitri贸n.
docker container run -d -p 8080:80 nginx
- Asignar puertos aleatorios a un contenedor.
docker container run -d -P nginx
- Mostrar varios puertos.
docker container run -d -p 8080:80 -p 3001:3000 -p 2222:2222 nginx (Tener cuidado con el puerto 22)
- Listar puertos abiertos de un contenedor.
docker container port [ID_CONTENEDOR]
En docker se dispone de 3 tipos de redes preconfiguradas para poder ser usadas:
-
- Bridge: red standard que usar谩n todos los contenedores.
-
- Host: el contenedor usar谩 la misma IP del Host.
-
- None: se utiliza para indicar que un contenedor no tiene asignada una red.
-
Para listar las redes que ya se tienen creadas:
docker network ls
- Para inspeccionar una red:
docker network inspect [Nombre_red]
- Para crear una red nueva:
docker network create [Nombre_red]
Si no se indica el tipo de red, por defecto sera bridge
- Para crear una red especifica:
docker network create --driver bridge [Nombre_red]
- Asignamos la red creada a un contenedor:
docker run -d -P --name [Nombre_contenedor] --network [Nombre_red] [ID_IMAGEN o NOMBRE_IMAGEN]
- EJ:
docker run -d -P --name pruebanginx --network [Nombre_red] nginx
- Para eliminar una red:
docker network delete [Nombre_red]
En este apartado hablaremos sobre lo tipos de vol煤menes existentes en docker, hay 3 tipos de vol煤menes:
-
Volumen: es la manera sencilla y predefinida para almacenar todos los ficheros en un contenedor, usa el espacio de Host en /var/lib/docker/volumes y crea una carpeta para cada contenedor.
-
Para crear un volume:
docker volume create [NOMBRE_VOLUMEN]
- Para asignar el volume creado a un contenedor:
docker run -d -it --name [NOMBRE_CONTENEDOR] -v [NOMBRE_VOLUMEN]:[/RUTA/CONTENEDOR] [NOMBRE_IMAGEN]
- Volumen bind: es una manera de asociar una carpeta de nuestro Host y conectarla como una carpeta dentro de un contenedor. Este sistema nos permite ver esa carpeta desde el contenedor y tambi茅n desde nuestro Host. Usar esos ficheros, copiarlos y adem谩s en caso de tener una soluci贸n de almacenamiento distribuido, poder tener m煤ltiples copias.
- Ejemplo:
docker run -d -it --name [NOMBRE_CONTENEDOR] -v [/RUTA/F脥SICA]:[/RUTA/CONTENEDOR] [NOMBRE_IMAGEN]
-
TMPFS (temporal file system): es una manera de montar carpetas temporales en un contenedor. Usan la RAM del equipo y su contenido desaparecer谩 al parar el contenedor.
-
Ejemplo:
docker run -d -it --name [NOMBRE_CONTENEDOR] --tmpfs [/RUTA/TEMPORAL] [NOMBRE_IMAGEN]
- Copiar ficheros desde un contenedor al equipo f铆sico.
docker cp [ID_CONTAINER:RUTA_CONTENEDOR] [RUTA_HOST_FISICO]
- Copiar desde Host f铆sico hasta el contenedor.
docker cp [RUTA_HOST_FISICO] [ID_CONTAINER:RUTA_CONTENEDOR]
Un Dockerfile es un archivo de texto plano que contiene una serie de instrucciones necesarias para crear una imagen que, posteriormente, se convertir谩 en una sola aplicaci贸n utilizada para un determinado prop贸sito.
Es como la receta necesaria para un banquete, en este caso el Dockerfile es necesario para la imagen que queramos construir, el Dockerfile es la receta y el gran banquete ser谩 nuestra imagen.
# Descarga la imagen de Ubuntu 22.04
FROM ubuntu:22.04
# Mantenedor del contenedor
MAINTAINER Adri谩nHern谩ndezRios [email protected]
# Actualiza la imagen base de Ubuntu 14.04
RUN apt-get update
# Definir ambiente de entorno
ENV PRUEBAVAR valorholaEQUIPO
# Instalar Git
RUN apt-get -qqy install git
# Ejecuta el commando apt-get install y elimina determinados archivos y temporales
RUN apt-get install -y nginx \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Indica los puertos TCP/IP los cuales se pueden accede a los servicios del contenedor
EXPOSE 80
# Establece el commando del proceso de inicio del contenedor
CMD [鈥渘ginx鈥漖
Guarda todos los comandos y salidas mostradas de tu consola.
- Hacer correr un contenedor ubuntu.
- Acceder al contenedor.
- Crear un fichero en /tmp.
- Generar una imagen del contenedor mientras se encuentra corriendo. (docker commit [ID_CONTENEDOR])
- Asignar un nombre a la imagen creada. (docker tag [ID_IMAGEN] [NOMBRE:ETIQUETA])
- Probar que el fichero existe en esta nueva imagen.
a) Realizar una imagen mediante dockerfile. (Nombre del fichero Dockerfilelabs-[TUNOMBRE])
- Debe contener 4 variables definidas en el dockerfile (Las que quieras)
- Debe exponer el puerto 80 y 443
- Debe tener instalado git y curl.
b) Averiguar el comando para generar la imagen a partir de un fichero de dockerfile. [INVESTIGACI脫N]
docker build --file [Nombre_fichero] -t [NOMBRE_IMAGEN:ETIQUETA] .
c) Crear un contenedor con la imagen creada.
[Ejercicio de investigaci贸n]
herramienta para definir y ejecutar aplicaciones Docker multicontenedor que permite simplificar el uso de Docker a partir de archivos YAML, de est谩 forma es mas sencillo crear contenedores que se relacionen entre s铆, conectarlos, habilitar puertos, vol煤menes, etc. Nos permite lanzar un solo comando para crear e iniciar todos los servicios desde su configuraci贸n(YAML), esto significa que puedes crear diferentes contenedores y al mismo tiempo diferentes servicios en cada contenedor, integrarlos a un volumen com煤n e iniciarlos y/o apagarlos, etc. Este es un componente fundamental para poder construir aplicaciones y microservicios. Docker-Compose funciona en todos los entornos: production, staging, development, testing, as铆 como flujos de trabajo basados en Continuous Integration(CI).
[Investigaci贸n]
En la carpeta 2.Docker-compose/Soluciones/EJERCICIO1, tenemos el fichero docker-compose.yml quien orquestar谩 toda la creaci贸n de contenedores que necesitemos, para ello debemos ejecutar el comando:
docker-compose up -d
Lo que realizara docker-compose.yml es aqu铆 el tremendo potencial que tiene, y es la sintaxis build, pues mediante docker-compose podemos indicarle que lea un Dockerfile, caso contrario podemos usar image para que pueda usar la imagen descargada en nuestro Host. La sintaxis container_name asigna un nombre a nuestro contenedor, enviroment sirve para setear las variables de entorno, para nuestro caso, passwd, user para mariadb, la sintaxis volume asigno el mismo al contendor.
-
Para visualizar la web, vamos a ingresar via un browser, colocando la IP Publica.
-
Si al acceder a la Web, nos encontramos con un Forbiden ( 403 ), debemos entrar al contenedor y crear un index.html
docker exec -it ID_CONTAINER bash touch index.html /var/www/html/
Modificar nuestro docker-compose, en esta linea: sg1:/var/www/html:rw por el valor: sg1:/var/www/html:ro
Levantar de nuevo el compose.
docker-compose up -d
Ahora se va a copiar la carpeta que se encuentra en EJERCICIO2 llamada web en el contenedor, para ello vamos a usar el comando:
docker cp web/. web_apache:/var/www/html
驴A qu茅 se debe el mensaje de error?
Error response from daemon: mounted volume is marked read-only
Al declarar el volumen como RO (Red-Only), no se dispone de permisos de escritura en el contenedor.
- Copiar la data desde el HOST hacia el volumen creado.
- La segunda opci贸n es cambiar en el fichero de docker-compose los valores nuevamente y dejarlo con RW.
Ejecutamos el compose de nuevo:
docker-compose up -d docker cp web/. web_apache:/var/www/html
El resto de ejercicios es para poner en pr谩ctica todo lo aprendido y ver muchas opciones diferentes de configuraci贸n a nivel de docker-compose.
ESTE APARTADO ES OPCIONAL. ESTA DISE脩ADO PARA TODOS AQUELLOS QUE QUIERAN SEGUIR APRENDIENDO SOBRE DOCKER Y SU SOLUCI脫N DE CLUSTER.
Es una herramienta que permite a los desarrolladores implementar contenedores en modo swarm. Un cl煤ster Swarm consiste en Docker Engine implementado en m煤ltiples nodos. Los nodos de administraci贸n realizan la orquestaci贸n y la administraci贸n del cl煤ster. Los nodos de trabajo reciben y ejecutan tareas desde los nodos de administraci贸n.
Un servicio consiste en tareas que puedes ejecutarse en nodos de Swarm. Los servicios se pueden replicar para ejecutarse en multiples nodos. En el modelo de servicio replicados, el equilibrio de carga de ingreso y el DNS internos se pueden usar para proporcionar puntos finales de servicio altamente disponibles.
- Para la instalaci贸n de docker swarm, se va a emplear docker-machine con virtualbox
# creaci贸n maquinas de ejemplo con docker machine
docker-machine create -d virtualbox manager1
Running pre-create checks...
Creating machine...
(manager1) Copying /home/usuario/.docker/machine/cache/boot2docker.iso to /home/usuario/.docker/machine/machines/manager1/boot2docker.iso...
(manager1) Creating VirtualBox VM...
(manager1) Creating SSH key...
(manager1) Starting the VM...
(manager1) Check network to re-create if needed...
(manager1) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env manager1
# creaci贸n resto maquinas
docker-machine create -d virtualbox worker1
docker-machine create -d virtualbox worker2
# lista maquinas creadas
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
manager1 - virtualbox Running tcp://192.168.33.102:2376 v20.10.17
worker1 - virtualbox Running tcp://192.168.33.103:2376 v20.10.17
worker2 - virtualbox Running tcp://192.168.33.104:2376 v20.10.17
- Swarm con maquinas virtuales en ejecuci贸n
```shell
# acceder a maquina manager1 por ssh
docker-machine ssh manager1
docker@manager1:~$
# ejecuci贸n init swarm en maquina actual (ip 192.168.33.102)
docker@manager1:~$ docker swarm init --advertise-addr 192.168.33.102
Swarm initialized: current node (7tn2zpmalg5cye47kdloy26ns) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3tisudabghsdbkyhwbkqwiuyfqewinciqe35itnf3u55tb4ubf-56qp帽lo25a3ikr47yendlfypu 192.168.33.102:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
docker@manager1:~$ exit
logout
# agregar workers al swarm del manager previo
docker-machine ssh worker1
docker@worker1:~$
# agregar sentencia para agregarse al nodo de la maquina manager
docker@worker1:~$ docker swarm join --token SWMTKN-1-3tisudabghsdbkyhwbkqwiuyfqewinciqe35itnf3u55tb4ubf-56qp帽lo25a3ikr47yendlfypu 192.168.33.102:2377
This node joined a swarm as a worker.
docker@worker1:~$ exit
logout
docker-machine ssh worker2
docker@worker2:~$
# agregar sentencia para agregarse al nodo de la maquina manager
docker@worker2:~$ docker swarm join --token SWMTKN-1-3tisudabghsdbkyhwbkqwiuyfqewinciqe35itnf3u55tb4ubf-56qp帽lo25a3ikr47yendlfypu 192.168.33.102:2377
This node joined a swarm as a worker.
docker@worker2:~$ exit
logout
- Gestion Swarm desde el manager
# acceder a maquina manager1 por ssh
docker-machine ssh manager1
# ver nodos
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
7tn2zpmalg5cye47kdloy26ns * manager1 Ready Active Leader 20.10.17
gyg6ros9ft2jqpkizlwscv583 worker1 Ready Active 20.10.17
i38hw0fjukjnvdlvdt8hpsith worker2 Ready Active 20.10.17
version: '3.2'
services:
wso2eiana-worker:
image: docker.wso2.com/wso2ei-analytics-worker:6.6.0.107
deploy:
placement:
constraints: [node.hostname == PEPELIDESWSO2EI01]
replicas: 1
resources:
limits:
cpus: '0.7'
memory: 1024M
reservations:
cpus: '0.2'
memory: 512M
hostname: worker
ports:
- 9091:9091
- 9444:9444
- 7612:7612
- 7712:7712
- 7070:7070
- 7443:7443
volumes:
# mounting configurations
- /opt/wso2_ei_6.6/docker-compose/integrator-analytics-DES/worker:/home/wso2carbon/wso2-config-volume
- /var/log/wso2ei/worker:/home/wso2carbon/wso2ei-6.6.0/wso2/analytics/wso2/worker/logs
- /opt/wso2_ei_6.6/certificados/DES:/home/wso2carbon/wso2ei-6.6.0/wso2/analytics/resources/security
env_file:
- ../vars/varsDES.env
environment:
- TZ=Europe/Madrid
secrets:
- PASSBD_EI_ANALYTICS
wso2eiana-dashboard:
image: docker.wso2.com/wso2ei-analytics-dashboard:6.6.0.107
deploy:
placement:
constraints: [node.hostname == PEPELIDESWSO2EI01]
replicas: 1
resources:
limits:
cpus: '0.7'
memory: 1024M
reservations:
cpus: '0.2'
memory: 512M
hostname: dashboard
ports:
- 9643:9643
- 9611:9611
- 9711:9711
env_file:
- ../vars/varsDES.env
environment:
- TZ=Europe/Madrid
volumes:
- /opt/wso2_ei_6.6/docker-compose/integrator-analytics-DES/dashboard:/home/wso2carbon/wso2-config-volume
- /var/log/wso2ei/dashboard:/home/wso2carbon/wso2ei-6.6.0/wso2/analytics/wso2/dashboard/logs
- /opt/wso2_ei_6.6/certificados/DES:/home/wso2carbon/wso2ei-6.6.0/wso2/analytics/resources/security
secrets:
- PASSBD_EI_ANALYTICS
- PASSBD_ANALYTICS_DASHBOARD
- PASSBD_ANALYTICS_PERMISSIONS
- PASS_EI
wso2ei-nodo01:
image: docker.wso2.com/wso2ei-integrator:6.6.0.107
deploy:
placement:
constraints: [node.hostname == PEPELISWSO2EI01]
replicas: 1
resources:
limits:
cpus: '1.6'
memory: 4096M
reservations:
cpus: '0.5'
memory: 1024M
hostname: nodo01
command:
- chmod 777 /home/wso2carbon/docker-entrypoint.sh; chmod +x /home/wso2carbon/docker-entrypoint.sh; chown wso2carbon:wso2carbon /home/wso2carbon/docker-entrypoint.sh
ports:
- target: 9443
published: 9443
protocol: tcp
mode: host
- target: 8243
published: 8243
protocol: tcp
mode: host
- target: 8280
published: 8280
protocol: tcp
mode: host
- target: 4100
published: 4100
protocol: tcp
mode: host
volumes:
# mounting configurations
- /opt/wso2_ei_6.6/docker-compose/integrator-analytics-DES/integrator01:/home/wso2carbon/wso2-config-volume/
- /opt/nfs/wso2/nfs-server:/home/wso2carbon/nfs-server/
- /opt/wso2_ei_6.6/datos_del_nfs_compartido/docker-entrypoint/docker-entrypoint.sh:/home/wso2carbon/docker-entrypoint.sh
- /var/log/wso2ei:/home/wso2carbon/wso2ei-6.6.0/repository/logs
#- /opt/wso2_ei6.6-analytics/certificados/DES:/home/wso2carbon/wso2ei-6.6.0/repository/resources/security
- /opt/wso2_ei_6.6/certificados/DES:/home/wso2carbon/wso2ei-6.6.0/repository/resources/security
env_file:
- ../vars/varsDES.env
environment:
- TZ=Europe/Madrid
depends_on:
- wso2eiana-worker
- wso2eiana-dashboard
secrets:
- PASS_CarbonDB_01
- PASS_CarbonDB_02
- PASS_WSO2RegistryDB
- PASS_WSO2UMDB
- PASS_EI
- PASS_ANALYTICS
secrets:
PASS_CarbonDB_01:
external: true
PASS_CarbonDB_02:
external: true
PASS_WSO2UMDB:
external: true
PASS_WSO2RegistryDB:
external: true
PASS_EI:
external: true
PASSBD_EI_ANALYTICS:
external: true
PASS_ANALYTICS:
external: true
PASSBD_ANALYTICS_DASHBOARD:
external: true
PASSBD_ANALYTICS_PERMISSIONS:
external: true
Vamos a desplegar una aplicaci贸n b谩sico, usar Nginx como imagen base y vamos a iniciarlo con 3 replicas:
docker service create --name webnginx --replicas 3 nginx
Donde:
- name: Nombre para el contenedor.
- replicas: Cantidad de replicas que se desea disponer.
- nginx: Nombre de la imagen.
Para listar los servicios creados usamos:
docker service ls
Para saber la cantidad de r茅plicas y donde est谩n distribuidas:
docker service ps [ID_CONTENEDOR]
Desde el nodo master, ejecutar:
docker inspect [ID_CONTENEDOR] | grep IPA
curl [IP_CONTENEDOR]
Como podemos observar, tenemos Nginx en funcionamiento, pero no es muy accesible que digamos, porque solo "vive" en la red de Docker.
Vamos ahora modificar esa limitante, para ello recurrimos al siguiente comando:
docker service update --publish-add 9090:80 webnginx
donde:
- update: Comando a usar para modificar un servicio.
- publish-add: Puertos Host/Contenedor
Acceder a un navegador para acceder al sitio web por el puerto 9090.
La acci贸n de publicar una entrada de acceso "externa" hacia el contenedor, se conoce como routing mesh
docker service create --name my-web --publish 8080:80 --replicas 2 nginx [驴Qu茅 hace esta ejecuci贸n?]
Ahora a ver el update de im谩genes, supongamos que se dispone de la aplicaci贸n Grafana con la version 5.0 y se desea desplegar en nuestro Cluster:
docker service create --replicas 3 --name monitor --update-delay 20s grafana/grafana:5.0.0
donde: 鈥搑eplicas: Es el n煤mero de tareas (task) 鈥搉ame: Es el nombre del servicio. 鈥搖pdate-delay: Es el tiempo que transcurre entre la actualizaci贸n de cada una de las tareas. -grafana/grafana:5.0.0: Es la imagen que se va a emplear.
docker service ls && docker service ps $ID