El laboratorio¶
Todo el módulo se hace sobre un laboratorio que se construye durante las primeras unidades y que después se reutiliza hasta el final. Esta página describe cómo queda cuando está completo, qué necesita cada puesto y cómo recuperarlo si algo se rompe.
Cómo queda al final del módulo¶
flowchart TB
subgraph host["Equipo del aula o portátil"]
subgraph pve["Proxmox VE en VM anidada"]
subgraph mgmt["Subred de gestión 10.10.0.0/24"]
fw["<b>OPNsense</b><br><small>.1 · el cortafuegos</small>"]:::act
adm["<b>admin01</b><br><small>.50 · puesto de administración</small>"]:::act
jenkins["<b>jenkins01 y agent01</b><br><small>.10 y .12</small>"]:::dato
mon["<b>mon01</b><br><small>.20 · monitorización y MinIO</small>"]:::dato
git["<b>gitea01</b><br><small>.11 · Gitea y registry</small>"]:::dato
end
subgraph front["front · DMZ externa 10.10.1.0/24"]
web["<b>web01</b><br><small>nginx</small>"]:::pieza
end
subgraph back["back · DMZ interna 10.10.2.0/24"]
app["<b>app01</b><br><small>API en Docker</small>"]:::pieza
end
subgraph data["data · zona interna 10.10.3.0/24"]
db["<b>db01</b><br><small>PostgreSQL</small>"]:::pieza
end
end
end
Internet(("<b>Aula / Internet</b>")):::infra -->|443| fw
Internet -->|SSH| adm
fw --> web
web -->|28080| app
app -->|5432| db
jenkins -.->|publica la imagen| git
mon -.->|scrape| app & db & jenkins
classDef act fill:#ea580c22,stroke:#ea580c,stroke-width:1.5px
classDef pieza fill:#64748b22,stroke:#64748b,stroke-width:1.5px
classDef dato fill:#2563eb22,stroke:#2563eb,stroke-width:1.5px
classDef infra fill:#a1a1aa14,stroke:#a1a1aa,stroke-width:1.5px
classDef ok fill:#16a34a22,stroke:#16a34a,stroke-width:1.5px
classDef riesgo fill:#dc262622,stroke:#dc2626,stroke-width:1.5px
El laboratorio completo al terminar el módulo. En naranja por dónde se entra desde fuera: el servicio, por el cortafuegos, y la administración, por admin01. En azul lo que vigila, construye y guarda las imágenes.
Ese es el entorno dev, el único que llega al final. pre tiene la misma estructura en 10.20.0.0/16 y vive del 8 de enero al 11 de marzo (su ficha está en El entorno pre); pro solo existe como red, en 10.30.0.0/16, para las pruebas de aislamiento de la UT2.
Las dos asignaturas comparten este laboratorio¶
La asignatura hermana, Mantenimiento del sistema de contenedores, vigila, prueba, actualiza y retira el mismo servicio, y empieza a hacerlo el 1 de octubre, cuando aquí todavía se está instalando Proxmox. Sus tres primeras sesiones trabajan con Docker en el puesto del alumno, porque el hipervisor se está montando todavía y la plantilla de la que salen las VM no existe hasta el 14 de octubre. Para que eso cuadre, en la sesión 3 (14 de octubre), nada más tener la plantilla cloud-init, junto a web01 se clonan dos VM pensadas para la otra asignatura: app01, que aloja el servicio del curso en Docker Compose, y mon01, que aloja la pila de monitorización. Las dos van en vmbr0, la red del aula, con IP por DHCP y sin subredes ni cortafuegos, y se entregan con Docker Engine y el plugin compose instalados, con el usuario ops en el grupo docker y con la clave pública del puesto del alumno dentro, porque Mantenimiento entra en ellas desde su puesto al día siguiente. Los ficheros compose que corren encima los entrega la otra asignatura y se despliegan allí a partir de su sesión 4 (15 de octubre).
El 27 de noviembre, en la A3.3, esta asignatura traslada las dos VM a su sitio definitivo, ya detrás del cortafuegos: app01 a la subred back con la 10.10.2.10 y mon01 a la de gestión con la 10.10.0.20. Mantenimiento audita su pila el 26 de noviembre, con las VM todavía en el aula, y la protege desde el 1 de diciembre, ya en la VPC. En marzo, la UT7 de monitorización no levanta una segunda pila: trabaja sobre la de /opt/monitoring de mon01 y en el mismo repositorio monitoring, y solo le añade ficheros propios que Mantenimiento no toca (los targets que genera Ansible, sus reglas, el job de Jenkins y el panel de la plataforma). PromQL, las reglas, Alertmanager, Grafana y los indicadores se repasan en pocos minutos, porque la otra asignatura ya los ha dado a fondo.
Requisitos por puesto¶
Proxmox va dentro de una máquina virtual de VirtualBox o VMware Workstation en el equipo del aula (virtualización anidada). No es lo ideal en rendimiento, pero permite que cada uno tenga su hipervisor completo y lo pueda romper sin afectar a nadie.
| Recurso | Mínimo | Recomendado |
|---|---|---|
| CPU del equipo | 4 núcleos con VT-x/AMD-V | 8 núcleos |
| RAM del equipo | 16 GB | 32 GB |
| Disco libre | 80 GB en SSD | 150 GB en SSD |
| VM de Proxmox | 4 vCPU, 12 GB RAM, 60 GB | 6 vCPU, 16 GB RAM, 100 GB |
Disco. Además de los clones de la plantilla (20 GB cada uno, de los que se ocupan unos 3 al principio), hay dos discos que se añaden a mano durante el curso: el segundo disco de db01 para /data, de 5 GB, el 27 de noviembre, y el volumen minio_data de la pila de mon01, que crece con el estado de OpenTofu (unos pocos MB) y con las copias restic de pre (entre 1 y 3 GB desde febrero).
Con un miniPC o un portátil antiguo de 16 GB disponible, instalar Proxmox directamente sobre él (tipo 1 de verdad) es mucho mejor que la VM anidada. Es la opción preferible siempre que sea posible.
Presupuesto de memoria¶
Lo que se busca es que la VM de Proxmox no se quede sin memoria en ninguna sesión. La cuenta se hace con la memoria asignada a cada VM, que es la de la columna «RAM al clonar» de la tabla de máquinas, más 2 GB para el propio Proxmox. La cifra de referencia para las dos asignaturas es 16 GB para la VM de Proxmox, es decir, 14 GB para las VM, y no se alcanza dejándolo todo encendido: en los tramos más cargados hay algo que se apaga.
Cuatro bloques se repiten en la cuenta:
- La base, encendida todo el curso desde el 27 de noviembre: OPNsense (1 GB),
admin01(1 GB), que es el salto para entrar en todo lo demás, ymon01(3 GB), con MinIO dentro. Son 5 GB. - El servicio en dev:
web01(1 GB),app01(2 GB) ydb01(2 GB). Son 5 GB. - pre, del 8 de enero al 11 de marzo: tres VM de 1 GB y
router-pre(512 MB). Son 3,5 GB. - La integración continua, desde febrero:
jenkins01(2 GB),agent01(2 GB) ygitea01(1 GB). Son 5 GB.
| Tramo | Encendido | Suma | Qué se apaga para no pasar de 14 GB |
|---|---|---|---|
| 14 oct a 3 nov | web01, app01 y mon01; db01 desde el 30 oct; las VM de prueba de la UT1 |
8 GB y las pruebas | Cada VM de prueba al terminar su hoja; en la evaluable de la UT1, todo menos app01, mon01 y app-eval |
| 4 a 19 nov | Lo anterior, router-dev, admin01, router-pre, router-pro y las dos web01 de prueba de la A2.5 |
11,5 GB | Nada; la A2.5 apaga db01 hasta la evaluable para caber también en 12 GB |
| 20 nov a 7 ene | La base, el servicio en dev y router-pre; cli-a y cli-b del 2 al 9 dic |
11,5 GB | Nada |
| 8 ene a 2 feb | La base, el servicio en dev y pre | 13,5 GB | Nada |
| 3 feb a 11 mar | La base, el servicio en dev, pre y la integración continua | 18,5 GB | En las sesiones de Despliegue, dev y pre salvo lo que use la hoja: la A6.8 (26 feb) enciende router-pre, web01-pre, app01-pre y db01-pre, porque test.sh comprueba las tres VM del servicio, y se queda en 13,5 GB. En las de Mantenimiento, jenkins01, agent01 y web01-pre, que no corre nada, y pre entera los días que la hoja no la usa; cuando la hoja necesita Jenkins (A7.6, A8.1, A8.2 y A8.3), se enciende y a cambio se apagan web01 y db01 de dev; la A8.1 y la A8.2 necesitan además router-pre, app01-pre y db01-pre encendidas |
| 12 a 24 mar | La base, el servicio en dev y la integración continua | 15 GB | web01 en las sesiones de la UT7, porque mon01 no la vigila; agent01 en las de Mantenimiento |
Con una VM de Proxmox de 12 GB (10 para las VM) el curso se sigue con la misma regla, más estricta: se enciende solo lo que usa la hoja del día y se apaga al terminar. Hasta enero basta con lo que ya dicen las hojas y con router-pre apagado hasta el 8 de enero; desde enero, cada sesión enciende el servicio en dev o pre, no los dos, y las de Despliegue de febrero y marzo apagan también mon01 salvo en la A6.4, que traslada Gitea desde ella. Con 8 GB se llega hasta la UT5 de Despliegue y la UT2 de Mantenimiento, pero no caben a la vez Jenkins con su agente y la pila de monitorización.
MinIO no añade ninguna línea a la cuenta: se monta el 18 de diciembre, en el primer paso de la A5.2, como un contenedor más de la pila de mon01, y ocupa unos 300 MB de los 3 GB que esa máquina ya tiene. Si el profesor lo monta para toda el aula, no ocupa nada en el puesto. app01 y mon01 las usa Mantenimiento a diario: si una sesión de Despliegue las apaga, se vuelven a encender al terminarla.
Convenciones¶
Esta es la tabla única del laboratorio y manda sobre cualquier otra cosa escrita en las unidades: si una hoja de práctica dice algo distinto, vale lo de aquí. La asignatura de Mantenimiento usa estas mismas convenciones y solo añade las suyas.
Zonas, VNets y direccionamiento¶
Cada entorno tiene cuatro VNets del SDN, una por zona, y cada VNet lleva una sola subred. Dos subredes dentro de la misma VNet comparten bridge, o sea el mismo dominio de capa 2, así que no se pueden separar con un cortafuegos; por eso hay una VNet por zona y no una sola con varias subredes dentro.
| Zona | VNet (dev) | Subred | Quién es el .1 |
Qué vive ahí |
|---|---|---|---|---|
| gestión | devmgmt |
10.10.0.0/24 | el router del entorno | jenkins01, agent01, gitea01 con el registry, mon01 con MinIO y el puesto de administración |
| front (DMZ externa) | devfront |
10.10.1.0/24 | el router del entorno | web01, el nginx que publica el servicio |
| back (DMZ interna) | devback |
10.10.2.0/24 | el router del entorno | app01, la API en Docker |
| data (zona interna) | devdata |
10.10.3.0/24 | el router del entorno | db01, PostgreSQL |
pre y pro son iguales cambiando el prefijo: premgmt, prefront, preback, predata sobre 10.20.0.0/16, y promgmt, profront, proback, prodata sobre 10.30.0.0/16, con el mismo tercer octeto por zona (0 gestión, 1 front, 2 back, 3 data). Los servicios de plataforma (Jenkins, Gitea, el registry, la monitorización, MinIO) no se duplican: viven en devmgmt. Desde gestión se llega a pre por una pata que router-pre tiene en devmgmt (El entorno pre dice cómo); a pro no se llega, porque pro no tiene más que sus redes.
El ID de una VNet admite como máximo 8 caracteres y solo alfanuméricos. Es un límite de Proxmox, no una manía del curso: nombres como vdev-front no se pueden crear. El ID de zona tiene el mismo límite; la zona del laboratorio se llama lab, es de tipo Simple y usa el IPAM pve.
El router del entorno tiene una pata en cada VNet y es el .1 de las cuatro subredes. En dev lo es la VM router-dev (100), con dnsmasq, desde la sesión 9, y OPNsense (109) desde la sesión 14, que ocupa su sitio con esas mismas direcciones; router-dev se apaga ese día y se destruye al cerrar la evaluable de la UT3. En pre y pro son router-pre (200) y router-pro (300). Orden de interfaces en los routers Debian: ens18 exterior (vmbr0), ens19 gestión, ens20 front, ens21 back y ens22 data, y en router-pre, desde la A5.3, ens23, su pata en devmgmt. Las de OPNsense están en la A3.1.
Quién reparte direcciones cambia una sola vez en todo el curso. En la sesión 8 las subredes del SDN se crean con gateway y con rango DHCP del SDN (dnsmasq por zona, unidad dnsmasq@lab), porque es lo que se explica ese día. En la sesión 9, al entrar router-dev, se quita el gateway y el rango DHCP de cada subred del SDN y el router pasa a hacer DHCP, DNS y NAT. Dos .1 distintos en la misma red no funcionan, así que ese paso no es opcional.
| Rango dentro de cada subred | Uso |
|---|---|
.1 |
router y cortafuegos del entorno; también es el DNS y el servidor DHCP |
.2 a .9 |
reservado para servicios de red; solo se usa uno, la 10.10.0.2 de gestión, que es la pata de router-pre desde la A5.3 (antes, durante la A3.1, la dirección provisional de OPNsense) |
.10 a .99 |
servidores fijos |
.100 a .199 |
rango DHCP |
.200 a .254 |
libre, para pruebas de un rato |
Una tarjeta que no existe y una red que no es del laboratorio
No hay patas de gestión en web01, app01 ni db01: cada uno tiene una sola tarjeta, la de su zona, y la monitorización llega hasta ellos atravesando el cortafuegos, con las filas 11 a 13 de la matriz de reglas. La 10.10.0.11 es gitea01 y la 10.10.0.12 es agent01, no segundas tarjetas de app01 y de db01.
La red 10.10.10.0/24 no es del laboratorio: es la del bridge vmbr1 del nodo, donde el host tiene la 10.10.10.1. En vmbr1 no vive ninguna VM de servicio: solo las VLAN de prueba de la UT1 y los dos clientes de la A3.4, en las VLAN 101 y 102 (10.10.101.0/24 y 10.10.102.0/24).
Máquinas, IDs de VM y direcciones¶
Una fila por máquina, con la hoja que la crea y la que la retira; las que no tienen fecha de baja llegan al final del curso. qm clone no admite la memoria, así que toda hoja que clona la fija en la misma orden con qm set <ID> --memory <MB>: la plantilla trae 2 GB y casi ninguna máquina los necesita. Los nombres DNS de cada una están en Nombres DNS y acceso.
| Máquina | ID | Red e IP | RAM al clonar | Qué corre | Nace en | Muere en |
|---|---|---|---|---|---|---|
| OPNsense | 109 | vmbr0 (WAN) y las cuatro VNets de dev, con el .1 de cada una; desde la A3.4, también vmbr1 |
1 GB | Cortafuegos, NAT, DHCP, DNS y hora de dev | A3.1, 20 nov (se instala en casa) | |
router-dev |
100 | vmbr0 y las cuatro VNets de dev, con el .1 de cada una |
512 MB | DHCP, DNS y NAT de dev hasta que llega OPNsense | A2.3, 4 nov | Se apaga en la A3.1 (20 nov) y se destruye al cerrar la evaluable de la UT3 (9 dic) |
jenkins01 |
101 | devmgmt, 10.10.0.10 |
2 GB | Jenkins con nginx delante | A6.1, 3 feb | |
gitea01 |
102 | devmgmt, 10.10.0.11 |
1 GB | Gitea con nginx delante; el registry desde la A6.6 (19 feb) | A6.4, 12 feb | |
mon01 |
103 | vmbr0 por DHCP hasta el 27 nov; después devmgmt, 10.10.0.20, y la 10.10.0.30 de MinIO |
3 GB | La pila de Mantenimiento en /opt/monitoring; la Gitea provisional del 17 nov al 12 feb; MinIO desde la A5.2 (18 dic) |
A1.3, 14 oct | |
admin01, el puesto de administración |
105 | vmbr0 por DHCP y devmgmt, 10.10.0.50 |
1 GB | El salto SSH hacia todas las zonas, la CA del curso, tofu y ansible, y las copias de trabajo de iac-lab, operacion y entregas-5166 |
A2.4, 6 nov | |
agent01 |
106 | devmgmt, 10.10.0.12 |
2 GB | El agente permanente de Jenkins, por SSH, y el Docker de los agentes efímeros; ansible y la ruta a pre desde la A6.8 |
A6.3, 10 feb | |
web01 |
110 | vmbr0 hasta el 30 oct; después devfront, 10.10.1.10 |
1 GB | nginx con TLS delante de la API | A1.3, 14 oct | |
app01 |
120 | vmbr0 por DHCP hasta el 27 nov; después devback, 10.10.2.10 |
2 GB | El compose servicio en /opt/servicio |
A1.3, 14 oct | |
db01 |
130 | devdata, 10.10.3.10 |
2 GB | PostgreSQL en su disco /data y postgres_exporter, desde la A3.3 (27 nov) |
A2.2, 30 oct | |
router-pre |
200 | vmbr0 y las cuatro VNets de pre, con el .1 de cada una; desde la A5.3, también devmgmt con la 10.10.0.2 |
512 MB | DHCP, DNS y NAT de pre, y el paso de gestión a pre | A2.5, 11 nov | A8.3 de Mantenimiento, 11 mar |
web01-pre, app01-pre y db01-pre |
210, 220 y 230 | prefront, preback y predata, con la .10 de cada subred |
1 GB | Lo que dice la ficha de pre | A5.3, 8 ene, con OpenTofu | A8.3 de Mantenimiento, 11 mar |
router-pro |
300 | vmbr0 y las cuatro VNets de pro |
512 MB | Nada: pro solo existe como red | A2.5, 11 nov | Al cerrar la evaluable de la UT2 (18 nov), junto con la 210 de prueba |
| MinIO | contenedor en mon01 |
devmgmt, 10.10.0.30, una segunda dirección de mon01 |
unos 300 MB, dentro de los 3 GB de mon01 |
Almacén S3 con los buckets tfstate y backups; si lo monta el profesor para toda el aula, no ocupa memoria del puesto. El ID 104 queda reservado por si algún curso le da VM propia |
A5.2, 18 dic |
Reparto de los ID de VM. La plantilla cloud-init es la 9000 (Debian 13 genericcloud). Las VM se numeran <entorno><zona><host>: la centena es el entorno (1 dev, 2 pre, 3 pro) y la decena es la zona, con el mismo número que el tercer octeto de su subred (0 gestión, 1 front, 2 back, 3 data). Así 120 se lee "dev, back, primera máquina" y nunca choca con 220, que es la misma pieza en pre.
| Entorno | Gestión | front | back | data | Pruebas y VM efímeras |
|---|---|---|---|---|---|
| dev | 100 a 109 | 110 a 119 | 120 a 129 | 130 a 139 | 150 a 199 |
| pre | 200 a 209 | 210 a 219 | 220 a 229 | 230 a 239 | 250 a 299 |
| pro | 300 a 309 | 310 a 319 | 320 a 329 | 330 a 339 | 350 a 399 |
Los contenedores LXC comparten numeración con las VM, así que salen del rango de pruebas del entorno que toque.
VM de prueba. Salen de la franja de pruebas de su entorno y se destruyen como muy tarde al cerrar la evaluable de su unidad, para dejar libre el ID: la A5.1, por ejemplo, vuelve a usar la 150.
| VM | ID | RAM al clonar | Nace en | Muere en |
|---|---|---|---|---|
web02, el clon enlazado de «Si te sobra tiempo» |
150 | 1 GB | A1.3, 14 oct | Al cerrar la evaluable de la UT1 (23 oct) |
La copia restaurada de web01 |
151 | 1 GB | A1.4, 16 oct | Al cerrar la evaluable de la UT1 |
ct01, el contenedor LXC |
170 | 512 MB | A1.4, 16 oct | Al cerrar la evaluable de la UT1 |
vlan10a, vlan10b y vlan20a |
160 a 162 | 512 MB | A1.5, 21 oct | Al terminar la A1.5 o su «Si te sobra tiempo» |
app-eval |
libre entre 150 y 199 | 3 GB, con ballooning | Evaluable de la UT1, 23 oct | Al entregarla |
web01 de prueba de pre |
210 | 512 MB | A2.5, 11 nov | Al cerrar la evaluable de la UT2 (18 nov) |
web01 de prueba de pro |
310 | 512 MB | A2.5, 11 nov | Al final de la A2.5 |
| Las de los scripts de la A2.6 | 310, 320 y 330 | 512 MB | A2.6, 13 nov | En la propia A2.6, con destruye-entorno.sh pro |
cli-a y cli-b |
180 y 181 | 512 MB | A3.4, 2 dic | Al cerrar la evaluable de la UT3 (9 dic) |
prueba01 |
150 | 1 GB | A5.1, 16 dic | En la propia A5.1, con tofu destroy |
El entorno pre¶
pre es la copia de dev en la que se ensaya antes de producción. Lo crea esta asignatura con OpenTofu el 8 de enero, lo usan las dos asignaturas y lo da de baja Mantenimiento el 11 de marzo. Esta ficha manda sobre lo que digan de pre las unidades de las dos asignaturas.
| Máquina | ID | IP | Qué corre |
|---|---|---|---|
router-pre |
200 | el .1 de cada subred de pre y la 10.10.0.2 en devmgmt |
DHCP y DNS de pre.lab, NAT de salida a Internet y el paso de gestión a pre |
web01-pre |
210 | 10.20.1.10 | Nada: se queda como clon limpio de la plantilla, sin nginx ni certificado |
app01-pre |
220 | 10.20.2.10 | El compose del servicio en /opt/servicio, proyecto servicio, solo con el servicio app y con DB_HOST=10.20.3.10 |
db01-pre |
230 | 10.20.3.10 | PostgreSQL del paquete de Debian, con la base servicio y el usuario app, abierto solo a 10.20.2.0/24 |
Las tres VM llevan 1 GB y salen de la plantilla, así que traen node_exporter. Lo que corre en app01-pre y en db01-pre lo deja el playbook de la A5.5; si no cabe en esa hoja, la parte de db01-pre pasa a la A5.6.
Cómo llega gestión a pre. La A2.5 aísla los entornos con rutas blackhole, y así se quedan. El paso lo da una pata de router-pre en devmgmt, que monta el paso 1 de la A5.3:
- En el nodo,
qm set 200 --net5 virtio,bridge=devmgmt --ipconfig5 ip=10.10.0.2/24; dentro derouter-preesa tarjeta esens23. Como 10.10.0.0/24 queda conectada, gana al blackhole de 10.10.0.0/16 yrouter-precontesta a gestión. - En
router-pre, tres reglas nftables deforward: lo establecido y relacionado se acepta, lo que entra porens23se acepta y nada nuevo de pre sale haciaens23. - En
admin01, la líneaExecStart=/sbin/ip route replace 10.20.0.0/16 via 10.10.0.2 dev ens19añadida aruta-lab.service.agent01, en la A6.8, ymon01, en la A7.4 de Mantenimiento, reciben la misma ruta con una unidad igual,ruta-pre.service.
pre no alcanza gestión: solo responde. Lo que llega a pre se empuja desde gestión, los ficheros con Ansible y las imágenes con docker save app:<versión> | ssh ops@10.20.2.10 docker load, porque desde pre no se llega al registry. pre sale a Internet por el NAT de router-pre. En las hojas se escribe con IP: los nombres <host>.pre.lab solo los resuelve router-pre.
Quién lo usa y cuándo.
| Fecha | Hoja | Qué hace con pre |
|---|---|---|
| 8 ene | A5.3 de Despliegue | Abre el camino de gestión y crea las tres VM con OpenTofu, con prevent_destroy |
| 13 a 20 ene | A5.4 a A5.6 de Despliegue | Estado remoto, playbook y test.sh, siempre sobre pre |
| 11 feb | A7.4 de Mantenimiento | La primera vez en Mantenimiento: da de alta en Prometheus el job node con env="pre", hace la copia previa y actualiza la aplicación con docker save y docker load |
| 25 feb | A8.1 de Mantenimiento | Plan de baja e inventario, sin tocar nada |
| 26 feb | A6.8 de Despliegue | El último despliegue en pre, con la etapa Deploy del pipeline |
| 9 mar | A8.2 de Mantenimiento | Para el servicio, guarda el volcado de bloqueo y libera los contenedores, los volúmenes y las imágenes de app01-pre |
| 10 mar | Evaluable de la UT6 de Despliegue | No despliega: se entrega con las evidencias del 26 de febrero |
| 11 mar | A8.3 de Mantenimiento | tofu destroy de pre (antes retira el prevent_destroy de las VM de pre en una rama de iac-lab), router-pre con su pata en devmgmt, las VNets de pre, las rutas de pre en admin01, agent01 y mon01, la credencial ssh-pre y la carpeta pre de Jenkins |
La UT4 de Mantenimiento trabaja contra dev (https://api.dev.lab), no contra pre. Las copias de pre las hace admin01 en el repositorio restic único, con la etiqueta pre: ssh ops@10.20.3.10 'sudo -u postgres pg_dump -Fc servicio' | restic backup --stdin --stdin-filename servicio-pre.dump --tag pre. En pre no hay certificados. Al dar de baja pre no se tocan el repositorio servicio, su webhook ni el job Multibranch, porque el pipeline sigue construyendo; del registry se borran solo las etiquetas que se desplegaron en pre, en la A8.4 de Mantenimiento (16 mar).
Nombres DNS y acceso¶
Hay dos categorías de nombres y conviene no mezclarlas:
- Servicios de plataforma, que viven en gestión y no pertenecen a ningún entorno: dominio plano
.lab.jenkins.lab,gitea.lab,registry.lab,grafana.labyprometheus.lab, y el de la máquina que los aloja, también en plano:jenkins01.lab,mon01.lab. - Hosts de servicio, uno por entorno:
<host>.<entorno>.lab.web01.dev.lab,app01.dev.lab,db01.dev.laby el servicio publicado,api.dev.lab.
No existe ningún gitea01.dev.lab: meter un servicio de plataforma en un entorno lo mezcla con lo que se da de baja con ese entorno. MinIO no tiene nombre: se usa como http://10.10.0.30:29000.
| Nombre | Apunta a | Lo resuelve | Desde |
|---|---|---|---|
app01 y mon01 |
la IP del aula de cada una | /etc/hosts del puesto del alumno y de mon01 |
A1.4 de Mantenimiento (15 oct), hasta el 27 nov |
<host>.dev.lab y api.dev.lab |
la IP de cada máquina; api.dev.lab, la de web01 |
router-dev, y OPNsense desde la A3.1 |
A2.3 (4 nov) |
gitea.lab |
mon01; gitea01 (10.10.0.11) desde la A6.4 (12 feb) |
/etc/hosts del puesto, de mon01, de app01 y del puesto de administración hasta el 27 nov; después, OPNsense |
A2.6 de Mantenimiento (17 nov) |
mon01.lab, grafana.lab y prometheus.lab |
10.10.0.20 | OPNsense | A3.1 (20 nov) |
jenkins.lab y jenkins01.lab |
10.10.0.10 | OPNsense | A6.1 (3 feb) |
registry.lab |
10.10.0.11 | OPNsense | A6.4 (12 feb) |
api.dev.lab, en el puesto del alumno |
la IP WAN de OPNsense | /etc/hosts del puesto |
A3.2 (25 nov) |
jenkins.lab y grafana.lab, en el puesto del alumno |
127.0.0.1, por el túnel de cada uno | /etc/hosts del puesto |
con su túnel |
<host>.pre.lab |
la .10 de cada subred de pre |
solo router-pre |
A5.3 (8 ene); en las hojas se usa la IP |
El 27 de noviembre, al trasladar app01 y mon01, se borran las líneas del aula del /etc/hosts del puesto, de mon01 y de app01: desde ese día los nombres los da OPNsense. Las VM de las zonas y mon01 reciben el DNS del .1 de su zona por DHCP; jenkins01, gitea01 y agent01 lo llevan fijo en su qm set (--nameserver 10.10.0.1 --searchdomain lab), y admin01 lo recibe en la A3.1 con esa misma orden (qm set 105 --nameserver 10.10.0.1 --searchdomain lab y un reinicio). Con la hora pasa lo mismo: desde la A3.1, OPNsense la sirve a todas las zonas por la regla 0, y cada VM la toma del .1 de su zona con systemd-timesyncd, como web01 y db01 en esa hoja.
Cómo se entra. Hasta el 27 de noviembre, a app01 y mon01 se entra por SSH directamente a su IP del aula, con la clave del puesto que la A1.3 metió en la plantilla; a las que ya están en la VPC (web01 y db01, desde el 30 de octubre), desde el nodo: directamente el 30 de octubre, que el nodo es todavía el .1 de cada subred, y con salto por router-dev desde el 4 de noviembre (ssh -J ops@<IP de aula de router-dev> ops@10.10.1.10); desde el 6 de noviembre, desde admin01. Desde el 27 de noviembre todas quedan detrás de OPNsense y solo admin01 tiene un pie en el aula, así que se entra con salto por él:
Para no escribir el salto cada vez, este ~/.ssh/config en el puesto del alumno:
Host admin01
HostName 192.168.1.60 # la IP de aula de admin01, la que le da el DHCP del aula
User ops
Host web01
HostName 10.10.1.10
Host app01
HostName 10.10.2.10
Host db01
HostName 10.10.3.10
Host mon01
HostName 10.10.0.20
Host jenkins01
HostName 10.10.0.10
Host gitea01
HostName 10.10.0.11
Host agent01
HostName 10.10.0.12
Host web01 app01 db01 mon01 jenkins01 gitea01 agent01 10.20.*
User ops
ProxyJump admin01
Con él, ssh app01, scp fichero mon01: o ssh 10.20.2.10 pasan por admin01 sin más. ssh toma cada opción del primer bloque que la define: por eso los HostName van arriba, uno por máquina, y el usuario y el salto, una sola vez abajo. Si el DHCP del aula cambia la IP de admin01, solo se toca la primera línea.
Las consolas web se abren con un túnel a través de admin01, que en el puesto escucha en el 28443: un puerto de la franja del curso, para no chocar con lo que ya tenga abierto el equipo. Las de esta asignatura son dos: la de OPNsense, ssh -L 28443:10.10.0.1:443 admin01 y https://localhost:28443, y la de Jenkins, ssh -L 28443:10.10.0.10:443 admin01 con la línea 127.0.0.1 jenkins.lab en el fichero hosts del puesto y https://jenkins.lab:28443. Las de la pila de monitorización (Prometheus, Alertmanager, Mailpit y Grafana) están en el laboratorio de Mantenimiento, en Cómo se llega a la pila desde el 3 de diciembre. La de Grafana usa también el 28443 del puesto, así que de esos tres túneles solo puede estar abierto uno a la vez.
Puertos¶
La franja del curso. Los puertos del servicio y de la monitorización van todos en la franja del 20000 al 29999, con una regla: el puerto de fábrica de cada programa más 20000 (Prometheus, del 9090 al 29090; la API, del 8080 al 28080). Los de fábrica son también los de muchas herramientas que pueden estar en marcha en el puesto del alumno, como el 80 de XAMPP o IIS, el 3000 de los servidores de desarrollo de Node, el 8080 de Tomcat o el 9090 de Cockpit, y un docker compose up que pide un puerto ocupado falla. La franja queda por encima de todos ellos y por debajo de los que el sistema operativo reparte a las conexiones salientes (desde el 32768 en Linux y desde el 49152 en Windows y macOS) y del rango de NodePort de Kubernetes (del 30000 al 32767). Cada servicio escucha en su número dentro del contenedor y se publica en el mismo, así que tiene uno solo en todas partes: en el compose.yml, en el navegador, en Prometheus y en el cortafuegos. La regla se ajusta cuando dos servicios de la misma máquina caerían en el mismo número: cAdvisor va en el 28081 porque el 28080 es de la API en app01, Gitea en el 23001 porque el 23000 es de Grafana en mon01, y whoami en el 28090 porque el 20080 es del nginx del compose del servicio.
Lo que se queda fuera. Los puertos que espera cualquier cliente (22, 53, 80, 443 y el 5432 de PostgreSQL), los de productos que no forman parte del servicio (el 8006 de Proxmox, el 2376 de Docker con TLS y el 5000 del registry, que va escrito en el nombre de cada imagen) y los que solo existen dentro de una red de Docker y nunca se publican, como el 8080 de Jenkins o el 1025, el SMTP de Mailpit.
| Puerto | Servicio | Dónde |
|---|---|---|
| 22 | SSH | todas las VM, usuario ops; desde el 27 nov, con salto por admin01 |
| 80 | HTTP, solo redirección a 443 | web01 |
| 443 | HTTPS, con nginx delante | api.dev.lab en web01, publicado en la WAN de OPNsense; jenkins.lab en jenkins01, gitea.lab en gitea01 desde el 12 feb y grafana.lab en mon01 desde el 3 dic, los tres en gestión; la consola de OPNsense, solo desde MGMT |
| 2376 | Docker de agent01 con TLS, para los agentes efímeros | agent01 |
| 5000 | registry de imágenes con TLS y htpasswd |
gitea01 desde el 19 feb, registry.lab:5000 |
| 5432 | PostgreSQL | db01, abierto solo a back; db01-pre, solo a 10.20.2.0/24 |
| 8006 | interfaz web de Proxmox | el nodo, en la red del aula |
| 8080 | Jenkins por HTTP, puerto interno | dentro del compose de jenkins01, nunca publicado |
| 20080 | nginx del compose del servicio | el puesto del alumno hasta el 13 oct y app01 hasta el 27 nov; desde entonces el proxy es el nginx de web01 |
| 23000 | Grafana | mon01; desde el 3 dic, solo por detrás de su nginx |
| 23001 | Gitea | mon01, publicado, del 17 nov (A2.6 de Mantenimiento) al 12 feb (A6.4); en gitea01, solo por detrás de su nginx |
| 23100 | Loki, con certificado de cliente desde el 3 dic | mon01 |
| 25000 | receptor de incidencias de Alertmanager | mon01, solo en 127.0.0.1 |
| 28025 | Mailpit, buzón de pruebas de Alertmanager (su web; el SMTP sigue en el 1025, dentro del compose) | mon01, solo en 127.0.0.1 desde el 3 dic |
| 28080 | la API del curso | app01 y app01-pre |
| 28081 | cAdvisor | app01 |
| 28090 | whoami, el contenedor de pruebas de cabeceras |
app01, desde la A3.3 |
| 28443 | túnel a las consolas web por HTTPS (OPNsense, Jenkins y Grafana) | el puesto del alumno |
| 29000 y 29001 | API S3 y consola de MinIO | 10.10.0.30, en mon01 |
| 29080 | Promtail | app01 |
| 29090 | Prometheus | mon01, solo en 127.0.0.1 desde el 3 dic |
| 29093 | Alertmanager | mon01, solo en 127.0.0.1 desde el 3 dic |
| 29100 | node_exporter | todas las VM que salen de la plantilla, que lo deja en este puerto; en app01, con TLS y usuario desde el 1 dic |
| 29102 | /metrics de la aplicación |
app01 |
| 29187 | postgres_exporter | en el compose del servicio hasta el 27 nov; en db01 desde la A3.3 |
Jenkins deja escrito su nombre en tres sitios y los tres dicen lo mismo: nombre público jenkins.lab, puerto público 443 (https://jenkins.lab, con nginx delante terminando TLS) y puerto interno 8080 dentro de la red del compose. En el servidor, el 8443 solo aparece en la variante con keystore Java, que no es la instalación del curso y está recogida en Para ampliar; en el puesto del alumno, el túnel usa el 28443. Los agentes que llaman al controlador lo hacen por WebSocket a través del mismo 443, así que el puerto 50000 no se abre.
El registry se escribe siempre entero, con puerto: registry.lab:5000. Ni registry.dev.lab ni registry.lab a secas.
Matriz de reglas de OPNsense¶
Una sola matriz para las dos asignaturas. Las pestañas son las interfaces de OPNsense (WAN, MGMT, DMZEXT, DMZINT, INT, CLI_A y CLI_B) y el grupo ZONAS, que las reúne todas menos WAN. Los alias son los de la A3.2 (srv_web, srv_app, srv_db, net_mgmt, p_web, p_app...) más los que añade la hoja de cada fila. Los números se reparten así: del 1 al 10, esta asignatura; del 11 al 20, la UT3 de Mantenimiento; del 21 en adelante, las unidades posteriores, que hoy no añaden ninguna. La denegación por defecto es siempre la 99. El número va al principio de la descripción de cada regla en OPNsense, para que el log y la matriz se crucen sin buscar.
| # | Pestaña | Origen | Destino | Puertos | Acción | Log | Para qué | Nace en |
|---|---|---|---|---|---|---|---|---|
| 0 | ZONAS | la red de la zona | This Firewall | p_infra (53 TCP y UDP, 123 UDP) e ICMP echo |
Pass | no | DNS, hora y ping al propio cortafuegos | A3.1 (20 nov) |
| 1 | WAN | any | srv_web |
p_web (80, 443) |
Pass | no | Publicación de api.dev.lab, con su port forward |
A3.2 (25 nov) |
| 2 | MGMT | net_mgmt |
any | p_web (80, 443) |
Pass | no | Consola del cortafuegos y salida a Internet de gestión, la única permanente | A3.2 (25 nov) |
| 3 | DMZEXT | srv_web |
srv_app |
p_app (28080, 28090) |
Pass | no | El proxy reenvía a la API y a whoami |
A3.3 (27 nov) |
| 4 | DMZINT | srv_app |
srv_db |
5432 | Pass | sí | La API consulta PostgreSQL | A3.3 (27 nov) |
| 5 | MGMT | net_mgmt |
any | 22 | Pass | sí | Administración por SSH | A3.2 (25 nov) |
| 6 | DMZINT | srv_app |
srv_gitea |
23001; 443 desde la A6.4 | Pass | no | git pull y git push de servicio desde app01. srv_gitea es la 10.10.0.20 hasta el 12 feb y la 10.10.0.11 desde la A6.4 |
A3.3 (27 nov) |
| 7 | CLI_A | net_cli_a |
srv_web |
443 | Pass | no | Cliente A al proxy compartido | A3.4 (2 dic) |
| 8 | CLI_A | net_cli_a |
any | any | Block | sí | Cliente A: el resto, denegado | A3.4 (2 dic) |
| 9 | CLI_B | net_cli_b |
srv_web |
443 | Pass | no | Cliente B al proxy compartido | A3.4 (2 dic) |
| 10 | CLI_B | net_cli_b |
any | any | Block | sí | Cliente B: el resto, denegado | A3.4 (2 dic) |
| 11 | MGMT | srv_mon |
srv_app |
p_mon_app (29100, 28081, 29102, 29080) |
Pass | sí | Scrape de mon01 a app01 | A3.1 de Mantenimiento (26 nov) |
| 12 | MGMT | srv_mon |
srv_db |
p_mon_db (29100, 29187) |
Pass | sí | Scrape de mon01 a db01 | A3.1 de Mantenimiento (26 nov) |
| 13 | DMZINT | srv_app |
srv_mon |
23100 | Pass | sí | Promtail de app01 hacia Loki | A3.1 de Mantenimiento (26 nov) |
| T | la de la zona | la máquina | any | p_web |
Pass | sí | TEMPORAL alta <fecha> baja <fecha> <motivo>: la salida de una zona de servicio para instalar algo |
La hoja que la necesita, que la borra en el mismo paso |
| 99 | todas | any | any | any | Block | sí | Denegación por defecto | A3.1 (20 nov) |
Desde el 20 de noviembre las zonas de servicio no salen a Internet (hasta ese día router-dev da salida a las cuatro zonas de dev): cuando una hoja tiene que instalar algo en ellas, abre la fila T en la pestaña de esa zona, instala y la borra en el mismo paso, y mientras existe la anota en la matriz. Gestión sale siempre, por la fila 2. La regla anti-lockout de MGMT la pone OPNsense sola y no lleva número. Ninguna fila deja a mon01 llegar a los puertos de scrape de front (la fila 2 solo le abre el 80 y el 443), y por eso la UT7 no vigila web01. pre no pasa por OPNsense: gestión llega a pre por la pata de router-pre en devmgmt, y pre sale a Internet por el NAT de router-pre.
La aplicación del curso¶
Las dos asignaturas trabajan sobre el mismo servicio, y esto es lo que cualquier hoja de cualquiera de las dos puede dar por hecho de él:
| Pieza | Valor |
|---|---|
| Lenguaje y servidor | Python con Flask, servido con gunicorn con un solo worker, hasta que se explique el modo multiproceso |
| Rutas | GET /health, GET /items, POST /items, GET /items/<id> y POST /login |
| Autenticación | POST /login con el usuario de prueba test devuelve un token Bearer |
| Errores | JSON {"error": "..."} con 400, 401, 404 o 422 |
| Puertos | la API en el 28080 y sus métricas en /metrics del 29102, los de la franja del curso; hasta el 27 nov, el nginx del compose en el 20080 |
| Repositorio | servicio: el código de la API en api/, con su api/Dockerfile, y compose.yml en la raíz |
| Compose | proyecto servicio en /opt/servicio, en todos los entornos. Servicios nginx, app y db hasta el 27 nov; desde la A3.3, solo app |
| Contenedores | servicio-app-1, servicio-db-1 y servicio-nginx-1 |
| Base de datos | base servicio y usuario de la aplicación app; el superusuario sigue siendo postgres. La API crea su esquema al arrancar si no existe |
| Imagen | app:<versión>, construida en app01 desde api/Dockerfile, hasta el 19 feb; desde la A6.6, registry.lab:5000/app:<versión> y registry.lab:5000/app:<commit corto>, que publica el pipeline |
| Etiquetas | el scrape de Prometheus deja host y service; Promtail deja host, service, container y level, este en minúsculas (info, warning, error) |
Las recetas que paran, arrancan o reinician una pieza usan siempre el compose y el nombre del servicio, nunca el del contenedor escrito a mano: docker compose -f /opt/servicio/compose.yml stop app. Las que provocan un fallo en app01 se lanzan desde el puesto, con ssh ops@<app01> docker compose -f /opt/servicio/compose.yml <acción> <servicio>. Los selectores de LogQL usan service y level: {service="app", level="error"}.
El paso a db01. Hasta el 27 de noviembre, la base y el proxy son los servicios db y nginx del compose de app01. La A3.3 instala PostgreSQL en db01 con la base servicio y el usuario app, pone DB_HOST=10.10.3.10 en el .env de /opt/servicio y quita db, nginx y postgres_exporter del compose. Los datos de prueba de octubre y noviembre no se trasladan: son de prueba, y la API crea el esquema vacío. Desde ese día PostgreSQL de dev se maneja con systemctl en db01, postgres_exporter corre como paquete en db01 y el proxy es el nginx de web01.
Nombres compartidos¶
Cada artefacto que usan las dos asignaturas tiene un solo nombre. Un nombre distinto no da error: da un 404, un «no existe» o una consulta vacía que se lee como cero.
| Artefacto | Nombre |
|---|---|
| Plantilla cloud-init | 9000, Debian 13 genericcloud, con qemu-guest-agent y prometheus-node-exporter dentro, este ya en el 29100, y dos claves públicas, la del puesto del alumno y la del nodo |
| Usuario en las VM | ops, con clave SSH ed25519 y sin contraseña |
| Zona del SDN | lab, tipo Simple, IPAM pve |
| Imagen del servicio | app:<versión> local hasta el 19 feb; desde entonces, registry.lab:5000/app:<versión> y registry.lab:5000/app:<commit corto> |
| Proyecto compose | servicio, en /opt/servicio, en dev y en pre |
| Base y usuario | base servicio, usuario app |
| Repositorios | propietario ops: ops/servicio, ops/monitoring, ops/alerting, ops/operacion, ops/incidencias, ops/iac-lab, ops/jenkins-config y ops/entregas-5166 |
| CA del curso | Lab 5166 CA, en ~/ca/ de admin01, creada con openssl ca en la A3.2 (25 nov); no hay otra |
| Usuario de Proxmox para OpenTofu | terraform@pve con el token tofu; nace en la A5.1 con PVEVMAdmin en /vms, PVEDatastoreUser en /storage/local-lvm y PVESDNUser en /sdn/zones/lab |
| Usuario de prácticas de la A2.6 | cli@pve, que la propia A2.6 borra al terminar |
| Credenciales de Jenkins | git-ro (token de Gitea de solo lectura), registry-cred (usuario jenkins del registry), ssh-pre (clave SSH de ops para pre, solo en la carpeta pre) y telegram-token. Jenkins no guarda ningún token de Proxmox |
| Etiqueta de equipo en las alertas | team |
| Tabla nftables en los hosts | inet fw |
| Credencial de MinIO para las copias | restic |
| Repositorio restic | uno solo, s3:http://10.10.0.30:29000/backups, con la contraseña en /etc/restic/pass; las copias de pre llevan --tag pre |
| Volumen de Gitea en mon01 | monitoring_gitea_data |
| Alarmas de la UT2 de Mantenimiento | la lista cerrada de su A2.4, que incluye HostDown; ninguna unidad cita otras |
| Retención de Prometheus | 45 días |
Repositorios¶
Todos los repositorios del curso viven en la Gitea del laboratorio, bajo el propietario ops. Hasta el 12 de febrero esa Gitea es un contenedor de mon01 y la URL es http://gitea.lab:23001/ops/<repositorio>.git; la A6.4 la traslada a gitea01, y cada copia de trabajo cambia de remoto una sola vez, con git remote set-url origin https://gitea.lab/ops/<repositorio>.git.
| Repositorio | Qué guarda | Nace en | Copia de trabajo | Remoto desde |
|---|---|---|---|---|
servicio |
La API en api/ con su Dockerfile, el compose.yml, las pruebas y el Jenkinsfile |
A1.1 de Mantenimiento (1 oct), con el código que entrega el profesor | app01, en /opt/servicio (en el puesto del alumno hasta el 15 oct) |
A2.6 de Mantenimiento (17 nov) |
monitoring |
La pila de mon01; desde la UT7 de esta asignatura, también sus ficheros ut7-* |
A1.1 de Mantenimiento (1 oct) | mon01, en /opt/monitoring (en el puesto del alumno hasta el 15 oct) |
A2.6 de Mantenimiento |
alerting |
Reglas, Alertmanager y el receptor de incidencias | A2.1 de Mantenimiento (29 oct) | mon01, en /opt/alerting |
A2.6 de Mantenimiento |
incidencias |
Solo las issues que abre el receptor de alertas | A2.6 de Mantenimiento (17 nov), directamente en Gitea | ninguna | desde que nace |
entregas-5166 |
El trabajo de las hojas de esta asignatura, una carpeta por hoja | A2.1 de Despliegue (28 oct), en local | admin01 desde la A2.4 (6 nov) | 17 nov, en cuanto existe la Gitea de mon01 |
operacion |
Fichas de métricas, catálogo de alarmas, runbooks y revisiones | A4.1 de Mantenimiento (15 dic) | admin01 | la propia A4.1 |
iac-lab |
OpenTofu y Ansible de pre | A5.1 de Despliegue (16 dic), con git init |
admin01 | la propia A5.1 |
jenkins-config |
La instalación de Jenkins (compose, JCasC, plugins, nginx) y el compose del registry | A6.2 de Despliegue (5 feb) | jenkins01, en ~/jenkins-config |
la propia A6.2 |
Desde el 27 de noviembre app01 llega a Gitea por la fila 6 de la matriz de reglas. Las dos asignaturas entregan cada una su etiqueta de git del mismo monitoring: entrega-5169-ut8 y entrega-5166-ut7.
Ninguno puede contener un secreto: .env y secrets/ van en .gitignore desde el primer commit, y desde la A5.8 (27 ene) gitleaks corre como hook de pre-commit en iac-lab.
Cómo se monta MinIO¶
Lo monta cada alumno en el paso 1 de la A5.2 (18 de diciembre), salvo que el profesor lo monte para toda el aula: entonces basta con apuntar el endpoint, la clave y el secreto que dé, y comprobar con mc ls que se ven tfstate y backups. Va como un contenedor más de la pila de mon01 y no como VM propia porque la máquina ya tiene Docker, está encendida desde octubre y así el presupuesto de memoria no sube. Fuera de un laboratorio no se juntaría el almacén de copias con la máquina que vigila: si se pierde mon01, se pierden a la vez la monitorización y las copias. En una empresa es un servicio aparte, con versionado y Object Lock, que es lo que comprueba la UT6 de Mantenimiento.
La segunda dirección. La 10.10.0.30 se añade a la tarjeta de gestión de mon01 (en las VM del curso, ens18) con una unidad de systemd, igual que la ruta del puesto de administración en la A2.4, para no depender de los ficheros de red que escribe cloud-init. El Before=docker.service asegura que la dirección existe antes de que arranque el contenedor; sin él, Docker falla con cannot assign requested address.
sudo tee /etc/systemd/system/ip-minio.service > /dev/null <<'EOF'
[Unit]
Description=Segunda dirección de mon01 para MinIO
After=network-online.target
Wants=network-online.target
Before=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/ip addr replace 10.10.0.30/24 dev ens18
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now ip-minio.service
El servicio. Va en el compose.yml de /opt/monitoring, con minio_data: declarado en volumes:. El puerto se publica solo en la dirección nueva, para que la pila de monitorización siga en la 10.10.0.20. La contraseña de admin va en el .env junto al compose.yml, en 600 y en el .gitignore del repositorio monitoring. La ruta interna es /almacen para no confundirla con el /data de db01. Los puertos son los de fábrica de MinIO, el 9000 de la API S3 y el 9001 de la consola, llevados a la franja del curso con --address y --console-address.
minio:
image: quay.io/minio/minio:latest
command: server /almacen --address ":29000" --console-address ":29001"
restart: unless-stopped
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?ponla en el .env}
ports:
- "10.10.0.30:29000:29000"
- "10.10.0.30:29001:29001"
volumes:
- minio_data:/almacen
Buckets y credenciales. mc, el cliente de MinIO, se usa como contenedor de un solo uso. Los secretos de tofu y restic van al gestor de contraseñas del puesto de administración: el de tofu lo pide la A5.4 y el de restic, la A7.4 de Mantenimiento.
cd /opt/monitoring && docker compose up -d minio
set -a; . ./.env; set +a # trae MINIO_ROOT_PASSWORD a esta terminal
M="docker run --rm --network host -e MC_HOST_lab=http://admin:$MINIO_ROOT_PASSWORD@10.10.0.30:29000 quay.io/minio/mc"
$M mb lab/tfstate # el estado de OpenTofu
$M mb lab/backups # las copias restic de Mantenimiento
$M admin user add lab tofu 'CambiaEsteSecreto1'
$M admin user add lab restic 'CambiaEsteSecreto2'
$M admin policy attach lab readwrite --user tofu
$M admin policy attach lab readwrite --user restic
$M ls lab # tfstate y backups
Desde el puesto de administración, curl -s -o /dev/null -w '%{http_code}\n' http://10.10.0.30:29000/minio/health/live tiene que responder 200.
Cuando algo se rompe¶
Se va a romper. Es parte del módulo. El orden de recuperación, de menos a más drástico:
- Snapshot de la VM afectada. Antes de cada práctica evaluable conviene hacer un snapshot de las VM que se vayan a tocar. Volver atrás cuesta segundos.
- Recrear la VM desde la plantilla. Con cloud-init es un minuto; las de pre, con un
tofu apply. - Snapshot de la VM de Proxmox en VirtualBox/VMware. Conviene hacerlo al terminar la UT1 (hipervisor limpio y configurado) y al terminar la UT3 (red y firewall montados). Son los dos puntos a los que más veces hay que volver.
- Reinstalar Proxmox. Dos horas con la ISO y las notas de la UT1 a mano. Por eso las notas.
Conviene guardar fuera del equipo del aula una copia de: la clave SSH, los ficheros de configuración del firewall (OPNsense exporta un XML), los repositorios, las plantillas cloud-init y la carpeta ~/ca/ de admin01, sin la que no se puede emitir ni revocar ningún certificado. Con eso se reconstruye todo lo demás.
Repaso previo¶
Si alguno de estos puntos no está fresco, conviene dedicarle una tarde antes de la UT1:
- Terminal de Linux: rutas, permisos,
systemctl,journalctl, edición connanoovim,sshcon claves. La guía de Linux Journey es corta y suficiente. - Redes: qué es una máscara, cómo se calcula el rango de una subred, qué hace una puerta de enlace, qué es NAT. Cualquier calculadora de subredes (ipcalc) sirve para practicar.
- Docker:
docker run,docker compose up, volúmenes, redes,docker logs. La documentación oficial tiene un tutorial de una hora. - Git: clonar, commit, push, ramas, resolver un conflicto. Pro Git en español, capítulos 2 y 3.