Saps fer servir totes dues. Has aixecat Aurora Libros amb compose.yaml i overrides per entorn al mòdul 4, i l'has desplegada en un clúster amb StatefulSet, Ingress, HPA i rollback assajat al mòdul 6. Aquesta lliçó no ve a dir-te quina guanya, sinó a donar-te els criteris per decidir quina necessita el teu projecte, amb les equivalències exactes entre tots dos formats i una xifra honesta del cost de mantenir un clúster.

Contingut

  1. No són la mateixa categoria d'eina
  2. La pregunta correcta
  3. Comparativa a fons, dimensió per dimensió
  4. Equivalències conceptuals
  5. El mateix aurora-api, en tots dos formats
  6. Arbre de decisió
  7. El camí intermedi: Compose en producció
  8. Swarm com a esglaó, i els serveis que executen Compose
  9. Kompose i els límits reals de la conversió
  10. El cost ocult de Kubernetes
  11. Aurora Libros a tres mides

  1. No són la mateixa categoria d'eina

Comparar Compose amb Kubernetes és com comparar una recepta amb una cuina industrial. Totes dues coses serveixen per menjar, però una és un document i l'altra és un sistema amb personal.

Docker Compose Kubernetes
Què és Un descriptor d'aplicació multicontenidor i una CLI que l'aplica Un orquestrador distribuït amb pla de control propi
On viu A la teva màquina, parlant amb un daemon En un clúster de nodes, amb etcd i controladors
Què fa quan alguna cosa cau Reinicia el contenidor segons restart: Reprograma la càrrega en un altre node
Model d'execució Un docker compose up que executes tu Bucles de reconciliació permanents
Estat desitjat Existeix mentre duri la comanda Persistent a etcd, vigilat sempre
Unitat mínima El contenidor El Pod (un o més contenidors)

La diferència estructural és a la quarta fila. Compose executa el que li demanes i acaba; Kubernetes guarda la teva intenció i no deixa de comparar-la amb la realitat. Aquell bucle és el que et permet que un node caigui a les quatre de la matinada i els Pods reapareguin en un altre sense que ningú es desperti. També és el que t'obliga a mantenir un pla de control.

  1. La pregunta correcta

No és «quina és millor?». És una bateria de preguntes concretes:

  1. Et pots permetre que la plataforma estigui caiguda quinze minuts mentre reinicies una màquina?
  2. Quants nodes tindràs de debò d'aquí a un any: un, tres o trenta?
  3. Hi ha algú a l'equip que sàpiga depurar un CrashLoopBackOff sense buscar a Internet?
  4. Qui està de guàrdia a les tres de la matinada, i cobra per estar-hi?
  5. La teva càrrega és constant o té pics de ×8 que exigeixen autoescalat?
  6. El pressupost aguanta el pla de control més els nodes amb marge lliure?

Si has respost «quinze minuts són acceptables, un node, ningú, ningú, constant, no» —que és la situació de la majoria de projectes—, Compose és la resposta professional, i dir-ho en veu alta t'estalviarà un any de patiment. Si has respost el contrari en tres preguntes o més, Kubernetes comença a pagar el seu cost.

  1. Comparativa a fons, dimensió per dimensió

Dimensió Docker Compose Kubernetes
Model mental Un fitxer, serveis, up/down API declarativa, objectes, controladors, selectors
Corba d'aprenentatge Hores Setmanes, i mesos per operar-lo bé
Abast Un host (o Swarm, amb deploy:) Desenes o milers de nodes
Alta disponibilitat La de l'host: si cau, cau tot Reprograma en un altre node automàticament
Reprogramació davant de caigudes No existeix El Deployment la garanteix
Escalat manual --scale api=4 al mateix host kubectl scale, a tot el clúster
Autoescalat No HPA, VPA i Cluster Autoscaler
Xarxa Bridge amb DNS per nom de servei CNI, Service, NetworkPolicy, malla opcional
Descobriment DNS intern de Docker DNS del clúster + Service estables
Balanceig Round-robin del DNS o un proxy propi Service (L4) + Ingress (L7)
Emmagatzematge Volums locals de l'host PV/PVC, StorageClass, provisió dinàmica
Configuració environment, env_file ConfigMap, muntables o injectables
Secrets Fitxer al disc o secrets: (Swarm) Secret + integració amb gestors externs
Actualitzacions Recrea el contenidor: hi ha tall Rolling update amb maxSurge/maxUnavailable
Rollback Tornar a l'etiqueta anterior a mà kubectl rollout undo, amb historial
Sondes healthcheck (una de sola) Liveness, readiness i startup separades
Observabilitat Logs del daemon, Prometheus si el muntes Mètriques i esdeveniments natius, ecosistema enorme
Extensibilitat Cap de real CRDs, operadors, webhooks
Multitinença No Namespaces, RBAC, quotes
Cost d'infraestructura El d'una VM Pla de control + nodes + marge lliure
Cost operatiu Gairebé zero Alt i permanent
Qui el manté Qualsevol de l'equip Algú que en sàpiga, de guàrdia
Maduresa d'equip necessària Un desenvolupador Almenys una persona amb experiència real

Les tres últimes files decideixen més projectes que totes les anteriors juntes, i són les que menys apareixen a les comparatives d'Internet.

  1. Equivalències conceptuals

Gairebé tot el que vas escriure al compose.yaml d'Aurora Libros té traducció. El que canvia no és la idea, sinó quants objectes calen per expressar-la.

Compose Kubernetes Nota
services: api: Deployment + Service Dos objectes on n'hi havia un
image: spec.containers[].image Idèntic; la mateixa imatge OCI
ports: "8080:8080" Service (intern) o Ingress (extern) L'exposició es parteix en dues capes
environment: ConfigMap + envFrom La configuració surt del descriptor
secrets: / .env Secret (+ gestor extern) Secret és base64, no xifrat per defecte
volumes: (amb nom) PersistentVolumeClaim Amb StorageClass i mode d'accés
volumes: (bind mount) hostPath (evita'l) o ConfigMap muntat Poques vegades és el que vols
deploy.replicas spec.replicas Compose només ho respecta a Swarm
deploy.resources.limits resources.requests / limits K8s distingeix el que demana del que topa
healthcheck: livenessProbe + readinessProbe + startupProbe D'una sonda a tres semàntiques
depends_on: condition: initContainers + readinessProbe No hi ha ordre global; hi ha reintents
restart: unless-stopped restartPolicy: Always (implícit) El Deployment ja ho garanteix
networks: NetworkPolicy A Compose aïlla; a K8s s'ha de declarar
profiles: Overlays de Kustomize Tots dos activen subconjunts
compose.prod.yaml (override) overlays/prod amb pedaços Mateixa idea, mecànica diferent
docker compose up -d kubectl apply -k overlays/prod Un aplica i surt; l'altre deixa controladors

Dues files mereixen un avís. La de depends_on: a Kubernetes no existeix l'arrencada ordenada global; el Pod de l'API arrencarà encara que PostgreSQL no hi sigui, fallarà, i CrashLoopBackOff ho reintentarà fins que la base de dades respongui. És lleig de veure i és el correcte: obliga que l'aplicació toleri que les seves dependències no hi siguin, que és just el que vas aprendre a 06-01. I la de Secret: està codificat en base64, no xifrat; sense xifratge en repòs d'etcd i RBAC ben posat, no és un secret, és un text incòmode de llegir.

  1. El mateix aurora-api, en tots dos formats

Compose, tal com va quedar després del mòdul 4:

# compose.yaml (fragment)
services:
  api:
    image: ghcr.io/auroralibros/aurora-api:2.0.0
    restart: unless-stopped
    environment:
      DB_HOST: aurora-db
      DB_NAME: aurora_llibres
      DB_USER: aurora
      REDIS_URL: redis://aurora-cache:6379
      LOG_LEVEL: info
    secrets: [db_password]
    ports: ["8080:8080"]
    depends_on:
      aurora-db:   { condition: service_healthy }
      aurora-cache: { condition: service_started }
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://localhost:8080/salut/viu')"]
      interval: 10s
      timeout: 3s
      retries: 3
      start_period: 20s
    deploy:
      replicas: 3
      resources:
        limits: { cpus: "1.0", memory: 512M }
    read_only: true
    cap_drop: [ALL]
    security_opt: ["no-new-privileges:true"]

Vint-i-vuit línies. Ara el mateix a Kubernetes, sense retallar res d'essencial:

# k8s/base/api.yaml
apiVersion: v1
kind: ConfigMap
metadata: { name: aurora-config, namespace: aurora }
data:
  DB_HOST: aurora-db
  DB_NAME: aurora_llibres
  DB_USER: aurora
  REDIS_URL: redis://aurora-cache:6379
  LOG_LEVEL: info
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: aurora-api, namespace: aurora }
spec:
  replicas: 3
  selector:
    matchLabels: { app: aurora-api }
  template:
    metadata:
      labels: { app: aurora-api }
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 10001
      containers:
        - name: api
          image: ghcr.io/auroralibros/aurora-api:2.0.0
          ports: [{ containerPort: 8080, name: http }]
          envFrom:
            - configMapRef: { name: aurora-config }
          env:
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef: { name: aurora-secrets, key: db-password }
          resources:
            requests: { cpu: "250m", memory: "256Mi" }
            limits:   { cpu: "1000m", memory: "512Mi" }
          startupProbe:
            httpGet: { path: /salut/viu, port: http }
            failureThreshold: 30
            periodSeconds: 2
          livenessProbe:
            httpGet: { path: /salut/viu, port: http }
            periodSeconds: 10
          readinessProbe:
            httpGet: { path: /salut/preparat, port: http }
            periodSeconds: 5
          securityContext:
            readOnlyRootFilesystem: true
            allowPrivilegeEscalation: false
            capabilities: { drop: [ALL] }
---
apiVersion: v1
kind: Service
metadata: { name: aurora-api, namespace: aurora }
spec:
  selector: { app: aurora-api }
  ports: [{ port: 80, targetPort: http }]
Compose Kubernetes
Línies per al mateix servei 28 63
Objectes declarats 1 3 (ConfigMap, Deployment, Service)
Fitxers en un projecte complet 1 + overrides Desenes, més els overlays
El que hi guanyes — Reprogramació, sondes separades, RBAC, HPA

La proporció de més del doble de YAML no és un detall estètic: es multiplica per cada servei, i amb quatre serveis i tres entorns tens un directori que ja ningú no llegeix sencer. A canvi, cada línia de més compra alguna cosa real. La pregunta és si necessites el que compra.

  1. Arbre de decisió

graph TD
    A["Quant tall toleres?"] -->|"Minuts, sense drama"| B["Més d'un node?"]
    A -->|"Segons o cap"| E["Hi ha algú que sàpiga K8s?"]
    B -->|No| C["Pics de càrrega imprevisibles?"]
    B -->|Sí| E
    C -->|No| D["**Compose en un host**<br/>ben muntat"]
    C -->|Sí| F["Hi cap en un servei<br/>gestionat de contenidors?"]
    F -->|Sí| G["**Cloud Run / Container Apps**<br/>autoescala sense clúster"]
    F -->|No| E
    E -->|"No, i no es pot contractar"| H["**Gestionat o Compose**<br/>mai K8s autogestionat"]
    E -->|Sí| I["Pressupost per a<br/>pla de control + marge?"]
    I -->|No| H
    I -->|Sí| J["**Kubernetes gestionat**<br/>mòdul 6 tal qual"]

Cinc criteris i cap no és «el que es porta». Fixa't que el camí cap a Kubernetes exigeix dos sís seguits —coneixement i pressupost— i que el node H existeix perquè la pitjor decisió possible és un clúster autogestionat que ningú no sap reparar.

  1. El camí intermedi: Compose en producció

Hi ha una idea molt estesa i falsa: que Compose «no és per a producció». Compose en un host ben muntat serveix milions de peticions diàries en empreses reals. El que cal és muntar-lo amb criteri:

# compose.prod.yaml — el que converteix una joguina en producció
services:
  api:
    image: ghcr.io/auroralibros/aurora-api@sha256:9f2c...   # digest, no etiqueta
    restart: unless-stopped                                  # sobreviu al reinici
    logging:
      driver: json-file
      options: { max-size: "10m", max-file: "3" }            # el disc no s'omple
    deploy:
      resources:
        limits: { cpus: "1.0", memory: 512M }                # ningú no es menja l'host
    healthcheck: { test: ["CMD", "node", "healthcheck.js"], interval: 10s }
Requisit de producció Com es compleix amb Compose
Arrencar després de reiniciar l'host restart: unless-stopped + Docker amb systemd
No perdre dades Volum aurora-dades + còpia externa provada
No omplir el disc Rotació de logs + docker system prune programat
Imatge reproduïble Referència per digest, mai :latest
Actualitzar sense tall llarg docker compose up -d --pull always (segons)
Tornada enrere El digest anterior a Git; up -d un altre cop
Vigilància cAdvisor + Prometheus + alertes (05-06)
Còpia de seguretat pg_dump programat a emmagatzematge remot
Certificat TLS Caddy o Traefik al davant, amb renovació automàtica

Els dos buits que no pot tapar: l'host és un punt únic de fallada (si mor la màquina, mor el servei fins que n'arrenquis una altra) i no hi ha autoescalat. Si el negoci tolera aquests dos buits —i moltíssims negocis els toleren—, has resolt la plataforma amb un fitxer, sense pla de control i sense guàrdies.

Una regla honesta de dimensionament: una VM de 4 vCPU i 8 GB amb la pila d'Aurora Libros ben afinada atén amb escreix uns quants centenars de peticions per segon. Abans de donar per fet que necessites un clúster, mesura amb la prova de càrrega de 06-06.

  1. Swarm com a esglaó, i els serveis que executen Compose

Si el problema és només el punt únic de fallada, hi ha un esglaó intermedi abans del salt gros.

Opció Què resol Què costa Estat el 2026
Docker Swarm Diversos nodes, reprogramació, rolling updates Aprendre poc: deploy: al mateix fitxer Mantingut, gairebé sense evolució
Compose + host de reserva Reposar ràpid després d'una caiguda Un procediment manual ben assajat Trivial
ECS amb Compose Executa un compose.yaml a AWS Lligar-se al proveïdor En ús
Cloud Run / Container Apps Autoescalat sense clúster, fins i tot a zero Menys control de xarxa i d'estat Molt madurs
Kubernetes gestionat Tot el del mòdul 6 Cost i coneixement L'estàndard

Swarm (06-03) mereix un paràgraf d'honestedat: és senzill, funciona, i portar el compose.yaml a tres nodes costa afegir deploy: i docker stack deploy. Però el seu ecosistema està congelat, contractar algú que el conegui és més difícil cada any i la documentació de tercers escasseja. Com a esglaó temporal és raonable; com a aposta a cinc anys, pensa-t'ho dues vegades.

Els serveis tipus Cloud Run són la novetat que canvia l'arbre de decisió: autoescalen de zero a centenars d'instàncies sense que existeixi cap clúster a mantenir. Per a ghcr.io/auroralibros/aurora-api:2.0.0 —sense estat, amb sondes, dotze factors i aturada ordenada— encaixen sense tocar res. L'estat se'n va a una base de dades gestionada, i el problema de la disponibilitat deixa de ser teu.

  1. Kompose i els límits reals de la conversió

kompose tradueix un compose.yaml a manifestos de Kubernetes. És útil com a punt de partida i perillós com a resultat final.

kompose convert -f compose.yaml -o k8s/
# INFO Kubernetes file "aurora-api-service.yaml" created
# INFO Kubernetes file "aurora-api-deployment.yaml" created
# WARN Volume mount on the host "./datos" isn't supported - ignoring
# WARN Service "aurora-db" won't be created because 'ports' is not specified
Què converteix bé Què converteix malament o ignora
image, command, ports depends_on (el perd: no hi ha ordre)
environment → variables soltes healthcheck → no genera les tres sondes
deploy.replicas Bind mounts → advertència i pel teu compte
restart → restartPolicy secrets → els deixa com a fitxers o els perd
networks (parcialment) profiles, extends, develop.watch
Cap Ingress, HPA, PDB ni NetworkPolicy

La conclusió pràctica: kompose t'estalvia el primer 60 % del teclejat i no t'estalvia res del pensament. Tot el que fa que un desplegament sigui apte per a producció —sondes separades, requests i limits mesurats, PDB, política de xarxa, Ingress amb TLS— continua sent feina teva. Tracta'l com un esborrany, revisa'l línia a línia i no l'apliquis mai directament contra un clúster real.

  1. El cost ocult de Kubernetes

El que no surt a les presentacions:

Cost Què significa a la pràctica
El clúster Pla de control (gestionat o no) + nodes + marge per reprogramar
Recursos ociosos Necessites capacitat lliure perquè hi càpiguen els Pods d'un node caigut
Actualitzacions Versions noves cada pocs mesos, amb suport limitat i APIs que es retiren
El deute de YAML Desenes de fitxers per entorn; els overlays tapen però no eliminen
Modes de fallada nous CrashLoopBackOff, ImagePullBackOff, Pending per manca de recursos, Evicted per pressió de memòria, PVC que no s'enllaça, DNS del clúster que falla
Depuració més difícil El problema pot ser a l'app, al Pod, al node, al CNI, al CSI o a l'Ingress
Eines al voltant Helm o Kustomize, un GitOps, un gestor de secrets, un sistema de mètriques
Formació contínua L'ecosistema canvia més ràpid del que es consolida el coneixement
Les guàrdies Algú ha de respondre a les tres de la matinada

L'última fila és la que decideix. Formula-la així a la reunió: «si el clúster es trenca un dissabte a les tres de la matinada, qui l'arregla, en quant de temps i cobrant què?». Si no hi ha una resposta amb un nom propi, Kubernetes encara no és una opció, per molt bé que quedi a l'arquitectura.

I convé dir-ho també a l'inrevés: quan la resposta existeix, Kubernetes torna amb escreix el que costa. Autoescalat real, desplegaments sense tall, reprogramació automàtica, quotes per equip i un ecosistema que resol problemes que ni sabies que tenies. L'error no és triar Kubernetes; és triar-lo abans d'hora.

  1. Aurora Libros a tres mides

Botiga petita En creixement Amb pics de campanya
Trànsit 5-20 req/s 100-300 req/s 40 req/s amb pics ×8-15
Equip 2 desenvolupadors 6 persones, 1 amb sistemes 4 desenvolupadors
Guàrdies No Horari laboral No
Tall tolerable 30 min 5 min Zero en campanya
Recomanació Compose en un host Kubernetes gestionat Cloud Run o similar
Per què Un fitxer, zero clúster, cost mínim El trànsit i l'equip ja ho justifiquen Autoescala sense clúster a mantenir
Base de dades Al mateix host, amb còpies provades Gestionada, amb rèplica Gestionada, obligatori
Risc assumit L'host és punt únic de fallada Cost operatiu permanent Dependència del proveïdor
Pas següent Monitoratge i còpies provades PDB, HPA i pressupost d'errors Mesurar el cost per petició en pic

Fixa't en la tercera columna: molt trànsit en pic no implica Kubernetes. Implica autoescalat, i hi ha més d'una manera d'aconseguir-lo. I a la segona, el que inclina la balança no és només el trànsit: és que existeix una persona amb perfil de sistemes. Sense aquella persona, la recomanació seria una altra encara que el trànsit fos el mateix.

Errors Habituals i Consells

  • Triar Kubernetes pel currículum. És una raó real i humana, i és la pitjor de totes per al projecte. Si el vols aprendre, munta un clúster de laboratori amb kind, no la plataforma de producció de l'empresa.
  • Creure que «Compose no és per a producció». Amb digests, límits, rotació de logs, còpies provades i vigilància, Compose sosté negocis reals. El que no dona és tolerància a la caiguda de l'host ni autoescalat.
  • Aplicar la sortida de kompose sense revisar-la. Perd depends_on, no genera les tres sondes ni Ingress, HPA o PDB, i ignora els bind mounts.
  • Migrar a Kubernetes sense haver mesurat. Abans de justificar un clúster per rendiment, executa la prova de càrrega de 06-06 sobre l'host actual. El límit real sol ser a la base de dades, i un clúster no el mou.
  • Traduir depends_on esperant arrencada ordenada. No existeix. L'aplicació ha de reintentar; si no ho fa, arregla-la abans de migrar.
  • Tractar els Secret com a xifrats. Són base64. Sense xifratge en repòs d'etcd i RBAC estricte, no protegeixen res.
  • Consell: escriu la decisió i els seus motius en un document breu dins del repositori, amb data. D'aquí a un any voldràs saber per què es va triar, i si les premisses continuen sent certes.
  • Consell: mantén el compose.yaml viu encara que despleguis a Kubernetes. És la millor manera d'aixecar la pila sencera en local per desenvolupar i depurar.
  • Consell: si dubtes, comença per Compose. Migrar de Compose a Kubernetes amb una imatge ben feta és una feina de dies; desmuntar un clúster que ningú no sap operar costa mesos.

Exercicis

Exercici 1 — Tradueix un servei complet. Pren el servei aurora-cache (redis:7-alpine, sense exposar a l'exterior, amb volum per a la persistència opcional, límit de 256 MB de memòria i un healthcheck amb redis-cli ping) tal com és al compose.yaml. Escriu-lo a Kubernetes: Deployment, Service intern i PersistentVolumeClaim. Indica quin element de l'original no té equivalent directe i com el resols.

Exercici 2 — Aplica l'arbre de decisió. Per a cada escenari, recorre l'arbre de §6, indica el node final i justifica la decisió en tres frases. (a) Una API interna de facturació que fan servir 30 empleats en horari d'oficina, amb un desenvolupador que també fa d'administrador. (b) Una plataforma de venda d'entrades que exhaureix un concert en 90 segons, amb equip de plataforma de cinc persones i guàrdies. (c) Un blog corporatiu amb 400 visites al dia que un proveïdor extern vol desplegar en un clúster gestionat «perquè és l'estàndard».

Exercici 3 — El cost real de la decisió. Aurora Libros creix i la direcció pregunta si «cal passar a Kubernetes». Prepara una comparativa d'una pàgina amb: cost mensual estimat d'infraestructura en tots dos escenaris (fes servir xifres aproximades de proveïdor i explicita els teus supòsits), temps d'aprenentatge i de posada en marxa, quina millora mesurable aporta el clúster, quin risc nou introdueix, i la teva recomanació amb la condició que s'hauria de complir per canviar-la.

Solucions

Solució 1.

apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: aurora-cache-dades, namespace: aurora }
spec:
  accessModes: [ReadWriteOnce]
  resources: { requests: { storage: 1Gi } }
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: aurora-cache, namespace: aurora }
spec:
  replicas: 1
  strategy: { type: Recreate }        # un sol PVC ReadWriteOnce
  selector: { matchLabels: { app: aurora-cache } }
  template:
    metadata: { labels: { app: aurora-cache } }
    spec:
      containers:
        - name: redis
          image: redis:7-alpine
          args: ["--maxmemory", "200mb", "--maxmemory-policy", "allkeys-lru"]
          ports: [{ containerPort: 6379, name: redis }]
          resources:
            requests: { cpu: "50m", memory: "128Mi" }
            limits:   { cpu: "500m", memory: "256Mi" }
          livenessProbe:
            exec: { command: ["redis-cli", "ping"] }
            periodSeconds: 10
          readinessProbe:
            exec: { command: ["redis-cli", "ping"] }
            periodSeconds: 5
          volumeMounts: [{ name: dades, mountPath: /data }]
      volumes:
        - name: dades
          persistentVolumeClaim: { claimName: aurora-cache-dades }
---
apiVersion: v1
kind: Service
metadata: { name: aurora-cache, namespace: aurora }
spec:
  selector: { app: aurora-cache }
  ports: [{ port: 6379, targetPort: redis }]

El que no té equivalent directe és el healthcheck únic de Compose: aquí s'ha desdoblat en liveness i readiness, totes dues amb redis-cli ping però amb períodes diferents, perquè a Kubernetes «està viu» i «pot rebre trànsit» són preguntes separades. Tres decisions més que l'enunciat no donava i que cal raonar: strategy: Recreate en lloc de rolling, perquè un PVC ReadWriteOnce no es pot muntar en dos Pods alhora i el rolling es quedaria bloquejat; el --maxmemory de Redis posat per sota del limits.memory del contenidor, perquè Redis expulsi claus abans que el kernel mati el procés per OOM; i l'absència de ports exposats cap a fora, ja que el Service sense tipus és ClusterIP i només s'hi arriba des de dins del clúster, que és exactament el que es demanava.

Solució 2.

(a) API interna de facturació. Tall tolerable: hores, perquè fora de l'horari d'oficina no hi ha ningú que la faci servir. Un sol node n'hi ha prou i no hi ha pics. Node final: Compose en un host ben muntat. L'únic administrador no pot sostenir un clúster, i un desplegament amb restart: unless-stopped, còpies provades i monitoratge bàsic cobreix el requisit amb escreix. Afegir-hi Kubernetes multiplicaria el cost operatiu sense millorar res perceptible.

(b) Venda d'entrades. El tall tolerable és zero durant els 90 segons que importen, hi ha equip de plataforma i hi ha guàrdies. El pic és brutal però previsible en l'instant, cosa que permet preescalar abans de l'esdeveniment en lloc d'esperar que reaccioni l'HPA. Node final: Kubernetes gestionat. És el cas de llibre: alta disponibilitat real, autoescalat, desplegaments sense tall i un equip que el pot operar. Aquí el clúster torna el que costa.

(c) Blog corporatiu. 400 visites al dia són unes 0,005 peticions per segon de mitjana. El tall tolerable és d'hores. Node final: Compose en un host, o directament allotjament estàtic si el contingut ho permet. Un clúster gestionat per a això costa més al mes del que el mateix blog genera de valor i hi afegeix una dependència que ningú de l'equip no sabrà reparar. Que sigui «l'estàndard» no és un requisit: demana al proveïdor que justifiqui la decisió amb els mateixos criteris de l'arbre i la conversa s'acaba sola.

Solució 3. Estructura de la comparativa (els imports són il·lustratius i s'han de substituir pels del proveïdor i la regió reals):

Concepte Compose en un host Kubernetes gestionat
Còmput 1 VM de 4 vCPU / 8 GB 3 nodes de 2 vCPU / 4 GB + marge
Pla de control 0 Cost fix mensual del proveïdor
Base de dades A l'host (o gestionada) Gestionada, obligatòria a la pràctica
Balancejador i TLS Traefik al mateix host Balancejador del proveïdor, facturat a part
Infraestructura Base Entre 2,5 i 4 vegades la base
Posada en marxa Ja està feta 2-4 setmanes de feina real
Formació 0 1-3 mesos fins a operar amb soltesa
Manteniment Pedaços de l'host Pedaços + actualitzacions de clúster

Millores mesurables del clúster: recuperació automàtica davant de la caiguda d'un node (de «minuts amb intervenció humana» a «segons sense ella»), autoescalat de 3 a 12 rèpliques davant de pics, i desplegaments sense tall amb rollback en una comanda. Riscos nous: dependència d'un coneixement que avui no existeix a l'equip, més superfície de configuració que pot fallar, i cost fix que no baixa quan baixa el trànsit.

Recomanació: continuar amb Compose i revisar la decisió amb un disparador concret, no amb una data. Per exemple: «passem a Kubernetes gestionat quan es compleixin dues d'aquestes tres condicions: superar de manera sostinguda el 60 % de CPU de l'host, que el negoci fixi un objectiu de disponibilitat per damunt del 99,9 %, o que s'incorpori a l'equip una persona amb experiència real operant clústers». Escriure el disparador converteix una discussió d'opinions en una condició verificable, i aquest és el veritable lliurable de l'exercici.

Conclusió

Ja pots defensar la decisió amb criteris en lloc de fer-ho amb modes. Tens clar el primer i el més oblidat: no són la mateixa categoria d'eina. Compose és un descriptor que executes i acaba; Kubernetes guarda la teva intenció a etcd i no deixa de reconciliar-la amb la realitat. D'aquella diferència en surten totes les altres, incloses les bones —reprogramació automàtica, autoescalat, desplegaments sense tall— i les cares.

Tens la comparativa per dimensions, amb les tres files que decideixen més projectes que cap altra: cost d'infraestructura, cost operatiu i maduresa de l'equip. Tens la taula d'equivalències completa, amb els seus dos avisos importants: depends_on no té traducció perquè a Kubernetes no existeix l'arrencada ordenada, i un Secret és base64, no xifrat. I has vist el mateix aurora-api en tots dos formats: 28 línies davant de 63, un objecte davant de tres, amb la pregunta correcta al damunt —necessites el que compren aquelles línies de més?—.

L'arbre de decisió et dona cinc criteris concrets i un detall que convé recordar: arribar a Kubernetes exigeix dos sís seguits, coneixement i pressupost, i la pitjor opció de totes és un clúster autogestionat que ningú no sap reparar. Saps que Compose en producció és una decisió perfectament professional quan l'host està ben muntat —digests, límits, rotació de logs, còpies provades, TLS automàtic—, amb els seus dos buits declarats: punt únic de fallada i absència d'autoescalat. Coneixes els esglaons intermedis: Swarm, honest però congelat; els serveis que executen la teva imatge sense que existeixi cap clúster; i kompose, que t'estalvia el 60 % del teclejat i res del pensament.

I t'endús la pregunta que ordena tota la resta: si el clúster es trenca un dissabte a les tres de la matinada, qui l'arregla, en quant de temps i cobrant què?. Amb les tres versions d'Aurora Libros —la botiga petita amb Compose, la que creix amb Kubernetes gestionat, la de campanya amb autoescalat sense clúster— tens tres respostes de referència i l'hàbit d'escriure la decisió, amb la seva data i el seu disparador de revisió, dins del repositori.

A la lliçó següent baixem de la infraestructura a l'escriptori: Docker Desktop. Què és exactament aquella VM Linux que fas servir sense veure-la, per què explica el rendiment dels bind mounts, quines funcions aporta, quines condicions de llicència té —i per què convé consultar-les abans d'instal·lar-lo a l'empresa— i quines alternatives existeixen a cada sistema operatiu.

Docker: De Principiant a Avançat

Mòdul 1: Introducció a Docker

Mòdul 2: Treballant amb Imatges Docker

Mòdul 3: Contenidors Docker

Mòdul 4: Docker Compose

Mòdul 5: Conceptes Avançats de Docker

Mòdul 6: Docker en Producció

Mòdul 7: Ecosistema i Eines de Docker

© Copyright 2026. Tots els drets reservats