Tancàvem el mòdul 1 amb una promesa: deixar de planificar i començar a construir. Aquesta lliçó la compleix. Compute Engine és el servei de màquines virtuals de Google Cloud i, encara que avui existeixin opcions més modernes —contenidors, PaaS, serverless—, continua sent la porta d'entrada natural per a una empresa com AlpinaShop, que avui té el seu catàleg Flask funcionant sobre un servidor físic llogat i necessita moure'l al núvol sense reescriure'l.

En aquesta lliçó aprendràs què és realment una VM gestionada i quan continua sent l'elecció correcta; com s'organitzen les famílies i els tipus de màquina, i com evitar pagar de més triant malament; quines imatges pots utilitzar i com crear-ne de pròpies; els tipus de disc i el seu rendiment; com crear la instància alpinashop-web-1 a europe-west1-b des de la consola i des de gcloud, amb un startup script que instal·la l'aplicació tota sola; com entrar per SSH de manera segura amb OS Login; i, sobretot, com les plantilles d'instància i els grups d'instàncies gestionats resolen el problema real d'AlpinaShop: els pics de trànsit de les campanyes de tardor.

Contingut

  1. Què és una màquina virtual gestionada i quan utilitzar-la
  2. Famílies i tipus de màquina
  3. Imatges públiques i personalitzades
  4. Discos: tipus, rendiment i instantànies
  5. Crear alpinashop-web-1 des de la consola
  6. Crear la mateixa VM amb gcloud i un startup script
  7. Accés per SSH i OS Login
  8. Comptes de servei i àmbits d'accés
  9. Plantilles d'instància i grups gestionats (MIG)
  10. Escalat automàtic i reparació automàtica: els pics de tardor
  11. VM Spot: còmput barat i interrompible
  12. Cicle de vida d'una instància i què es cobra en cada estat

  1. Què és una màquina virtual gestionada i quan utilitzar-la

Una màquina virtual de Compute Engine és un ordinador complet que s'executa sobre la infraestructura de Google: té la seva CPU, la seva memòria, els seus discos, el seu sistema operatiu i la seva adreça IP. Des de dins, és indistingible d'un servidor físic. La diferència és en tot allò que l'envolta: es crea en 30 segons amb una comanda, es redimensiona apagant-la i encenent-la, es replica cent vegades amb una plantilla i desapareix quan l'esborres.

Que sigui gestionada significa que Google s'ocupa del maquinari, la virtualització, la xarxa física, la refrigeració i el reemplaçament de discos avariats. Tu t'ocupes del sistema operatiu cap amunt: pedaços, configuració, aplicació, dades. És exactament el repartiment IaaS que vam veure a la taula de responsabilitat compartida de la lliçó 01-05.

Quan continua tenint sentit una VM el 2026, amb tanta alternativa serverless disponible:

  • Migració lift-and-shift. Tens una aplicació que funciona i vols moure-la sense reescriure-la. És el cas d'AlpinaShop.
  • Necessites control del sistema operatiu. Kernel concret, mòduls, controladors, programari amb llicència lligada a maquinari, agents de seguretat corporatius.
  • Processos de llarga durada o sempre actius. El serverless penalitza (o directament prohibeix) processos d'hores.
  • Programari que no es contenidoritza bé. Aplicacions monolítiques antigues, sistemes amb estat al disc local, servidors de llicències.
  • Càrregues amb maquinari especial. GPU per a inferència, discos locals de latència mínima, màquines de molta memòria per a bases de dades en RAM.
  • Cost predictible amb ús constant elevat. Una VM 24×7 amb descompte per ús compromès pot sortir més barata que el seu equivalent serverless.

Quan NO és l'elecció adequada: una API HTTP amb trànsit intermitent (millor Cloud Run, 07-02), una feina que respon a un esdeveniment i dura segons (Cloud Functions, 06-03) o una aplicació web ja contenidoritzada que vols escalar horitzontalment (GKE, 02-05). A la lliçó 02-07 posarem tot això en una taula de decisió.

  1. Famílies i tipus de màquina

El tipus de màquina defineix quantes CPU virtuals (vCPU) i quanta memòria té la instància. Google els agrupa en famílies, cadascuna optimitzada per a un perfil de càrrega diferent. Triar bé aquí és la decisió que més impacte té a la factura de còmput.

Família Perfil vCPU/memòria típics Per a què serveix Exemple de tipus
E2 Ús general econòmic 2–32 vCPU, ràtios flexibles Servidors web petits, entorns de desenvolupament, microserveis. L'opció per defecte per començar e2-medium (2 vCPU, 4 GB)
N2 / N2D Ús general equilibrat 2–128 vCPU Càrregues de producció generals. N2D fa servir AMD EPYC i sol sortir una mica més barata n2-standard-4 (4 vCPU, 16 GB)
N4 / C4 Generacions recents Ampli Substituts moderns d'N2/C2 amb millor relació preu-rendiment a les regions on estan disponibles n4-standard-4
C3 / C3D Optimitzada per a còmput 4–176 vCPU CPU intensiva: renderització, compilació, simulació, servidors de jocs, processament d'imatges c3-highcpu-8
M3 / M2 / M1 Optimitzada per a memòria Fins a diversos TB de RAM SAP HANA, bases de dades en memòria, anàlisi de grans datasets en RAM m3-ultramem-32
A3 / G2 Acceleradors Amb GPU (NVIDIA) Entrenament i inferència de models, transcodificació de vídeo a3-highgpu-8g
Personalitzada A mida Tu tries vCPU i RAM Quan cap tipus estàndard no encaixa i pagues memòria o CPU que no utilitzes custom-6-16384

Dins de cada família hi ha sufixos que indiquen la ràtio memòria/CPU:

  • -highcpu: poca memòria per vCPU (≈1 GB). Per a processos de càlcul.
  • -standard: ràtio equilibrada (≈4 GB per vCPU). El cas general.
  • -highmem: molta memòria per vCPU (≈8 GB). Memòries cau, bases de dades.
  • -ultramem / -megamem: extrems de memòria, només a les famílies M.

Tipus personalitzats. Si la teva aplicació necessita 6 vCPU i 16 GB, cap tipus estàndard no et dóna exactament això: n2-standard-8 et donaria 8 vCPU i 32 GB, i pagaries el doble del que necessites. La sintaxi d'un tipus personalitzat és <familia>-custom-<vCPU>-<MiB de memòria>:

# 6 vCPU i 16 GB (16384 MiB) sobre la familia N2
gcloud compute instances create exemple-custom \
  --machine-type=n2-custom-6-16384 \
  --zone=europe-west1-b

Tingues en compte les restriccions: el nombre de vCPU ha de ser parell (excepte 1), i la memòria per vCPU té un mínim i un màxim per família. Si et passes del màxim estàndard, es factura com a "memòria estesa", més cara.

Què tria AlpinaShop? El seu catàleg Flask serveix avui unes poques desenes de peticions per segon, amb pics concentrats a la tardor. Comencem amb e2-medium (2 vCPU, 4 GB) en desenvolupament i e2-standard-2 en producció, sabent que el creixement es resoldrà horitzontalment (més instàncies) i no verticalment (una instància més gran). Aquesta decisió —escalar en amplada, no en alçada— és la que fa possible l'escalat automàtic de l'apartat 10.

Sobre preus: tots els imports d'aquest curs són ordres de magnitud per raonar, no tarifes. Els preus varien per regió i canvien amb el temps; consulta sempre la calculadora oficial de Google Cloud i la pàgina de preus de Compute Engine abans de comprometre't.

  1. Imatges públiques i personalitzades

Una imatge és la plantilla del disc d'arrencada: el sistema operatiu i el programari preinstal·lat. Google manté un catàleg d'imatges públiques, agrupades en famílies d'imatges que sempre apunten a la versió més recent.

# Veure les families d'imatges de Debian disponibles
gcloud compute images list \
  --filter="family~debian" \
  --format="table(name, family, status)"

Les més habituals:

Família d'imatge Projecte Notes
debian-12 debian-cloud Lleugera, estable, l'elecció per defecte a GCP
ubuntu-2404-lts ubuntu-os-cloud Molt comuna, molta documentació de tercers
rocky-linux-9 rocky-linux-cloud Compatible amb RHEL, sense cost de llicència
rhel-9 rhel-cloud Red Hat oficial, amb cost de llicència afegit
cos-stable cos-cloud Container-Optimized OS: mínima, pensada només per executar contenidors
windows-2022 windows-cloud Windows Server, amb llicència facturada per hora

Utilitzar la família en lloc del nom exacte (--image-family=debian-12 en lloc de --image=debian-12-bookworm-v20260101) és una bona pràctica: cada VM nova arrenca amb l'última versió apedaçada.

Imatges personalitzades. Quan tens una VM configurada com vols —dependències instal·lades, agents, configuració de l'empresa— pots convertir-la en imatge i utilitzar-la com a base de totes les altres. És la tècnica clau perquè les instàncies noves arrenquin en segons en lloc de minuts:

# 1. Aturar la instancia per garantir consistencia del disc
gcloud compute instances stop alpinashop-web-1 --zone=europe-west1-b

# 2. Crear la imatge a partir del seu disc d'arrencada
gcloud compute images create alpinashop-web-base-v1 \
  --source-disk=alpinashop-web-1 \
  --source-disk-zone=europe-west1-b \
  --family=alpinashop-web \
  --description="Debian 12 + Python + Flask + dependencies del cataleg"

En assignar-li --family=alpinashop-web, les versions posteriors (-v2, -v3) formaran una família pròpia i podràs crear VM amb --image-family=alpinashop-web --image-project=alpinashop-prod, obtenint sempre l'última.

Al mòdul 6 veuràs com automatitzar la construcció d'aquestes imatges en un pipeline; de moment, fer-ho a mà és suficient per entendre el mecanisme.

  1. Discos: tipus, rendiment i instantànies

Tota VM necessita com a mínim un disc d'arrencada, i pot tenir discos addicionals. L'elecció del tipus de disc afecta el rendiment tant o més que la CPU.

Tipus Nom a gcloud Rendiment Persistència Quan utilitzar-lo
Persistent estàndard pd-standard Baix (HDD) Sobreviu a la VM Dades fredes, registres, còpies. Gairebé obsolet
Persistent balancejat pd-balanced Mitjà-alt (SSD) Sobreviu a la VM Opció per defecte. Arrencada i dades generals
Persistent SSD pd-ssd Alt, IOPS elevades Sobreviu a la VM Bases de dades, càrregues amb moltes escriptures aleatòries
Persistent extrem pd-extreme Molt alt, IOPS aprovisionables Sobreviu a la VM Bases de dades crítiques de mida gran
Hyperdisk hyperdisk-balanced, hyperdisk-extreme, hyperdisk-throughput Configurable: IOPS i cabal independents de la mida Sobreviu a la VM Generació actual a les famílies modernes (C3, N4, M3); permet ajustar el rendiment sense sobredimensionar la mida
SSD local local-ssd Màxim, latència mínima Es perd en aturar o esborrar la VM Memòria cau, scratch, índexs reconstruïbles. Mai dades úniques
Disc persistent regional --region en lloc de --zone Una mica menor que el seu equivalent zonal Replicat de manera síncrona en dues zones Quan necessites que les dades sobrevisquin a la caiguda d'una zona

Punts que solen sorprendre qui ve d'un servidor físic:

  • Als discos persistents tradicionals, el rendiment escala amb la mida. Un pd-balanced de 10 GB té molt poques IOPS. Si la teva base de dades va lenta, de vegades la solució és engrandir el disc encara que no necessitis l'espai. Amb Hyperdisk això es trenca: el rendiment s'aprovisiona per separat.
  • El rendiment també està limitat pel tipus de màquina. Una VM de 2 vCPU no arribarà al cabal màxim del disc encara que el disc ho permeti.
  • Els discos persistents ja estan replicats dins de la seva zona. No necessites RAID per fiabilitat.
  • L'SSD local és efímer de debò. Si atures la instància, el contingut desapareix. És un error freqüent i car.

Instantànies (snapshots) i imatges de disc. Són dos mecanismes diferents que sovint es confonen:

Instantània Imatge
Propòsit Còpia de seguretat puntual Plantilla per crear VM noves
Incremental Sí (només blocs canviats des de l'anterior) No
Abast Global, es pot restaurar en una altra regió Global
Ús típic Recuperació davant de desastre, backup diari Estandarditzar l'arrencada d'una flota

Crear una instantània i programar-les automàticament:

# Instantania puntual del disc d'arrencada
gcloud compute snapshots create alpinashop-web-1-snap-20260805 \
  --source-disk=alpinashop-web-1 \
  --source-disk-zone=europe-west1-b \
  --storage-location=europe-west1

# Politica d'instantanies diaries a les 03:00 UTC, amb 14 dies de retencio
gcloud compute resource-policies create snapshot-schedule alpinashop-diario \
  --region=europe-west1 \
  --max-retention-days=14 \
  --daily-schedule \
  --start-time=03:00 \
  --on-source-disk-delete=apply-retention-policy

# Associar la politica al disc
gcloud compute disks add-resource-policies alpinashop-web-1 \
  --resource-policies=alpinashop-diario \
  --zone=europe-west1-b

Aquest bloc mereix aturar-s'hi. --max-retention-days=14 significa que les instantànies més antigues de 14 dies s'esborren soles, cosa que evita que el cost creixi indefinidament. --on-source-disk-delete=apply-retention-policy indica que, si algú esborra el disc, les instantànies no s'esborren immediatament sinó que segueixen la seva política de retenció: és la teva xarxa de seguretat davant d'un esborrat accidental. La Marta tindrà còpies diàries sense escriure ni un sol cron.

  1. Crear alpinashop-web-1 des de la consola

Abans d'automatitzar convé veure el formulari complet una vegada, perquè ensenya quines opcions existeixen. A la consola: Compute Engine → Instàncies de VM → Crear instància.

Els camps que importen:

  1. Nom: alpinashop-web-1. Minúscules, guions, sense accents. No es pot canviar després.
  2. Regió i zona: europe-west1 / europe-west1-b, la decisió que vam prendre a 01-05.
  3. Configuració de la màquina: família Ús general → sèrie E2 → tipus e2-medium.
  4. Disc d'arrencada: Debian 12, pd-balanced, 20 GB.
  5. Identitat i accés a l'API: compte de servei i àmbits (apartat 8).
  6. Tallafoc: les caselles "Permetre trànsit HTTP/HTTPS" afegeixen etiquetes de xarxa i creen regles de tallafoc. Les utilitzarem per provar, però el disseny correcte de xarxa i tallafoc és matèria de la lliçó 03-01.
  7. Opcions avançades → Automatització: aquí s'enganxa el startup script.
  8. Etiquetes (labels): entorno=dev, equipo=plataforma, centro-coste=tienda, aplicacion=catalogo, seguint l'esquema que vam fixar a 01-04.

Abans de prémer Crear, utilitza l'enllaç "Línia de comandes equivalent" que vam veure a 01-03: et retorna la comanda gcloud exacta. És la millor manera d'aprendre la sintaxi i el primer pas cap a la infraestructura com a codi.

  1. Crear la mateixa VM amb gcloud i un startup script

Un startup script és un script que la VM executa com a root en cada arrencada. És la forma més simple de configuració automàtica: sense ell, hauries d'entrar per SSH i teclejar les comandes a mà en cada instància nova, cosa que fa impossible l'escalat automàtic.

Primer escrivim el script en un fitxer a part (més llegible i versionable que posar-lo en línia):

cat > ~/startup-catalogo.sh <<'SCRIPT'
#!/bin/bash
set -e

# Instal.lar dependencies del sistema
apt-get update
apt-get install -y python3-pip python3-venv

# Crear l'entorn de l'aplicacio
mkdir -p /opt/alpinashop
python3 -m venv /opt/alpinashop/venv
/opt/alpinashop/venv/bin/pip install flask gunicorn

# Aplicacio Flask minima del cataleg
cat > /opt/alpinashop/app.py <<'PYCODE'
from flask import Flask
import socket

app = Flask(__name__)

PRODUCTES = [
    {"sku": "MOC-40", "nom": "Motxilla Trekking 40L", "preu": 89.90},
    {"sku": "BOT-GTX", "nom": "Botes Gore-Tex Alpina", "preu": 149.00},
    {"sku": "TDA-2P", "nom": "Tenda 2 places Ultralight", "preu": 219.50},
]

@app.route("/")
def cataleg():
    files = "".join(
        f"<li>{p['sku']} - {p['nom']} - {p['preu']:.2f} EUR</li>"
        for p in PRODUCTES
    )
    return (
        f"<h1>AlpinaShop</h1><ul>{files}</ul>"
        f"<p>Servit per: {socket.gethostname()}</p>"
    )

@app.route("/salud")
def salut():
    return "ok", 200
PYCODE

# Servei systemd perque arrenqui sol i es reinicii si falla
cat > /etc/systemd/system/alpinashop.service <<'UNIT'
[Unit]
Description=Cataleg AlpinaShop
After=network.target

[Service]
WorkingDirectory=/opt/alpinashop
ExecStart=/opt/alpinashop/venv/bin/gunicorn -b 0.0.0.0:80 -w 2 app:app
Restart=always

[Install]
WantedBy=multi-user.target
UNIT

systemctl daemon-reload
systemctl enable --now alpinashop
SCRIPT

Tres detalls del script que convé entendre:

  • set -e avorta el script tan bon punt una comanda falla. Sense això, un apt-get fallit passaria desapercebut i acabaries amb una VM a mig configurar que sembla sana.
  • <<'SCRIPT' amb cometes simples impedeix que bash substitueixi les variables en escriure el fitxer; volem que el contingut arribi literal a la VM.
  • La ruta /salud existeix perquè, més endavant, el grup d'instàncies pugui comprovar si l'aplicació és viva. Retornar 200 en una ruta lleugera és la base de qualsevol health check.

Ara creem la instància:

gcloud compute instances create alpinashop-web-1 \
  --project=alpinashop-dev \
  --zone=europe-west1-b \
  --machine-type=e2-medium \
  --image-family=debian-12 \
  --image-project=debian-cloud \
  --boot-disk-size=20GB \
  --boot-disk-type=pd-balanced \
  --tags=http-server \
  --metadata-from-file=startup-script=$HOME/startup-catalogo.sh \
  --metadata=enable-oslogin=TRUE \
  --labels=entorno=dev,equipo=plataforma,centro-coste=tienda,aplicacion=catalogo

Flag per flag:

  • --image-family + --image-project: sempre l'última Debian 12 apedaçada.
  • --tags=http-server: etiqueta de xarxa que associa la VM a la regla de tallafoc que permet el port 80. Les regles de tallafoc s'estudien a 03-01; aquí n'hi ha prou de saber que sense l'etiqueta correcta el trànsit no arriba.
  • --metadata-from-file=startup-script=...: la clau de metadades startup-script és especial, l'agent convidat l'executa en cada arrencada.
  • --metadata=enable-oslogin=TRUE: activa OS Login (apartat 7).
  • --labels: etiquetes de facturació, no de xarxa. No confonguis --tags amb --labels: els primers governen el tallafoc, les segones la comptabilitat.

Comprovem que funciona:

# Veure la IP externa assignada
gcloud compute instances describe alpinashop-web-1 \
  --zone=europe-west1-b \
  --format="value(networkInterfaces[0].accessConfigs[0].natIP)"

# Si encara no existeix la regla de tallafoc, crear-la (detall a 03-01)
gcloud compute firewall-rules create permitir-http \
  --allow=tcp:80 \
  --target-tags=http-server \
  --description="Acces HTTP temporal per a proves del cataleg"

# Provar (el startup script triga 1-2 minuts la primera vegada)
IP=$(gcloud compute instances describe alpinashop-web-1 \
  --zone=europe-west1-b \
  --format="value(networkInterfaces[0].accessConfigs[0].natIP)")
curl -s "http://$IP/"

Si no respon, el lloc on mirar és el registre del script:

gcloud compute ssh alpinashop-web-1 --zone=europe-west1-b \
  --command="sudo journalctl -u google-startup-scripts.service --no-pager | tail -40"

  1. Accés per SSH i OS Login

Hi ha tres maneres d'entrar en una VM de Linux:

Mètode Com funciona Avantatges Inconvenients
SSH des del navegador Botó SSH a la consola; Google genera claus efímeres Zero configuració, funciona des de qualsevol lloc Requereix que la VM tingui IP pública o IAP configurat
gcloud compute ssh Genera un parell de claus a ~/.ssh/google_compute_engine i el publica Còmode, integrat amb la teva identitat de gcloud Depèn del CLI instal·lat
Client SSH propi Afegeixes la teva clau pública a les metadades o a OS Login Compatible amb les teves eines Gestió manual de claus

Exemples:

# Entrar a la VM
gcloud compute ssh alpinashop-web-1 --zone=europe-west1-b

# Executar una comanda sense sessio interactiva
gcloud compute ssh alpinashop-web-1 --zone=europe-west1-b \
  --command="systemctl status alpinashop --no-pager"

# Copiar un fitxer a la VM
gcloud compute scp ./catalogo.csv alpinashop-web-1:/tmp/ --zone=europe-west1-b

# Entrar sense IP publica, a traves d'IAP (tunel segur)
gcloud compute ssh alpinashop-web-1 --zone=europe-west1-b --tunnel-through-iap

Per què OS Login és el recomanat. Sense OS Login, les claus SSH es desen a les metadades de la instància o del projecte. Això té tres problemes seriosos: qualsevol amb permís per editar metadades pot afegir la seva clau i entrar; quan algú deixa l'empresa cal recórrer les instàncies esborrant la seva clau a mà; i no queda un rastre clar de qui va entrar.

OS Login vincula el compte SSH del Linux a la identitat de Google Cloud. Amb això:

  • L'accés es concedeix amb rols IAM (roles/compute.osLogin per a usuari normal, roles/compute.osAdminLogin per a sudo), no manipulant fitxers.
  • Quan es desactiva el compte d'un empleat a Cloud Identity, perd l'accés a totes les VM immediatament.
  • Els accessos queden auditats a Cloud Logging.
  • Es pot exigir verificació en dos passos amb enable-oslogin-2fa=TRUE.

Activa'l a escala de projecte perquè s'apliqui a totes les instàncies, presents i futures:

gcloud compute project-info add-metadata \
  --metadata=enable-oslogin=TRUE

# Concedir al Dani acces SSH normal (sense sudo)
gcloud projects add-iam-policy-binding alpinashop-dev \
  --member="user:[email protected]" \
  --role="roles/compute.osLogin"

El detall de com es componen els rols IAM el veurem a 03-04; aquí n'hi ha prou de retenir la idea: l'accés als servidors es gestiona amb identitats, no amb fitxers de claus repartits.

  1. Comptes de servei i àmbits d'accés

Tota VM s'executa com algú. Aquest algú és un compte de servei: una identitat no humana que l'aplicació fa servir per cridar altres API de Google Cloud. Quan el catàleg d'AlpinaShop pugi una imatge a alpinashop-catalogo (lliçó 02-02), no utilitzarà contrasenyes: utilitzarà el compte de servei de la VM.

Per defecte s'assigna el compte de servei predeterminat de Compute Engine, que té el rol d'Editor sobre tot el projecte. És massa permissiu: si algú compromet l'aplicació web, obté control gairebé total del projecte. La pràctica correcta és crear un compte de servei dedicat amb només els permisos necessaris:

# Crear un compte de servei propi per al cataleg
gcloud iam service-accounts create sa-catalogo-web \
  --display-name="Cataleg web d'AlpinaShop"

# Donar-li nomes el que necessita: llegir i escriure objectes a Storage
gcloud projects add-iam-policy-binding alpinashop-dev \
  --member="serviceAccount:[email protected]" \
  --role="roles/storage.objectAdmin"

# Assignar-lo a la VM (requereix la VM aturada)
gcloud compute instances set-service-account alpinashop-web-1 \
  --zone=europe-west1-b \
  --service-account="[email protected]" \
  --scopes=cloud-platform

Sobre els àmbits (scopes): són un mecanisme antic que limita quines API pot invocar la VM, a més del que permet IAM. El permís efectiu és la intersecció de tots dos. La recomanació actual és utilitzar --scopes=cloud-platform i controlar els permisos reals amb rols IAM, que són molt més granulars. Tot això es desenvolupa a 03-04.

  1. Plantilles d'instància i grups gestionats (MIG)

Una sola VM té dos problemes: si cau, el lloc cau; i si arriba un pic de trànsit, no hi ha cap on créixer. La solució de Compute Engine són les plantilles d'instància i els grups d'instàncies gestionats.

  • Plantilla d'instància (instance template): la definició immutable de com és una VM (tipus, imatge, discos, xarxa, metadades, script). No crea res per si sola; és un motlle. Com que és immutable, canviar alguna cosa significa crear una plantilla nova.
  • Grup d'instàncies gestionat (MIG): un conjunt de VM idèntiques creades a partir d'una plantilla, que el sistema manté vives i en el nombre que li indiquis.
graph TD
    A[Plantilla d'instancia<br/>alpinashop-web-tpl-v1] --> B[MIG alpinashop-web-mig]
    B --> C[VM alpinashop-web-mig-a1b2]
    B --> D[VM alpinashop-web-mig-c3d4]
    B --> E[VM alpinashop-web-mig-e5f6]
    F[Comprovacio d'estat<br/>GET /salud] --> B
    G[Politica d'escalat automatic<br/>CPU objectiu 60 per cent] --> B

Creem la plantilla a partir de tot el que ja sabem:

gcloud compute instance-templates create alpinashop-web-tpl-v1 \
  --machine-type=e2-medium \
  --image-family=debian-12 \
  --image-project=debian-cloud \
  --boot-disk-size=20GB \
  --boot-disk-type=pd-balanced \
  --tags=http-server \
  --metadata-from-file=startup-script=$HOME/startup-catalogo.sh \
  --metadata=enable-oslogin=TRUE \
  --service-account="[email protected]" \
  --scopes=cloud-platform \
  --labels=entorno=prod,equipo=plataforma,centro-coste=tienda,aplicacion=catalogo

Definim una comprovació d'estat i creem el grup regional (repartit entre les zones d'europe-west1, per sobreviure a la caiguda d'una zona, tal com vam raonar a 01-05):

# Comprovacio d'estat: demana /salud cada 10 s
gcloud compute health-checks create http hc-catalogo \
  --port=80 \
  --request-path=/salud \
  --check-interval=10s \
  --timeout=5s \
  --healthy-threshold=2 \
  --unhealthy-threshold=3

# Grup gestionat regional amb 2 instancies inicials
gcloud compute instance-groups managed create alpinashop-web-mig \
  --template=alpinashop-web-tpl-v1 \
  --size=2 \
  --region=europe-west1 \
  --health-check=hc-catalogo \
  --initial-delay=180

--initial-delay=180 és important: li diu al grup que esperi 3 minuts abans de considerar malalta una instància acabada de crear. Sense aquest marge, el startup script encara estaria instal·lant dependències, el health check fallaria i el MIG entraria en un bucle de destruir i recrear instàncies que mai no arriben a arrencar. És un dels errors clàssics.

  1. Escalat automàtic i reparació automàtica: els pics de tardor

Aquí hi ha la resposta al problema que arrossega AlpinaShop des de la primera lliçó: a les campanyes de tardor el servidor físic se satura i la botiga va lenta just quan més ven.

gcloud compute instance-groups managed set-autoscaling alpinashop-web-mig \
  --region=europe-west1 \
  --min-num-replicas=2 \
  --max-num-replicas=10 \
  --target-cpu-utilization=0.60 \
  --cool-down-period=120

Què fa exactament:

  • --min-num-replicas=2: mai baixa de 2 instàncies, en zones diferents. És el mínim perquè una caiguda zonal no deixi la botiga sense servei.
  • --max-num-replicas=10: sostre de seguretat. Protegeix la factura davant d'un pic anòmal o un atac; sense sostre, un bot podria multiplicar la teva despesa.
  • --target-cpu-utilization=0.60: l'escalador automàtic afegeix o treu instàncies per mantenir la CPU mitjana del grup a prop del 60 %. Es deixa marge perquè escalar no és instantani: entre que es decideix crear una VM i està servint trànsit passen minuts.
  • --cool-down-period=120: ignora les mètriques dels primers 120 segons de vida de cada instància, mentre arrenca.

També es pot escalar per peticions per segon o per mètriques pròpies de Cloud Monitoring (per exemple, la longitud d'una cua), cosa que sol funcionar millor que la CPU per a aplicacions web. Ho veurem a 06-04.

Reparació automàtica. Amb el health check associat, si una instància deixa de respondre a /salud durant tres comprovacions seguides, el MIG l'esborra i en crea una altra a partir de la plantilla. És autoreparació real, no un reinici: la instància nova neix neta.

Això té una conseqüència de disseny que cal assumir: les instàncies del grup són d'un sol ús. Res important no pot viure només al seu disc, perquè desapareixeran sense avisar. Les dades van a Cloud SQL (02-03), les imatges a Cloud Storage (02-02) i les sessions a un magatzem compartit (02-06). El servidor deixa de ser una mascota i passa a ser bestiar.

Per actualitzar l'aplicació es crea una plantilla nova i es llança una actualització progressiva:

gcloud compute instance-groups managed rolling-action start-update alpinashop-web-mig \
  --region=europe-west1 \
  --version=template=alpinashop-web-tpl-v2 \
  --max-surge=2 \
  --max-unavailable=0

--max-unavailable=0 combinat amb --max-surge=2 significa: crea fins a dues instàncies noves abans de retirar les velles, de manera que la capacitat mai no baixi. És un desplegament sense tall de servei. Si alguna cosa va malament, es rellança la comanda apuntant de nou a -v1.

El que falta perquè això sigui una arquitectura completa és un balancejador de càrrega que reparteixi el trànsit entre les instàncies del grup amb una única IP i un certificat TLS. Aquest és exactament el contingut de la lliçó 03-02, i per això aquí parem.

  1. VM Spot: còmput barat i interrompible

Les VM Spot (evolució de les antigues preemptibles) utilitzen capacitat sobrant de Google i costen de l'ordre d'un 60–90 % menys. A canvi, Google pot aturar-les en qualsevol moment amb només 30 segons d'avís.

gcloud compute instances create procesador-imagenes-spot \
  --zone=europe-west1-b \
  --machine-type=e2-standard-4 \
  --provisioning-model=SPOT \
  --instance-termination-action=DELETE \
  --metadata-from-file=startup-script=$HOME/procesar-lote.sh
Aspecte VM estàndard VM Spot
Preu Tarifa normal Molt inferior (varia amb la demanda)
Durada Indefinida Es pot acabar en qualsevol moment
Avís previ — 30 segons (esdeveniment ACPI G2)
SLA Sí No
Ús adequat Serveis en producció Lots, renderització, proves, CI

Casos vàlids per a AlpinaShop: regenerar les miniatures dels 60 GB d'imatges de producte, recalcular un informe pesat, executar la bateria de tests nocturna. Casos invàlids: el servidor web de la botiga o qualsevol cosa la interrupció de la qual es noti en un client.

Bona pràctica: captura el senyal de terminació amb un shutdown script per desar el progrés i que la feina pugui reprendre's on la va deixar.

  1. Cicle de vida d'una instància i què es cobra en cada estat

stateDiagram-v2
    [*] --> PROVISIONING: crear
    PROVISIONING --> STAGING
    STAGING --> RUNNING
    RUNNING --> STOPPING: stop
    STOPPING --> TERMINATED
    TERMINATED --> STAGING: start
    TERMINATED --> [*]: delete
    RUNNING --> SUSPENDING: suspend
    SUSPENDING --> SUSPENDED
    SUSPENDED --> RUNNING: resume

Aquesta és la taula que més diners estalvia de tota la lliçó:

Estat Es cobra CPU/RAM? Es cobren els discos? Es cobra la IP externa? Es conserva el contingut?
RUNNING Sí Sí Sí (si és estàtica o efímera en ús) Sí
TERMINATED (aturada) No Sí Sí si és estàtica i sense utilitzar Disc persistent sí; SSD local no
SUSPENDED No (es cobra l'emmagatzematge de la RAM abocada) Sí Igual que aturada Sí, inclosa la memòria
Esborrada No Només si vas marcar "conservar disc" Només si la IP és estàtica Només el que hagis conservat

Lliçons pràctiques:

  • Aturar una VM no elimina el seu cost. Els discos continuen facturant-se. Una VM de desenvolupament aturada durant mesos amb un disc de 500 GB continua costant diners.
  • Les IP externes estàtiques reservades i no utilitzades es cobren, precisament per desincentivar l'acaparament. Allibera les que no facis servir.
  • Apagar els entorns de desenvolupament fora d'horari és l'optimització més rendible i senzilla: unes 128 hores setmanals apagat sobre 168 és un estalvi directe del 75 % en còmput. Es pot automatitzar amb Cloud Scheduler i una funció (06-03).

Operacions habituals:

# Aturar i arrencar
gcloud compute instances stop alpinashop-web-1 --zone=europe-west1-b
gcloud compute instances start alpinashop-web-1 --zone=europe-west1-b

# Redimensionar (requereix la instancia aturada)
gcloud compute instances set-machine-type alpinashop-web-1 \
  --zone=europe-west1-b \
  --machine-type=e2-standard-2

# Ampliar el disc (en calent; despres cal ampliar el sistema de fitxers)
gcloud compute disks resize alpinashop-web-1 --zone=europe-west1-b --size=50GB
gcloud compute ssh alpinashop-web-1 --zone=europe-west1-b \
  --command="sudo resize2fs /dev/sda1"

# Protegir contra esborrat accidental
gcloud compute instances update alpinashop-web-1 \
  --zone=europe-west1-b --deletion-protection

# Esborrar conservant el disc de dades
gcloud compute instances delete alpinashop-web-1 \
  --zone=europe-west1-b --keep-disks=data

Fixa't en resize2fs: ampliar el disc a Google Cloud no amplia automàticament el sistema de fitxers dins del sistema operatiu. És un pas que s'oblida constantment i produeix el desconcert de veure 50 GB a la consola i 20 GB a df -h.

Errors habituals i consells

  • Sobredimensionar la primera VM "per si de cas". És més barat començar petit i créixer: Compute Engine et dirà fins i tot, a les recomanacions de la consola, que la teva instància està infrautilitzada. L'optimització sistemàtica s'aborda a 07-05.
  • Confondre --tags amb --labels. Les tags de xarxa controlen regles de tallafoc; els labels són metadades de facturació i organització. Posar entorno=prod com a tag no fa res útil.
  • Desar dades importants en un SSD local. Es perden en aturar la instància. Mai no és "només un moment".
  • Dependre del disc d'una instància d'un MIG. Les instàncies d'un grup gestionat són d'un sol ús per disseny.
  • Oblidar --initial-delay al MIG. El grup mata les instàncies mentre arrenquen i entra en un bucle infinit de creació i destrucció.
  • Deixar el compte de servei predeterminat amb rol Editor. És l'escalada de privilegis més fàcil d'explotar si comprometen la teva aplicació.
  • Repartir claus SSH per metadades. Utilitza OS Login des del principi; retirar accessos després és molt més difícil.
  • Creure que aturar una VM la deixa a cost zero. Els discos i les IP estàtiques continuen comptant.
  • Consell: fes que el startup script sigui idempotent. S'executa en cada arrencada, no només a la primera.
  • Consell: prova el startup script en una VM d'un sol ús abans de posar-lo en una plantilla. Depurar-lo dins d'un MIG que s'autodestrueix és exasperant.
  • Consell: anomena les plantilles amb versió (-v1, -v2). Són immutables i necessitaràs poder tornar enrere.
  • Consell: activa la protecció contra esborrat en qualsevol instància de producció que no formi part d'un grup gestionat.

Exercicis

Exercici 1: triar tipus de màquina i disc

Per a cada escenari d'AlpinaShop, indica família i tipus de màquina, tipus de disc i justificació breu:

  1. El servidor web del catàleg Flask en producció, amb trànsit moderat i creixement horitzontal previst.
  2. Un procés nocturn que reescala les 60.000 imatges de producte i triga unes 3 hores; es pot reintentar si falla.
  3. Una futura instància d'anàlisi que carrega en memòria un dataset de 400 GB per a consultes interactives.
  4. Una VM de desenvolupament on el Dani prova canvis unes 6 hores al dia.

Exercici 2: crear la instància i verificar el startup script

Partint del projecte alpinashop-dev:

  1. Crea alpinashop-web-2 a europe-west1-c amb e2-medium, Debian 12, disc balancejat de 20 GB, OS Login activat i els quatre labels de l'esquema d'AlpinaShop.
  2. Utilitza un startup script que instal·li nginx i escrigui una pàgina amb el nom de la instància.
  3. Crea la regla de tallafoc necessària i comprova amb curl que respon.
  4. Consulta el registre del startup script dins de la instància.
  5. Esborra la instància conservant el seu disc d'arrencada i explica quin cost continua generant.

Exercici 3: grup gestionat amb escalat automàtic

La Marta vol estar preparada per a la campanya de tardor:

  1. Crea una plantilla alpinashop-web-tpl-ej amb el startup script del catàleg.
  2. Crea un MIG regional a europe-west1 amb 2 instàncies i comprovació d'estat sobre /salud.
  3. Configura l'escalat automàtic entre 2 i 6 instàncies amb objectiu de CPU al 65 %.
  4. Simula una caiguda: entra en una instància, atura el servei i observa què fa el grup.
  5. Explica per què aquesta arquitectura encara no és utilitzable de cara al públic i què hi falta.

Solucions

Solució 1

Escenari Màquina Disc Justificació
1. Web del catàleg e2-standard-2 (o e2-medium) pd-balanced 20 GB Càrrega lleugera i estable; el creixement es resol amb més instàncies al MIG, no amb una màquina més gran
2. Reescalat d'imatges c3-highcpu-8 o e2-standard-8 en mode Spot pd-balanced + local-ssd com a scratch CPU intensiva, tolerant a interrupció: Spot redueix molt el cost. L'SSD local és vàlid perquè el resultat final va a Cloud Storage
3. Anàlisi en memòria m3-ultramem-32 o similar de la família M pd-ssd o Hyperdisk Només les famílies de memòria ofereixen aquesta RAM; el disc ràpid accelera la càrrega inicial
4. VM de desenvolupament e2-medium pd-balanced 20 GB Barata; l'important és apagar-la fora d'horari, cosa que elimina el cost de CPU i RAM

Solució 2

cat > ~/startup-nginx.sh <<'SCRIPT'
#!/bin/bash
set -e
apt-get update
apt-get install -y nginx
NOM=$(curl -s -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/name)
echo "<h1>AlpinaShop</h1><p>Instancia: $NOM</p>" > /var/www/html/index.html
systemctl enable --now nginx
SCRIPT

gcloud compute instances create alpinashop-web-2 \
  --project=alpinashop-dev \
  --zone=europe-west1-c \
  --machine-type=e2-medium \
  --image-family=debian-12 --image-project=debian-cloud \
  --boot-disk-size=20GB --boot-disk-type=pd-balanced \
  --tags=http-server \
  --metadata-from-file=startup-script=$HOME/startup-nginx.sh \
  --metadata=enable-oslogin=TRUE \
  --labels=entorno=dev,equipo=plataforma,centro-coste=tienda,aplicacion=catalogo

Observa com el script obté el nom de la instància del servidor de metadades (metadata.google.internal), disponible des de dins de qualsevol VM. La capçalera Metadata-Flavor: Google és obligatòria i serveix com a protecció davant de peticions fabricades des de l'exterior.

# 3. Tallafoc i comprovacio
gcloud compute firewall-rules create permitir-http \
  --allow=tcp:80 --target-tags=http-server 2>/dev/null || true

IP=$(gcloud compute instances describe alpinashop-web-2 --zone=europe-west1-c \
  --format="value(networkInterfaces[0].accessConfigs[0].natIP)")
curl -s "http://$IP/"

# 4. Registre del startup script
gcloud compute ssh alpinashop-web-2 --zone=europe-west1-c \
  --command="sudo journalctl -u google-startup-scripts.service --no-pager | tail -30"

# 5. Esborrar conservant el disc
gcloud compute instances delete alpinashop-web-2 \
  --zone=europe-west1-c --keep-disks=boot

Després del punt 5 continues pagant el disc persistent de 20 GB, que queda orfe a la zona europe-west1-c. Discos orfes així són una font clàssica de despesa invisible: convé llistar-los periòdicament amb gcloud compute disks list --filter="-users:*".

Solució 3

# 1. Plantilla
gcloud compute instance-templates create alpinashop-web-tpl-ej \
  --machine-type=e2-medium \
  --image-family=debian-12 --image-project=debian-cloud \
  --boot-disk-type=pd-balanced --boot-disk-size=20GB \
  --tags=http-server \
  --metadata-from-file=startup-script=$HOME/startup-catalogo.sh \
  --metadata=enable-oslogin=TRUE

# 2. Health check i MIG regional
gcloud compute health-checks create http hc-catalogo-ej \
  --port=80 --request-path=/salud \
  --check-interval=10s --unhealthy-threshold=3

gcloud compute instance-groups managed create alpinashop-web-mig-ej \
  --template=alpinashop-web-tpl-ej \
  --size=2 --region=europe-west1 \
  --health-check=hc-catalogo-ej --initial-delay=180

# 3. Escalat automatic
gcloud compute instance-groups managed set-autoscaling alpinashop-web-mig-ej \
  --region=europe-west1 \
  --min-num-replicas=2 --max-num-replicas=6 \
  --target-cpu-utilization=0.65 --cool-down-period=120

# 4. Simular caiguda
INST=$(gcloud compute instance-groups managed list-instances alpinashop-web-mig-ej \
  --region=europe-west1 --format="value(instance)" | head -1 | xargs basename)
ZONA=$(gcloud compute instances list --filter="name=$INST" --format="value(zone)")
gcloud compute ssh "$INST" --zone="$ZONA" --command="sudo systemctl stop alpinashop"

# Observar l'estat del grup
watch -n 10 gcloud compute instance-groups managed list-instances \
  alpinashop-web-mig-ej --region=europe-west1

Al punt 4 veuràs que, després de tres comprovacions fallides (uns 30 segons), l'estat de la instància passa a UNHEALTHY i poc després el grup la recrea: canvia el seu nom i torna a HEALTHY un cop el startup script ha acabat. No s'ha reiniciat el servei: s'ha reemplaçat la màquina sencera.

Al punt 5, el que falta és un balancejador de càrrega: avui cada instància té la seva pròpia IP efímera, no hi ha un punt d'entrada únic, ni HTTPS, ni un nom de domini, ni distribució del trànsit. A més, les instàncies estan directament exposades a internet al port 80, cosa inacceptable en producció. Tot això es resol al mòdul 3 (03-01 VPC, 03-02 balanceig, 03-07 DNS i TLS).

Recorda netejar en acabar:

gcloud compute instance-groups managed delete alpinashop-web-mig-ej --region=europe-west1 --quiet
gcloud compute instance-templates delete alpinashop-web-tpl-ej --quiet
gcloud compute health-checks delete hc-catalogo-ej --quiet

Conclusió

Hem fet el primer pas real de la migració d'AlpinaShop. Saps què és una VM gestionada i, més important, quan continua sent la resposta correcta i quan no. Coneixes les famílies de màquines —E2 per començar, N2/N4 per a producció general, C3 per a còmput, M3 per a memòria, i els tipus personalitzats quan no encaixa res— i saps que el sufix highcpu/standard/highmem governa la ràtio de memòria. Has vist el catàleg d'imatges públiques, per què convé utilitzar famílies d'imatge en lloc de versions fixes, i com crear la teva pròpia imatge base. Has comparat els tipus de disc i has interioritzat dues idees crítiques: que el rendiment d'un disc persistent clàssic depèn de la seva mida, i que un SSD local es perd en aturar la màquina. Has programat instantànies automàtiques amb retenció, la còpia de seguretat que la Marta no havia tingut mai.

Has creat alpinashop-web-1 a europe-west1-b des de la consola i des de gcloud, amb un startup script que instal·la Python, Flask i gunicorn i deixa el catàleg servint sota systemd, incloent-hi una ruta /salud que va resultar ser la peça clau de la resta de la lliçó. Has après les tres vies d'accés SSH i per què OS Login —identitats en lloc de fitxers de claus— és l'única opció defensable en una empresa. Has substituït el compte de servei predeterminat per sa-catalogo-web, amb permisos mínims. I, sobretot, has convertit una màquina única en una plantilla i un grup gestionat regional amb escalat automàtic de 2 a 10 instàncies i reparació automàtica: el mecanisme que farà que la campanya de tardor d'AlpinaShop deixi de ser un problema. Pel camí has assumit el canvi mental que exigeix el núvol: les instàncies són d'un sol ús, i per tant les dades han de viure en un altre lloc.

Aquest "altre lloc" és justament el tema de la lliçó següent. A 02-02, Cloud Storage, mourem els 60 GB d'imatges de producte que avui ocupen el disc local del servidor físic al bucket alpinashop-catalogo: veurem el model d'objectes i per què no existeixen els directoris, triarem classe d'emmagatzematge i ubicació, farem la transferència real amb gcloud storage rsync, protegirem el bucket amb accés uniforme i URL signades, automatitzarem l'abaratiment amb regles de cicle de vida i connectarem l'aplicació Flask a Storage amb la biblioteca client de Python. Les instàncies podran morir sense endur-se res per davant.

Curs de Google Cloud Platform (GCP)

Mòdul 1: Introducció a Google Cloud Platform

Mòdul 2: Serveis principals de GCP

Mòdul 3: Xarxes i seguretat

Mòdul 4: Dades i anàlisi

Mòdul 5: Aprenentatge automàtic i IA

Mòdul 6: DevOps i monitoratge

Mòdul 7: Temes avançats de GCP

Mòdul 8: Projecte final

© Copyright 2026. Tots els drets reservats