Skip to content

UCU Octubre 2026

Desafío del Taller

Desde tu proyecto de Public Cloud en Netuy, desplegá empleando exclusivamente las herramientas de la interface gráfica:

  • 3 nodos de aplicación aislados de Internet que al recibir peticiones HTTP respondan con su hostname.
  • 1 balanceador de carga conectado a Internet que al recibir peticiones HTTP en la ruta http://IP-PUBLICA/nodos/, redirija la petición aleatoriamente a alguno de los 3 nodos de aplicación y luego redirija la respuesta de estos a su destinatario.

El caso de uso del desafío se representa en el siguiente diagrama:

Desafío


Algunos tips

Arquitectura

La arquitectura de la solución se parecerá a la siguiente:

Arquitectura del desafío


Prepara las redes antes de lanzar las instancias

Ten presente que para completar el desafío:

  1. Deberás conocer de antemano las direcciones IP internas que se asignarán a tus nodos de aplicación.
  2. Todas tus instancias deberán contar con conexión a Internet para instalar los paquetes que necesites.
  3. Necesitarás habilitar el tráfico HTTP entrante en todos tus servidores (recuerda que la security group predeterminada solo habilita el tráfico saliente).
Pista para punto #1

Una posible estrategia para satisfacer el punto Nro. 1 es:

  • crear tu red interna con pool de asignación con exactamente 3 direcciones IP y resolvedores DNS externos. Por ejemplo utilizando esta configuración:

    Configuración de red
    Paso 1 de 3: Creación de la red interna

    Configuración de subred
    Paso 2 de 3: Creación de la red interna: configuración de la subred

    Configuración pools de asignación y DNS
    Paso 3 de 3: Creación de la red interna: configuración de pools de asignación y servidores DNS

    • dentro de tu red interna, crear un puerto de red para utilizar en el balanceador de carga, especificando cualquier dirección IP de tu segmento que no se solape con las del pool de asignación. Siguiendo el ejemplo, puede ser la dirección 172.16.0.10

    Configuración de red
    Creación del puerto de red

Pista para punto #2

Para satisfacer el punto Nro. 2, bastará con crear un router y conectarlo a la red interna que acabas de crear y configurar.

Pista para punto #3

Una opción rápida para resolver este aspecto, es sumar reglas a la security group predeterminada para habilitar el tráfico HTTP entrante desde todos los orígenes:

Habilitar entrada HTTP IPv4
Crear regla para habilitar la entrada HTTP desde todos los orígenes IPv4

Selección de sistema operativo y recursos

Ubuntu Server es un sistema operativo estable, seguro, apto para uso en producción e incluye gran cantidad de utilizarios en sus respositorios estándar.

Puedes lanzar tus instancias desde la imagen ubuntu-resolute-26.04, la edición LTS más reciente. Además, requiere tan pocos recursos que el flavor 1x1 será suficiente.

Customization Scripts (cloud-config)

Debes valerte solo de la interface gráfica para el desafío, por lo que necesitarás utilizar customization scripts para la instalación y configuración interna de los servidores.

Tal vez, si utilizaste Ubuntu para lanzar tus instancias, esos scripts sean los mismos que los que se nos cayeron aquí 😏

Al lanzar el balanceador de carga

#cloud-config

users:
  - default
  - name: ucu
    shell: /bin/bash
    sudo: ALL=(ALL) NOPASSWD:ALL
    lock_passwd: false
    passwd: $6$rounds=4096$DVwNAZeG9EnlYxyh$V18.fqjRHGCi1TdHo0owqbn8OnPdaXxX5UlWoH0MC3nie7SPDD4F95xiPWiWbS1QsFrvfs5xg/1WTsete469L/
    # password hash de "taller2026"

package_update: true
packages:
  - nginx
  - prometheus-nginx-exporter
  - prometheus-node-exporter

runcmd:
- mkdir /app
- cp /etc/hostname /app/index.html

write_files:
  - path: /etc/nginx/sites-enabled/default
    permissions: '0644'
    owner: root
    content: |
        upstream pool_nodos {
            # ip_hash;  # Descomentar para ser dirigido siempre al mismo nodo
            server 172.16.0.11 max_fails=1 fail_timeout=15s;
            server 172.16.0.12 max_fails=1 fail_timeout=15s;
            server 172.16.0.13 max_fails=1 fail_timeout=15s;
        }

        server {
            listen 80;
            # Contenido servido desde el propio loadbalancer:
            location / {
                root /app;
            }
            # Contenido servido dinámicamente desde los nodos de aplicación:
            location /nodos/ {
                proxy_pass http://pool_nodos/;
            }
        }

Al lanzar los nodos de aplicación

#cloud-config

users:
  - default
  - name: ucu
    shell: /bin/bash
    sudo: ALL=(ALL) NOPASSWD:ALL
    lock_passwd: false
    passwd: $6$rounds=4096$DVwNAZeG9EnlYxyh$V18.fqjRHGCi1TdHo0owqbn8OnPdaXxX5UlWoH0MC3nie7SPDD4F95xiPWiWbS1QsFrvfs5xg/1WTsete469L/
    # password hash de "taller2026"

package_update: true
packages:
  - nginx
  - prometheus-nginx-exporter
  - prometheus-node-exporter

runcmd:
- mkdir /app
- cp /etc/hostname /app/index.html

write_files:
  - path: /etc/nginx/sites-enabled/default
    permissions: '0644'
    owner: root
    content: |
        server {
            listen 80;
            location / {
                root /app;
            }
        }

¿Te sobró tiempo?

Desafío adicional para los velocistas:

  1. Sumá un servidor a tu red privada para monitorear los nodos aplicación y balanceador de carga
  2. Accedé a tus métricas y dasboard desde un navegador empleando una floating IP
Customization script de ejemplo para Prometheus + Grafana
#cloud-config

users:
  - default
  - name: ucu
    shell: /bin/bash
    sudo: ALL=(ALL) NOPASSWD:ALL
    lock_passwd: false
    passwd: $6$rounds=4096$DVwNAZeG9EnlYxyh$V18.fqjRHGCi1TdHo0owqbn8OnPdaXxX5UlWoH0MC3nie7SPDD4F95xiPWiWbS1QsFrvfs5xg/1WTsete469L/
    # password hash de "taller2026"

package_update: true
packages:
  - apt-transport-http
  - prometheus
  - prometheus-node-exporter

runcmd:
  - install -d -m 0755 /etc/apt/keyrings
  - wget -q -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key
  - chmod 0644 /etc/apt/keyrings/grafana.asc
  - sh -c 'echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list'
  - apt-get update
  - DEBIAN_FRONTEND=noninteractive apt-get install -y grafana
  - systemctl daemon-reload
  - systemctl enable --now grafana-server

write_files:
  - path: /etc/prometheus/prometheus.yml
    permissions: '0644'
    owner: root
    content: |
      global:
        scrape_interval:     15s

      scrape_configs:
        - job_name: 'prometheus'
          scrape_interval: 5s
          scrape_timeout: 5s
          static_configs:
            - targets: ['localhost:9090']

        - job_name: app-nodes
          static_configs:
            - targets: ['172.16.0.11:9100','172.16.0.12:9100', '172.16.0.13:9100']

        - job_name: app-nginx
          static_configs:
            - targets: ['172.16.0.11:9113','172.16.0.12:9113', '172.16.0.13:9113']

  - path: /etc/grafana/provisioning/datasources/prometheus.yml
    permissions: '0644'
    owner: root
    content: |
      apiVersion: 1
      datasources:
        - name: Prometheus
          type: prometheus
          url: http://localhost:9090
          isDefault: true