diff --git a/01-contenedores/ejercicios/readme.md b/01-contenedores/ejercicios/readme.md new file mode 100644 index 0000000..9cf7a42 --- /dev/null +++ b/01-contenedores/ejercicios/readme.md @@ -0,0 +1,388 @@ +# Laboratorio Docker + +Este laboratorio tiene como objetivo practicar los conceptos básicos de +Docker: + +- Imágenes +- Contenedores +- Capas +- Volúmenes +- Redes +- Docker Compose + +--- + +# 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 +``` + +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 + +--- + +## reader + +Debe: + +- montar el volumen en modo solo lectura +- mostrar el contenido en consola + +--- + +# 10. Docker Compose Profiles (opcional) + +Crea un `docker-compose.yml` con: + +- `postgres` +- `pgadmin` + +Haz que `pgadmin` pueda conectarse a `postgres`. + +--- + +Crea dos perfiles: + +### Perfil completo + +Levanta: + +- postgres +- pgadmin + +### Perfil base + +Levanta solo: + +- postgres + +--- + +# Resumen evaluación + +Nivel Requisitos + +--- + +Aprobado Parte obligatoria completa +Notable Parte obligatoria + ejercicios opcionales +Sobresaliente Parte obligatoria + opcionales + bonus 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