From c11d57ff10ca014c3afab67ab27c2b90300fc038 Mon Sep 17 00:00:00 2001 From: Jaime Salas Date: Sun, 15 Mar 2026 21:24:50 +0100 Subject: [PATCH 1/3] ejercicios contenedores y K8s --- 01-contenedores/ejercicios/readme.md | 71 +++++++++++++++++++++++++ 02-kubernetes/ejercicios/readme.md | 77 ++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 01-contenedores/ejercicios/readme.md create mode 100644 02-kubernetes/ejercicios/readme.md diff --git a/01-contenedores/ejercicios/readme.md b/01-contenedores/ejercicios/readme.md new file mode 100644 index 0000000..23e552d --- /dev/null +++ b/01-contenedores/ejercicios/readme.md @@ -0,0 +1,71 @@ +# Ejercicios + +## 1. Creando imágenes + +- Ejecuta un contenedor de `ubuntu`, instala `curl` dentro del mismo. +- ¿Con qué comando podrías preservar el cambio? +- Crea un `Dockerfile` que haga lo mismo. Ejecuta la nueva imagen y verifica que puedes usar `curl` +- ¿Cómo podrías ver las distaintas capas del contenedor? + +Para instalar `curl` en `ubuntu` puedes usar: + +```bash +apt-get install curl +``` + +## 2. Limpiando imágenes + +Construye tres imágenes distintas: + +1. Parte de la imagen base de `alpine` o `ubuntu`. Crea un `Dockerfile` y construye la imagen. +2. En una nueva iteración, instala `curl` y construye la imagen. +3. En la siguiente iteración, instala `wget` y construye la imagen. + +- Inspecciona tus imágenes locales ¿Qué ocurre? +- ¿Cómo podemos limpiar el sistema? + +## 3. Volumenes persistentes + +Ejecuta un contenedor de `postgres` con un volumen manejado por Docker y que monte en `/var/lib/postgresql/data`. Conectate a la base de datos y crea una tabla `items`, que tenga doos campos `id` y `name`, siendo `id` primary key. Inserta un registro en la tabla items. + +- Para y elimina el contenedor que has creado. +- Vuelve a ejecutar un nuevo contenedor de `postgres` montando el volumen anterior, en el mismo *path*. Verifica que los datos persisten. + +## 4. Bind mounts + +Crea un fichero `index.html` en tu máquina local. Ejecuta un contenedor de `nginx` mapeando el puerto 80 a un puerto en tu local, y enlace tu fichero `index.html` local con `/usr/share/nginx/html/index.html`. + +- ¿Qué ocurre si editas el fichero local `index.html`? + +## 5. Auditando volumenes + +- ¿Qué comando deberías usar para averiguar dónde alamacena Docker los datos de un volumen dado? +- Si estás usando Docker Desktop en Windows o macOS que diferencia habría con un Linux en el contexto de dónde están alamacenados los datos. + +## 6. Creando redes privadas + +- Crea una red tipo `bridge` llamada `my-net`. Eejcuta dos conetenedores de tipo `ubuntu`, asegura que `ping` está disponible, ambos deben correr en la red `my-net`. +- Comprueba que puedes usar `ping` en ambos y se alcazan entre si. + +## 7. Red `none` + +- ¿Cuáles serían los casos de uso de la red `none`? + +## 8. Multi-network + +Crea dos redes de tipo bridge `secure-zone` y `public-zone`. Arranca un contenedor en `public-zone`. + +- ¿Puedes añadir tu contenedor a `secure-zone`? ¿Qué comado deberías utilizar? +- ¿Cómo puedes verificar en que red se encuentra un contenedor? + +## 9. Docker Compose - Compartiendo Volumenes + +- Crea un manifiesto para Docker Compose con dos servicios que comparten un mismo volumen. +- Nombra al primer servicio como `writer`, este debe montar el volumen en `/app/logs` y añadir un `timestamp` a un fichero cada 30 segundos. +- Nombra al sergundo servicion como `reader`, debe montar el volumen como solo para lectura, y redireccionar su conetnido a `stdout`. + +## 10. Docker Compose - Profiles + +- Crea un manifiesto para docker compose con `postgres` y `pgadmin` +- `Pgadmin` debe conectar con `Postgres`. Crea los mecanismo adecuados para aegurar que la comunicación entre ambos servicios es posible. +- Crea dos perfiles, uno para levantar ambos servicios y otro para levanatr sólo `Postgres` \ No newline at end of file diff --git a/02-kubernetes/ejercicios/readme.md b/02-kubernetes/ejercicios/readme.md new file mode 100644 index 0000000..b6c3fe1 --- /dev/null +++ b/02-kubernetes/ejercicios/readme.md @@ -0,0 +1,77 @@ +# Ejercicios + +## 1. Naked Pod + +- Levanta un Pod desde consola, su imagen debe ser `nginx:alpine`. +- Verfica que el Pod se está ejecutando +- Borra el Pod. + +## 2. Self-Healing Deployment + +- Crea un Deployment con 3 replicas desde consola cuya imagen sea `httpd:alpine`. +- Verifica que las 3 replicas están corriendo. +- Elimina una de la réplicas. ¿Qué ocurre pasado un tiempo? +- ¿Qué comando deberías usar para ver cómo aparacen las replicas en tiempo real? + +## 3. Zero-downtime Rollouts + +- Crea un Deployment usando la imagen `nginx:1.19`. +- Actualiza la imagen a `nginx:1.21` ¿Qué opciones tienes para actualizar la imagen sin eliminar el Depolyment? +- ¿Qué comando puedes usar para verificar el estado del *rollout*? + +## 4. PVC + +- Crea un `PersistentVolumClaim` solicitando 1Gi de alamacenamiento. +- Monta el PVC en un POd y crea un fichero en el path `/temp`. +- Elmina el Pod, crea un nuevo que monte el PVC anterior, verifica que el fichero sigue existiendo. + +## 5. StorageClass + +- Verifica si en tu cluster existe una `StorageClass default`. +- Crea un volumen a través de la `StorageClass default`. +- Verifica que el volumen se ha creado. + +## 6. Networking - ClusterIP + +- Crea un Deployment con la imagen `nginx`, expón el Deployment a través de un servicio ClusterIP. +- Verifica que eres capaz de interactuar con `nginx` a través del servicio que has creado. Para ello usa una imagen `busybox`. +- Si el Pod de `busybox` se hallará en otro `namespace` que FQN deberíamos usar. +- ¿Cómo podemos aislar `namespaces` completamente en K8s? + +## 7. Networking - NodePort + +- Convierte el servicio anterior a NodePort. +- Verifica `nginx` sigue siendo accesible. + +## 8. Networking - Ingress Controller + +Crea dos Deployments en `yaml` y exponlo a través de un servicio, también en `yaml`. Usa la imagen `hashicorp/http-echo`. Esta imagen permite pasar como argumento un 'echo'. Aquí tienes un ejemplo, usando un Pod: + +```yml +kind: Pod +apiVersion: v1 +metadata: + name: apple-app + labels: + app: apple +spec: + containers: + - name: apple-app + image: hashicorp/http-echo + args: + - "-text=apple" +``` + +- El primer Deployment dará como echo la palabra *red* +- El segundo Deployment dará como echo la palabra *yellow* +- Crea un Ingress que exponga el primer Deployment en `example.com/red`, y el segundo en `example.com/yellow`. +- Comprueba que funciona usando `curl -H "Host: example.com" ...` +- Refactoriza el Ingress para que existan un Virtual Host por cada uno de los Deloyments. + +## 9. Networking - Gateway API + +Si quisieramos utilizar la [Gateway API](https://gateway-api.sigs.k8s.io/) en vez del Ingress del ejercicio anetrior, ¿qué consideraciones deberíamos tomar? + +## 10. Canary Deployment + +- Explica que es un Canary Deployment y los pasos para ejecutarlo en K8s. \ No newline at end of file From ea0d27fdbb287da57b6ea0313cc53549c1d1e2b7 Mon Sep 17 00:00:00 2001 From: Antonio Contreras Date: Thu, 26 Mar 2026 11:36:26 +0100 Subject: [PATCH 2/3] Fix typos in README for clarity and consistency --- 01-contenedores/ejercicios/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/01-contenedores/ejercicios/readme.md b/01-contenedores/ejercicios/readme.md index 23e552d..a30bb8a 100644 --- a/01-contenedores/ejercicios/readme.md +++ b/01-contenedores/ejercicios/readme.md @@ -5,7 +5,7 @@ - Ejecuta un contenedor de `ubuntu`, instala `curl` dentro del mismo. - ¿Con qué comando podrías preservar el cambio? - Crea un `Dockerfile` que haga lo mismo. Ejecuta la nueva imagen y verifica que puedes usar `curl` -- ¿Cómo podrías ver las distaintas capas del contenedor? +- ¿Cómo podrías ver las distintas capas del contenedor? Para instalar `curl` en `ubuntu` puedes usar: @@ -68,4 +68,4 @@ Crea dos redes de tipo bridge `secure-zone` y `public-zone`. Arranca un contened - Crea un manifiesto para docker compose con `postgres` y `pgadmin` - `Pgadmin` debe conectar con `Postgres`. Crea los mecanismo adecuados para aegurar que la comunicación entre ambos servicios es posible. -- Crea dos perfiles, uno para levantar ambos servicios y otro para levanatr sólo `Postgres` \ No newline at end of file +- Crea dos perfiles, uno para levantar ambos servicios y otro para levanatr sólo `Postgres` From 8b8998cc40cf86316d78cccc1d09884e05b63e4c Mon Sep 17 00:00:00 2001 From: Antonio Contreras Date: Thu, 26 Mar 2026 11:50:39 +0100 Subject: [PATCH 3/3] Refactor README to enhance structure and clarity for Docker lab exercises --- 01-contenedores/ejercicios/readme.md | 399 ++++++++++++++++++++++++--- 1 file changed, 358 insertions(+), 41 deletions(-) diff --git a/01-contenedores/ejercicios/readme.md b/01-contenedores/ejercicios/readme.md index a30bb8a..9cf7a42 100644 --- a/01-contenedores/ejercicios/readme.md +++ b/01-contenedores/ejercicios/readme.md @@ -1,71 +1,388 @@ -# Ejercicios +# Laboratorio Docker -## 1. Creando imágenes +Este laboratorio tiene como objetivo practicar los conceptos básicos de +Docker: -- Ejecuta un contenedor de `ubuntu`, instala `curl` dentro del mismo. -- ¿Con qué comando podrías preservar el cambio? -- Crea un `Dockerfile` que haga lo mismo. Ejecuta la nueva imagen y verifica que puedes usar `curl` -- ¿Cómo podrías ver las distintas capas del contenedor? +- Imágenes +- Contenedores +- Capas +- Volúmenes +- Redes +- Docker Compose -Para instalar `curl` en `ubuntu` puedes usar: +--- + +# Entrega del laboratorio + +Este laboratorio debe entregarse mediante un **repositorio público en +GitHub**. + +El repositorio debe contener un fichero: + + README.md + +En este fichero deberás documentar: + +- Los pasos que has realizado +- Los comandos utilizados +- Una breve explicación de cada paso +- Las respuestas a las preguntas del laboratorio + +El objetivo es que cualquier persona pueda **seguir tu documentación y +reproducir el laboratorio**. + +Ejemplo de entrega: + + https://github.com/usuario/docker-lab + +--- + +# Criterios de evaluación + +El laboratorio se divide en: + +- **Parte obligatoria (necesaria para aprobar)** +- **Parte opcional (para subir nota)** + +--- + +## Parte obligatoria (mínimo para aprobar) + +Debes completar correctamente los siguientes ejercicios: + +- Ejercicio 1 --- Creando imágenes +- Ejercicio 3 --- Volúmenes persistentes +- Ejercicio 4 --- Bind mounts +- Ejercicio 6 --- Redes privadas +- Ejercicio 9 --- Docker Compose + +Si estos ejercicios **no funcionan o no están documentados**, el +laboratorio **no se considerará aprobado**. + +--- + +## Parte opcional (para subir nota) + +Estos ejercicios son **muy sencillos** y sirven para mejorar la nota. + +Puedes hacer uno o varios. + +- Ejercicio 2 --- Limpieza de imágenes +- Ejercicio 5 --- Ver información de un volumen +- Ejercicio 7 --- Investigar la red `none` +- Ejercicio 8 --- Conectar un contenedor a dos redes + +También puedes hacer una pequeña mejora en Docker Compose. + +### Bonus sencillo + +Añade un servicio `nginx` a tu `docker-compose.yml`. + +Debe: + +- usar la imagen `nginx` +- exponer el puerto `8080` +- mostrar una página simple + +Ejemplo `index.html`: + +```html +

Laboratorio Docker funcionando

+``` + +Si al abrir: + + http://localhost:8080 + +aparece la página, el bonus estará completado. + +--- + +# 1. Creando imágenes + +## Paso 1 + +Ejecuta un contenedor basado en la imagen: + + ubuntu + +Accede a la terminal del contenedor. + +Instala `curl`: ```bash +apt-get update apt-get install curl ``` -## 2. Limpiando imágenes +Comprueba que funciona: + +```bash +curl --version +``` + +--- + +## Pregunta + +¿Con qué comando podrías **guardar los cambios del contenedor como una +nueva imagen**? + +--- + +## Paso 2 --- Dockerfile + +Crea un `Dockerfile` que haga lo mismo automáticamente. + +Ejemplo: + +```dockerfile +FROM ubuntu + +RUN apt-get update && apt-get install -y curl +``` + +Construye la imagen y ejecuta un contenedor. + +Comprueba que `curl` está instalado. + +--- + +## Pregunta + +¿Qué comando permite ver las **capas de una imagen Docker**? + +--- + +# 2. Limpiando imágenes (opcional) + +Crea un `Dockerfile` basado en: + + ubuntu + +Construye la imagen. + +Después modifica el Dockerfile para instalar: + +- `curl` +- después `wget` + +Construye la imagen en cada cambio. + +Lista las imágenes: + +```bash +docker images +``` + +Pregunta: + +¿Qué ocurre con las imágenes anteriores? + +--- + +# 3. Volúmenes persistentes + +Ejecuta un contenedor de: + + postgres + +Usa un volumen Docker montado en: + + /var/lib/postgresql/data + +--- + +## Crear tabla + +Conéctate a la base de datos. + +Crea la tabla: + +```sql +CREATE TABLE items ( + id SERIAL PRIMARY KEY, + name TEXT +); +``` + +Inserta un registro: + +```sql +INSERT INTO items(name) VALUES ('item1'); +``` + +--- + +## Comprobación + +1. Para el contenedor +2. Elimina el contenedor +3. Crea un nuevo contenedor usando **el mismo volumen** + +Comprueba que los datos siguen existiendo. + +--- + +# 4. Bind mounts + +Crea un archivo en tu máquina: + + index.html + +Ejemplo: + +```html +

Hola Docker

+``` + +--- + +Ejecuta un contenedor `nginx`: + +- mapea el puerto `80` +- monta el archivo en: + +```{=html} + +``` + + /usr/share/nginx/html/index.html + +Abre el navegador. + +--- + +Pregunta: + +¿Qué ocurre si modificas el archivo `index.html` en tu máquina? + +--- + +# 5. Auditando volúmenes (opcional) + +Investiga: + +¿Qué comando permite ver **dónde guarda Docker los datos de un +volumen**? + +--- + +# 6. Creando redes privadas + +Crea una red llamada: + + my-net + +--- + +Arranca dos contenedores `ubuntu` en esa red. + +Instala `ping` si es necesario. + +Desde un contenedor intenta hacer: + +```bash +ping otro_contenedor +``` + +--- + +Pregunta + +¿Los contenedores pueden comunicarse entre sí? + +--- + +# 7. Red none (opcional) + +Investiga: + +¿Para qué serviría ejecutar un contenedor con red: + + none + +--- + +# 8. Multi-network (opcional) + +Crea dos redes: + + secure-zone + public-zone + +Arranca un contenedor en `public-zone`. + +Pregunta: + +¿Puedes conectarlo también a `secure-zone`? + +¿Qué comando usarías? + +--- + +# 9. Docker Compose --- Compartiendo volúmenes + +Crea un fichero: + + docker-compose.yml + +Con dos servicios. + +--- + +## writer + +Debe: + +- montar un volumen en `/app/logs` +- escribir un timestamp cada 30 segundos -Construye tres imágenes distintas: +--- -1. Parte de la imagen base de `alpine` o `ubuntu`. Crea un `Dockerfile` y construye la imagen. -2. En una nueva iteración, instala `curl` y construye la imagen. -3. En la siguiente iteración, instala `wget` y construye la imagen. +## reader -- Inspecciona tus imágenes locales ¿Qué ocurre? -- ¿Cómo podemos limpiar el sistema? +Debe: -## 3. Volumenes persistentes +- montar el volumen en modo solo lectura +- mostrar el contenido en consola -Ejecuta un contenedor de `postgres` con un volumen manejado por Docker y que monte en `/var/lib/postgresql/data`. Conectate a la base de datos y crea una tabla `items`, que tenga doos campos `id` y `name`, siendo `id` primary key. Inserta un registro en la tabla items. +--- -- Para y elimina el contenedor que has creado. -- Vuelve a ejecutar un nuevo contenedor de `postgres` montando el volumen anterior, en el mismo *path*. Verifica que los datos persisten. +# 10. Docker Compose Profiles (opcional) -## 4. Bind mounts +Crea un `docker-compose.yml` con: -Crea un fichero `index.html` en tu máquina local. Ejecuta un contenedor de `nginx` mapeando el puerto 80 a un puerto en tu local, y enlace tu fichero `index.html` local con `/usr/share/nginx/html/index.html`. +- `postgres` +- `pgadmin` -- ¿Qué ocurre si editas el fichero local `index.html`? +Haz que `pgadmin` pueda conectarse a `postgres`. -## 5. Auditando volumenes +--- -- ¿Qué comando deberías usar para averiguar dónde alamacena Docker los datos de un volumen dado? -- Si estás usando Docker Desktop en Windows o macOS que diferencia habría con un Linux en el contexto de dónde están alamacenados los datos. +Crea dos perfiles: -## 6. Creando redes privadas +### Perfil completo -- Crea una red tipo `bridge` llamada `my-net`. Eejcuta dos conetenedores de tipo `ubuntu`, asegura que `ping` está disponible, ambos deben correr en la red `my-net`. -- Comprueba que puedes usar `ping` en ambos y se alcazan entre si. +Levanta: -## 7. Red `none` +- postgres +- pgadmin -- ¿Cuáles serían los casos de uso de la red `none`? +### Perfil base -## 8. Multi-network +Levanta solo: -Crea dos redes de tipo bridge `secure-zone` y `public-zone`. Arranca un contenedor en `public-zone`. +- postgres -- ¿Puedes añadir tu contenedor a `secure-zone`? ¿Qué comado deberías utilizar? -- ¿Cómo puedes verificar en que red se encuentra un contenedor? +--- -## 9. Docker Compose - Compartiendo Volumenes +# Resumen evaluación -- Crea un manifiesto para Docker Compose con dos servicios que comparten un mismo volumen. -- Nombra al primer servicio como `writer`, este debe montar el volumen en `/app/logs` y añadir un `timestamp` a un fichero cada 30 segundos. -- Nombra al sergundo servicion como `reader`, debe montar el volumen como solo para lectura, y redireccionar su conetnido a `stdout`. +Nivel Requisitos -## 10. Docker Compose - Profiles +--- -- Crea un manifiesto para docker compose con `postgres` y `pgadmin` -- `Pgadmin` debe conectar con `Postgres`. Crea los mecanismo adecuados para aegurar que la comunicación entre ambos servicios es posible. -- Crea dos perfiles, uno para levantar ambos servicios y otro para levanatr sólo `Postgres` +Aprobado Parte obligatoria completa +Notable Parte obligatoria + ejercicios opcionales +Sobresaliente Parte obligatoria + opcionales + bonus