Tanquem el mòdul 9 amb un diagnòstic incòmode: la plataforma Rutas Norte ja sap escalar sola, resistir el pont de maig i protegir-se durant els manteniments, però el directori k8s/ s'ha convertit en més de 120 fitxers YAML duplicats entre dev, pre i pro que algú aplica a mà des del seu portàtil. El mòdul 10 va precisament d'això: de les eines que envolten Kubernetes i que converteixen un munt de manifestos solts en un sistema operable.

Comencem per la baula més propera a l'equip de desenvolupament: el clúster local. Abans de plantillar res amb Helm (10-03), superposar res amb Kustomize (10-04) o reconciliar res amb Argo CD (10-05), cal un lloc barat i llencable on provar els canvis. Al mòdul 1 vam aixecar el clúster de pràctiques amb minikube start --profile=rutas-norte gairebé com un tràmit, i vam dir que hi tornaríem. Ha arribat el moment: en aquesta lliçó anem a fons amb minikube, coneixem kind (l'eina preferida en integració contínua), comparem les cinc alternatives més habituals i, sobretot, aprenem què es pot validar en un clúster local i què no, que és l'arrel del clàssic «a la meva màquina funciona».

Contingut

  1. Per què tot equip necessita un clúster llencable
  2. Minikube a fons: perfils i controladors
  3. Dimensionament, versió de Kubernetes i clústers multinode
  4. El catàleg d'addons
  5. Treballar amb imatges locals sense registre
  6. Accés al clúster: tunnel, service, dashboard, mount i ssh
  7. El cicle de vida: stop, start, delete i logs
  8. kind a fons: nodes com a contenidors
  9. Taula comparativa: minikube, kind, k3d, Docker Desktop i Rancher Desktop
  10. Les diferències amb producció que provoquen «a la meva màquina funciona»
  11. Recepta reproduïble: l'entorn complet de Rutas Norte en local
  12. Errors comuns i consells
  13. Exercicis
  14. Conclusió

  1. Per què tot equip necessita un clúster llencable

A Rutas Norte S.L. hi ha tres entorns reals: rutas-norte-dev, rutas-norte-pre i rutas-norte-pro. Tots tres viuen en clústers compartits. Això vol dir que quan una desenvolupadora vol provar si la seva nova NetworkPolicy trenca la connexió entre api-reserves i postgres-reserves, té dues opcions dolentes:

  • Aplicar-la a rutas-norte-dev i arriscar-se a bloquejar la feina dels altres sis companys que comparteixen aquell namespace.
  • No provar-la i descobrir-ho a pre, amb el cicle d'espera que això implica.

Un clúster local resol el dilema. És seu, gratuït, ràpid de recrear i, si el trenca, minikube delete i tornem a començar en tres minuts.

Què SÍ es pot validar en local

Aspecte Validable en local? Comentari
Sintaxi i validesa dels manifestos Sí, perfectament kubectl apply --dry-run=server ja valida contra l'esquema real
Comportament d'un Deployment, rollout i rollback El controlador és el mateix que en producció
Sondes de liveness/readiness/startup La mateixa lògica del kubelet
ConfigMaps, Secrets i variables d'entorn Idèntic
RBAC: Roles, RoleBindings, ServiceAccounts L'API és la mateixa
Ingress i encaminament per host/ruta Sí, amb l'addon o extraPortMappings Un altre controlador, però les mateixes regles
CRDs i operadors S'instal·len igual
HPA amb mètriques de CPU Sí, amb metrics-server El comportament és realista
Jobs, CronJobs, StatefulSets Idèntic

Què NO es pot validar en local

Aspecte Per què falla On es va estudiar
Balancejador de núvol real (Service LoadBalancer) No hi ha proveïdor de núvol que assigni IP 04-02
Rendiment i latència reals de l'emmagatzematge La StorageClass local és un directori del node 05-04
NetworkPolicies amb el CNI per defecte Molts CNI locals les ignoren silenciosament 04-06
Distribució topològica entre zones Hi ha una sola "zona" fictícia 09-05
Cluster Autoscaler i addició de nodes No hi ha grup de nodes elàstic 09-03
Quotes i pressió real de recursos El teu portàtil no és un node de 64 GB 03-04
Federació d'identitat amb el núvol (IRSA, Workload Identity) No hi ha proveïdor d'identitat 10-06
Latència entre nodes i particions de xarxa Tot corre a la mateixa màquina

La regla pràctica: el clúster local valida la correcció dels teus manifestos i la lògica de la teva aplicació; no valida el rendiment, la topologia ni la integració amb el núvol.

flowchart LR
    A[Portàtil<br/>minikube / kind] -->|valida sintaxi,<br/>lògica, RBAC| B[rutas-norte-dev]
    B -->|valida integració,<br/>dades semblants| C[rutas-norte-pre]
    C -->|valida càrrega,<br/>topologia, cost| D[rutas-norte-pro]
    style A fill:#e8f4ff
    style D fill:#ffe8e8

  1. Minikube a fons: perfils i controladors

minikube és una eina que aixeca un clúster de Kubernetes d'un sol node (o de diversos) dins d'una màquina virtual o un contenidor del teu equip. L'hem fet servir des del mòdul 1; ara entendrem què fa per dins.

Perfils: diversos clústers alhora

Un perfil és un clúster independent amb el seu propi nom, la seva pròpia configuració i el seu propi context de kubectl. És la raó per la qual al mòdul 1 vam escriure --profile=rutas-norte i no simplement minikube start.

# Crear (o arrencar) el clúster del curs
minikube start --profile=rutas-norte

# Crear un segon clúster per provar una versió antiga de Kubernetes
minikube start --profile=rutas-norte-vell --kubernetes-version=v1.28.15

# Veure tots els perfils i el seu estat
minikube profile list

Sortida típica:

|--------------------|-----------|---------|--------------|------|---------|---------|-------|--------|
|      Profile       | VM Driver | Runtime |      IP      | Port | Version | Status  | Nodes | Active |
|--------------------|-----------|---------|--------------|------|---------|---------|-------|--------|
| rutas-norte        | docker    | docker  | 192.168.49.2 | 8443 | v1.30.4 | Running |     3 | *      |
| rutas-norte-vell   | docker    | docker  | 192.168.58.2 | 8443 | v1.28.15| Stopped |     1 |        |
|--------------------|-----------|---------|--------------|------|---------|---------|-------|--------|

Sense --profile, minikube fa servir el perfil minikube. Pots fixar el perfil actiu per no repetir-lo a cada ordre:

minikube profile rutas-norte     # a partir d'aquí, totes les ordres van a aquest perfil
minikube status                  # ja no cal --profile

Consell: fixar el perfil és còmode però perillós, perquè és un estat invisible. Als scripts de l'equip Rutas Norte fem servir sempre --profile=rutas-norte explícit.

Cada perfil crea també el seu context de kubectl amb el mateix nom:

kubectl config get-contexts
kubectl config use-context rutas-norte

Controladors: on viu el node

El controlador (driver) decideix on s'executa el node de minikube. És la decisió més important en començar.

Controlador Plataforma Aïllament Velocitat d'arrencada Notes
docker Linux, macOS, Windows Contenidor Molt ràpida (~40 s) El més usat; el node és un contenidor
podman Linux principalment Contenidor Ràpida Alternativa sense dimoni; una mica menys provada
kvm2 Linux Màquina virtual Mitjana (~90 s) Aïllament real de kernel; ideal si proves coses de kernel
hyperkit macOS Intel Màquina virtual Mitjana Substituït a la pràctica per docker o qemu a Apple Silicon
qemu macOS Apple Silicon, Linux Màquina virtual Lenta Útil quan no hi ha Docker
virtualbox Multiplataforma Màquina virtual Lenta Compatible arreu, però el més lent
none Linux Cap Instantània Instal·la Kubernetes directament a la teva màquina; no el facis servir en un portàtil

Com triar, en tres preguntes:

  1. Tens Docker o Podman funcionant? Fes servir --driver=docker (o podman). És el més ràpid i el que menys memòria consumeix, perquè no hi ha una VM completa pel mig.
  2. Necessites provar mòduls del kernel, un CNI exigent o iptables de debò? Fes servir kvm2 a Linux. Un contenidor comparteix kernel amb l'amfitrió i algunes coses no es poden aïllar.
  3. Estàs a Windows sense WSL2 o en un entorn corporatiu restringit? hyperv o virtualbox són la sortida.
# Elecció explícita del controlador
minikube start --profile=rutas-norte --driver=docker

# Fixar el controlador per defecte per a tots els perfils futurs
minikube config set driver docker

Amb el controlador docker, el node és literalment un contenidor. Pots veure-ho:

docker ps --filter "name=rutas-norte"
CONTAINER ID   IMAGE                                 NAMES
a3f19c2b7d41   gcr.io/k8s-minikube/kicbase:v0.0.45   rutas-norte
8b7e2211ff05   gcr.io/k8s-minikube/kicbase:v0.0.45   rutas-norte-m02

Aquest kicbase és la imatge que conté systemd, containerd, el kubelet i les eines necessàries perquè un contenidor es comporti com un node.

  1. Dimensionament, versió de Kubernetes i clústers multinode

Dimensionament

Per defecte minikube demana 2 CPU i 2 GB de memòria. Per a Rutas Norte això es queda curt tan bon punt instal·lem Prometheus (07-03) i cert-manager (04-05):

minikube start \
  --profile=rutas-norte \
  --driver=docker \
  --cpus=4 \
  --memory=8192 \
  --disk-size=40g

Explicació de cada opció:

  • --cpus=4: nombre de CPU virtuals assignades al node. Amb menys de 4, el kube-apiserver i Prometheus competeixen i el clúster es percep lent.
  • --memory=8192: memòria en MiB (8 GB). També pots escriure 8g. Compte: aquesta memòria es reserva davant del teu sistema; si el teu portàtil té 16 GB, no li'n donis 12.
  • --disk-size=40g: mida del disc del node. Les imatges de contenidor s'acumulen ràpid; 20 GB s'esgoten en un parell de setmanes de feina real.

Aquests valors es recorden per perfil. Si demà executes minikube start --profile=rutas-norte sense flags, respecta el que ja vas configurar. Per canviar-los cal esborrar i recrear el perfil (o fer servir minikube config set abans).

Un advertiment important: --cpus i --memory no es poden canviar en calent amb el controlador de VM. Si et quedes curt, minikube delete --profile=rutas-norte i torna a crear-lo amb els valors nous. Per això convé tenir l'script de creació versionat (apartat 11).

Fixar la versió de Kubernetes

Aquesta és una de les pràctiques més rendibles i més oblidades. Si rutas-norte-pro corre Kubernetes 1.30 i el teu minikube corre 1.32, pots escriure manifestos que funcionen al teu portàtil i són rebutjats en producció, o al revés: pots no detectar una API obsoleta.

minikube start --profile=rutas-norte --kubernetes-version=v1.30.4
# Comprovar quines versions concretes coneix el teu minikube
minikube start --help | grep -A2 kubernetes-version
kubectl version

Sortida:

Client Version: v1.30.4
Server Version: v1.30.4

Regla de l'equip de plataforma de Rutas Norte: el fitxer de l'script d'arrencada local declara la mateixa versió menor que producció. Quan pro puja de versió, l'script s'actualitza en el mateix canvi.

Clústers multinode

Un sol node no permet provar res relacionat amb la planificació: afinitats (06-05), topologySpreadConstraints (09-05), DaemonSets amb diversos objectius (06-02) o el drenatge d'un node. minikube en sap crear diversos:

minikube start \
  --profile=rutas-norte \
  --nodes=3 \
  --cpus=2 \
  --memory=4096 \
  --kubernetes-version=v1.30.4
kubectl get nodes -o wide
NAME             STATUS   ROLES           AGE   VERSION
rutas-norte      Ready    control-plane   3m    v1.30.4
rutas-norte-m02  Ready    <none>          2m    v1.30.4
rutas-norte-m03  Ready    <none>          2m    v1.30.4

Fixa't que --cpus i --memory s'apliquen per node: tres nodes de 2 CPU i 4 GB consumeixen 6 CPU i 12 GB de l'amfitrió. És fàcil ofegar el portàtil sense adonar-se'n.

Pots afegir o treure nodes després:

minikube node add --profile=rutas-norte
minikube node delete rutas-norte-m03 --profile=rutas-norte

I etiquetar els nodes per simular zones i provar la distribució topològica de 09-05:

kubectl label node rutas-norte-m02 topology.kubernetes.io/zone=zona-a
kubectl label node rutas-norte-m03 topology.kubernetes.io/zone=zona-b

Això és una simulació útil per verificar que el selector funciona, però recorda: continuen estant a la mateixa màquina física, així que no prova la tolerància real a la caiguda d'una zona.

  1. El catàleg d'addons

Els addons són components preempaquetats que minikube sap instal·lar i mantenir per tu. És el que evita haver d'aplicar a mà els manifestos del controlador d'Ingress o del metrics-server.

minikube addons list --profile=rutas-norte
|-----------------------------|--------------|--------------|
|         ADDON NAME          |    PROFILE   |    STATUS    |
|-----------------------------|--------------|--------------|
| csi-hostpath-driver         | rutas-norte  | disabled     |
| dashboard                   | rutas-norte  | disabled     |
| default-storageclass        | rutas-norte  | enabled ✅   |
| ingress                     | rutas-norte  | enabled ✅   |
| metrics-server              | rutas-norte  | enabled ✅   |
| registry                    | rutas-norte  | disabled     |
| storage-provisioner         | rutas-norte  | enabled ✅   |
| volumesnapshots             | rutas-norte  | disabled     |
|-----------------------------|--------------|--------------|

Els que fa servir aquest curs i per què:

Addon Per a què el fem servir Lliçó
ingress Desplega ingress-nginx per a les regles de www.rutasnorte.example 04-04
metrics-server Dona dades a kubectl top i a l'HPA 07-02, 09-01
storage-provisioner Aprovisiona PVs dinàmicament per a postgres-reserves 05-05
default-storageclass Marca standard com a StorageClass per defecte 05-04
csi-hostpath-driver + volumesnapshots Necessaris per practicar els snapshots CSI 05-05
dashboard Interfície web d'exploració aquesta lliçó
registry Registre d'imatges dins del clúster aquesta lliçó
# Activar els del curs
minikube addons enable ingress --profile=rutas-norte
minikube addons enable metrics-server --profile=rutas-norte
minikube addons enable csi-hostpath-driver --profile=rutas-norte
minikube addons enable volumesnapshots --profile=rutas-norte

# Desactivar un que consumeix recursos i no estàs fent servir
minikube addons disable dashboard --profile=rutas-norte

Cada addon és, per dins, un conjunt de manifestos que minikube aplica al namespace kube-system (o a un de propi). Pots veure'ls:

kubectl get pods -n ingress-nginx
kubectl get deploy metrics-server -n kube-system

Avís important: l'addon ingress de minikube instal·la ingress-nginx amb una configuració pensada per a un sol node. En producció, el teu equip de plataforma probablement l'instal·la amb Helm i amb valors molt diferents (rèpliques, PDB, recursos). El comportament de les regles és el mateix; el de la disponibilitat, no.

  1. Treballar amb imatges locals sense registre

Aquest és, a la pràctica diària, el punt on més temps es perd. Has construït api-reserves:dev-local al teu portàtil i el pod es queda a ImagePullBackOff, perquè el node de minikube té el seu propi magatzem d'imatges, separat del Docker de la teva màquina.

Hi ha tres maneres de resoldre-ho.

Opció A: minikube image load (la més simple i recomanable)

# 1. Construeixes la imatge a la teva màquina, com sempre
docker build -t registry.rutasnorte.example/api-reserves:dev-local ./api-reserves

# 2. La copies al magatzem del node de minikube
minikube image load registry.rutasnorte.example/api-reserves:dev-local --profile=rutas-norte

# 3. Comproves que hi és
minikube image ls --profile=rutas-norte | grep api-reserves

Al manifest, la clau és evitar que Kubernetes intenti descarregar-la del registre:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-reserves
  namespace: rutas-norte-dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api-reserves
  template:
    metadata:
      labels:
        app: api-reserves
        app.kubernetes.io/part-of: rutas-norte
    spec:
      containers:
        - name: api
          image: registry.rutasnorte.example/api-reserves:dev-local
          # CLAU: amb IfNotPresent, el kubelet fa servir la imatge local
          # i no intenta contactar amb el registre.
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080

Parany clàssic: si l'etiqueta de la imatge és latest, Kubernetes aplica per defecte imagePullPolicy: Always i sempre intentarà descarregar-la, ignorant la còpia local. No facis servir mai latest (ja ho vam veure a 08-05); aquí a més et trenca el flux local.

Si hi ha diversos nodes, image load la copia a tots automàticament.

Opció B: minikube docker-env (construir dins del node)

Aquesta opció reapunta el teu client Docker al dimoni que corre dins del node de minikube. El que construeixis queda directament disponible per al kubelet, sense pas de còpia.

# Veure què fa exactament
minikube docker-env --profile=rutas-norte
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.49.2:2376"
export DOCKER_CERT_PATH="/home/usuari/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="rutas-norte"
# Aplicar-ho a la sessió actual del terminal
eval $(minikube docker-env --profile=rutas-norte)

# A partir d'aquí, docker build construeix DINS del node
docker build -t registry.rutasnorte.example/api-reserves:dev-local ./api-reserves

# Desfer-ho quan acabis
eval $(minikube docker-env --unset --profile=rutas-norte)

Avantatge: és més ràpid al bucle editar-construir-provar, perquè no hi ha còpia. Desavantatge: només funciona amb el runtime docker; si el perfil fa servir containerd, no s'aplica. I és un estat del terminal fàcil d'oblidar (has construït dins del node i després no trobes la imatge a la teva màquina).

Opció C: l'addon registry

minikube addons enable registry --profile=rutas-norte

Aixeca un registre dins del clúster. És l'opció més semblant a producció, però també la que més passos exigeix (cal empènyer la imatge, resoldre el nom des del node). Per a la feina diària, l'opció A guanya gairebé sempre.

Opció Velocitat del bucle Complexitat Quan fer-la servir
image load Mitjana (còpia cada vegada) Molt baixa Ús general, multinode
docker-env Alta Baixa, però amb estat ocult Iteració intensiva en un sol node amb runtime docker
Addon registry Baixa Alta Quan vols reproduir el flux real de registre

  1. Accés al clúster: tunnel, service, dashboard, mount i ssh

minikube tunnel: Services de tipus LoadBalancer

Quan declares un Service de tipus LoadBalancer (04-02), Kubernetes demana a un controlador del proveïdor de núvol que aprovisioni un balancejador. Al teu portàtil no hi ha proveïdor de núvol, així que el Service es queda per sempre a <pending>:

kubectl get svc botiga-web -n rutas-norte-dev
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
botiga-web   LoadBalancer   10.104.12.201   <pending>     80:31820/TCP   2m

minikube tunnel simula aquest balancejador: crea rutes a la teva màquina i assigna una IP externa.

# Executar en un terminal A PART i deixar-lo obert.
# Demana contrasenya d'administrador perquè crea rutes de xarxa.
minikube tunnel --profile=rutas-norte
Status:
	machine: rutas-norte
	pid: 48211
	route: 10.96.0.0/12 -> 192.168.49.2
	minikube: Running
	services: [botiga-web]

Ara, en un altre terminal:

kubectl get svc botiga-web -n rutas-norte-dev
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
botiga-web   LoadBalancer   10.104.12.201   10.104.12.201   80:31820/TCP   5m

Punts que confonen tothom la primera vegada:

  • El procés ha de seguir viu. Si tanques el terminal, la IP torna a <pending>.
  • No és un balancejador real: no hi ha comprovacions de salut del proveïdor, ni distribució entre zones, ni regles de tallafocs de núvol. Només encamina.
  • A macOS i Windows amb el controlador docker, tunnel també és necessari per arribar a l'Ingress.

minikube service: obrir un Service al navegador

Per a Services de tipus NodePort (o fins i tot ClusterIP amb --url), aquesta és la via ràpida:

# Obre el navegador apuntant al servei
minikube service botiga-web -n rutas-norte-dev --profile=rutas-norte

# Només imprimir l'URL, sense obrir navegador (útil en scripts)
minikube service botiga-web -n rutas-norte-dev --url --profile=rutas-norte
http://192.168.49.2:31820

minikube dashboard: la interfície web

minikube dashboard --profile=rutas-norte
minikube dashboard --url --profile=rutas-norte   # només l'URL

Activa l'addon dashboard si no ho estava, aixeca un proxy i obre el navegador. Útil per explorar visualment el clúster mentre aprens; en el dia a dia professional kubectl i k9s són més ràpids.

minikube mount: compartir un directori de l'amfitrió

De vegades vols que el pod vegi un directori del teu portàtil: un bolcat SQL de dades de prova per a postgres-reserves, o els fitxers estàtics de botiga-web.

# Terminal a part, es queda en primer pla
minikube mount ~/rutas-norte/dades-prova:/dades-prova --profile=rutas-norte

Al pod es fa servir un hostPath (05-01) apuntant a /dades-prova, que ara existeix dins del node:

      volumes:
        - name: dades
          hostPath:
            path: /dades-prova
            type: Directory

Advertiment: hostPath està prohibit per les Pod Security Standards del nivell restricted (08-03). En local és acceptable per a dades de prova; a rutas-norte-pro seria rebutjat, i amb raó.

minikube ssh: entrar al node

minikube ssh --profile=rutas-norte

Et deixa dins del node. Útil per a:

# Veure l'espai en disc del node quan hi ha problemes d'eviction
df -h /var

# Veure les imatges que té el runtime
sudo crictl images

# Veure els pods estàtics del pla de control (hi tornarem a 10-02)
ls /etc/kubernetes/manifests

# Sortir
exit

En un clúster multinode, tria el node:

minikube ssh --node=rutas-norte-m02 --profile=rutas-norte

  1. El cicle de vida: stop, start, delete i logs

# Apagar el clúster conservant-ho tot (objectes, imatges, dades dels PV)
minikube stop --profile=rutas-norte

# Tornar a arrencar-lo tal com estava
minikube start --profile=rutas-norte

# Estat actual
minikube status --profile=rutas-norte
rutas-norte
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
# Esborrar el clúster (irreversible: es perden objectes, PVs i imatges)
minikube delete --profile=rutas-norte

# Esborrar TOTS els perfils de cop (neteja total)
minikube delete --all --purge

--purge esborra a més el directori ~/.minikube amb la configuració i la memòria cau d'imatges de Kubernetes. Fes-lo servir quan minikube estigui en un estat estrany que no aconsegueixes explicar; és l'equivalent a apagar i encendre.

Diagnòstic amb logs

Quan minikube start falla o el clúster arrenca a mitges:

minikube logs --profile=rutas-norte

# Només els problemes detectats, molt més llegible
minikube logs --problems --profile=rutas-norte

# Seguir en directe
minikube logs -f --profile=rutas-norte
==> Audit <==
==> kubelet <==
Sep 12 09:14:02 rutas-norte kubelet[2311]: E0912 09:14:02.118 Failed to
  create pod sandbox: rpc error: code = Unknown desc = failed to set up
  sandbox network: plugin type="bridge" failed

Aquest tipus de missatge gairebé sempre significa que el node es va quedar sense recursos o que l'estat de xarxa del contenidor va quedar corrupte després d'una aturada brusca. minikube delete && minikube start ho resol, i és exactament per això que un clúster local ha de ser llencable.

  1. kind a fons: nodes com a contenidors

kind (Kubernetes IN Docker) té un enfocament diferent i una filosofia més estreta: cada node del clúster és un contenidor de Docker que executa containerd i el kubelet. No hi ha addons, no hi ha tunnel, no hi ha dashboard. Només Kubernetes, molt ràpid i molt reproduïble.

Precisament per aquesta austeritat, és l'eina que el mateix projecte Kubernetes fa servir per a les seves proves i l'elecció habitual en integració contínua.

Un clúster mínim

kind create cluster --name rutas-norte
Creating cluster "rutas-norte" ...
 ✓ Ensuring node image (kindest/node:v1.30.4) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-rutas-norte"

Triga uns 25 segons. El context es diu kind-rutas-norte (amb el prefix kind-).

Fitxer de configuració: diversos nodes, ports i muntatges

Aquí hi ha la veritable potència de kind: el clúster es declara en un fitxer versionable.

# k8s/local/kind-rutas-norte.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: rutas-norte

# Igualem la xarxa de pods a la de producció perquè les
# NetworkPolicies amb blocs CIDR es comportin igual.
networking:
  podSubnet: "10.244.0.0/16"
  serviceSubnet: "10.96.0.0/16"
  # Desactivem el CNI per defecte per instal·lar Calico i així
  # PODER provar de debò les NetworkPolicies de 04-06.
  disableDefaultCNI: false

nodes:
  # --- Pla de control ---
  - role: control-plane
    image: kindest/node:v1.30.4
    # Publiquem els ports 80 i 443 del contenidor al portàtil,
    # perquè l'Ingress sigui accessible a http://localhost sense tunnel.
    extraPortMappings:
      - containerPort: 80
        hostPort: 80
        protocol: TCP
      - containerPort: 443
        hostPort: 443
        protocol: TCP
    # Etiqueta que exigeix el controlador d'ingress-nginx per a kind.
    kubeadmConfigPatches:
      - |
        kind: InitConfiguration
        nodeRegistration:
          kubeletExtraArgs:
            node-labels: "ingress-ready=true"

  # --- Nodes de treball, etiquetats com a zones diferents ---
  - role: worker
    image: kindest/node:v1.30.4
    labels:
      topology.kubernetes.io/zone: zona-a
    # Muntem un directori del portàtil dins del node.
    extraMounts:
      - hostPath: /home/usuari/rutas-norte/dades-prova
        containerPath: /dades-prova
        readOnly: true

  - role: worker
    image: kindest/node:v1.30.4
    labels:
      topology.kubernetes.io/zone: zona-b
kind create cluster --config k8s/local/kind-rutas-norte.yaml
kubectl get nodes
NAME                        STATUS   ROLES           AGE   VERSION
rutas-norte-control-plane   Ready    control-plane   47s   v1.30.4
rutas-norte-worker          Ready    <none>          32s   v1.30.4
rutas-norte-worker2         Ready    <none>          32s   v1.30.4

Repassem els camps clau:

  • extraPortMappings: publica un port del contenidor-node a la teva màquina. És la solució de kind al problema de l'accés extern. Amb hostPort: 80, un cop instal·lat ingress-nginx, curl -H "Host: www.rutasnorte.example" http://localhost arriba a botiga-web. Només es pot definir en crear el clúster: si l'oblides, cal recrear-lo.
  • extraMounts: l'equivalent a minikube mount, però declaratiu i sense procés en primer pla. Molt més còmode.
  • kubeadmConfigPatches: kind fa servir kubeadm per dins (ho veurem a 10-02). Aquest camp et deixa modificar-ne la configuració; aquí el fem servir per posar l'etiqueta ingress-ready=true que el manifest d'ingress-nginx per a kind espera al seu nodeSelector.
  • image: fixa la versió de Kubernetes. Igual que amb minikube, iguala-la a producció.
  • labels: etiquetes de node aplicades des del principi, sense kubectl label posterior.

Instal·lar l'Ingress a kind

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=120s

Ara sí:

curl -H "Host: www.rutasnorte.example" http://localhost/

Carregar imatges locals

docker build -t registry.rutasnorte.example/api-reserves:dev-local ./api-reserves
kind load docker-image registry.rutasnorte.example/api-reserves:dev-local --name rutas-norte

Igual que a minikube, la imatge es copia a tots els nodes. I també aquí cal imagePullPolicy: IfNotPresent i evitar l'etiqueta latest.

També pots carregar un fitxer d'imatge exportat, pràctic en canalitzacions on la construcció i la càrrega estan en passos diferents:

docker save registry.rutasnorte.example/api-reserves:dev-local -o api.tar
kind load image-archive api.tar --name rutas-norte

Per què kind mana en integració contínua

Motiu Explicació
Velocitat 25-40 s davant dels 60-120 s de minikube; en una canalització que corre 40 vegades al dia, això són hores
Sense virtualització imbricada En ser contenidors, funciona en corredors de CI que no permeten KVM
Configuració en un fitxer El clúster és reproduïble bit a bit des del repositori
Multinode barat Afegir un node és afegir un contenidor
Neteja total kind delete cluster no deixa rastre
Sense estat ocult No hi ha perfils persistents ni configuració recordada entre execucions

Un pas típic a la canalització ci-rutasnorte es redueix a: kind create cluster --config kind-ci.yaml --wait 120s, construir i carregar la imatge, kubectl apply -k k8s/entorns/dev (això és Kustomize, ho veurem a 10-04), esperar el rollout, executar les proves de fum i kind delete cluster al final passi el que passi.

  1. Taula comparativa: minikube, kind, k3d, Docker Desktop i Rancher Desktop

Criteri minikube kind k3d Docker Desktop Rancher Desktop
Què és Clúster local amb addons Nodes com a contenidors k3s en contenidors Kubernetes integrat a l'app App d'escriptori amb k3s
Arrencada (1 node) 60-120 s 25-40 s 15-25 s ~90 s (en activar-lo) ~60 s
Multinode Sí (--nodes) Sí (fitxer) Sí (--agents) No No
Consum en repòs Mitjà-alt Mitjà Baix Alt Mitjà
Addons integrats Molts (ingress, metrics, CSI, registre) Cap Traefik i servidor local inclosos Cap Traefik inclòs
Configuració en fitxer Parcial (flags + config set) Completa i versionable Completa i versionable No Parcial
Idoneïtat per a CI Regular (lent, requereix driver) Excel·lent Excel·lent Nul·la Baixa
Fidelitat amb Kubernetes estàndard Alta Molt alta (kubeadm real) Mitjana (k3s retalla components) Alta Mitjana (k3s)
Registre local integrat Addon registry No (es munta a part) Sí (k3d registry) Comparteix el de Docker Comparteix el seu
Llicència comercial Lliure Lliure Lliure De pagament en empreses grans Lliure
Millor per a Aprendre i feina diària amb extres CI i proves reproduïbles Bucles ultraràpids, equips petits Qui ja el té i no vol més eines Substitut lliure de Docker Desktop

Notes per triar:

  • k3s (el motor de k3d i Rancher Desktop) és una distribució lleugera i conforme, però substitueix algunes peces: fa servir Traefik com a Ingress, SQLite en comptes d'etcd per defecte i desactiva components de núvol. És perfecte per desenvolupar; és enganyós si vols comprovar un comportament fi del pla de control.
  • Docker Desktop amb Kubernetes activat és el més còmode si ja el tens, però és un sol node, no configurable, i la seva llicència és de pagament per a empreses per sobre de certa mida. Rutas Norte S.L. és petita, així que no l'afecta, però és un factor real en decisions d'equip.
  • La recomanació d'aquest curs: minikube per a la feina diària (pels addons, que estalvien molta instal·lació manual) i kind a la canalització ci-rutasnorte (per velocitat i reproduïbilitat). Que siguin dues eines diferents no és un problema si el manifest que desplegues és el mateix.

  1. Les diferències amb producció que provoquen «a la meva màquina funciona»

Aquest apartat és el més important de la lliçó. Cada punt és un incident real esperant a passar.

10.1 No hi ha balancejador de núvol

En local, type: LoadBalancer no fa res sense minikube tunnel. A rutas-norte-pro, aquest mateix Service aprovisiona un balancejador de veritat, amb la seva IP pública, el seu cost mensual i el seu temps d'aprovisionament de diversos minuts.

Conseqüències que només veus al núvol: anotacions específiques del proveïdor (tipus de balancejador, certificats, llistes d'accés), comprovacions de salut pròpies, i el fet que esborrar el Service esborra el balancejador. Ho veurem a 10-06.

Mitigació: en local, fes servir Ingress (04-04) i no LoadBalancer als manifestos de l'aplicació. Deixa el LoadBalancer només per al controlador d'Ingress, que en local es publica per NodePort o extraPortMappings.

10.2 La classe d'emmagatzematge és una altra

A minikube, la StorageClass standard és un directori del node servit per storage-provisioner. A rutas-norte-pro, postgres-reserves fa servir una StorageClass de disc de xarxa amb IOPS provisionades (05-04).

Diferència Local Producció
Mode d'accés ReadWriteOnce, però amb un node tot "funciona" ReadWriteOnce de debò: dos pods en nodes diferents fallen
Rendiment L'SSD del teu portàtil Disc de xarxa, amb latència i límits
Expansió i snapshots Pot no estar suportada Sí, natius del proveïdor
Vinculació Immediata Freqüentment WaitForFirstConsumer

Aquest últim punt és traïdor: en producció el PV no es crea fins que el pod es planifica, i això canvia l'ordre dels esdeveniments. Un StatefulSet que arrenca bé en local pot quedar-se a Pending al núvol per una afinitat de zona incompatible.

10.3 El CNI per defecte pot ignorar les NetworkPolicies

Aquest és el més perillós perquè falla en silenci. Escrius una NetworkPolicy que aïlla postgres-reserves perquè només api-reserves hi pugui parlar (04-06), l'apliques al teu minikube, l'objecte es crea sense error... i no fa absolutament res, perquè el CNI per defecte no la implementa.

kubectl apply -f k8s/base/netpol-postgres.yaml
networkpolicy.networking.k8s.io/postgres-nomes-api created

Sembla que funciona. Però:

# Des d'un pod que NO hauria de poder connectar
kubectl run curiosa --rm -it --image=busybox:1.36 -n rutas-norte-dev -- \
  nc -zv postgres-reserves 5432
postgres-reserves (10.104.55.12:5432) open

Connecta. La política es va ignorar.

Com detectar-ho: kubectl get pods -n kube-system -o wide | grep -Ei 'calico|cilium|flannel|kindnet'. kindnet (el de kind per defecte) i el bridge bàsic no implementen NetworkPolicies; calico i cilium sí.

Mitigació: a minikube, --cni=calico. A kind, disableDefaultCNI: true amb podSubnet: "192.168.0.0/16" i aplicar després el manifest de Calico.

I la regla d'or: una NetworkPolicy no està provada fins que has verificat que una cosa que abans connectava, ara no connecta. Provar només que el que està permès continua funcionant no demostra res.

10.4 No hi ha diverses zones ni escalat de nodes

topologySpreadConstraints (09-05) amb topologyKey: topology.kubernetes.io/zone en un clúster d'un node se satisfà trivialment. Etiquetar els nodes d'un clúster multinode simula zones i verifica que el selector i les etiquetes són correctes, però no prova la tolerància a fallades.

Igual amb el Cluster Autoscaler (09-03): en local no hi ha grup de nodes elàstic, així que un pod Pending per falta de recursos es queda Pending per sempre. En producció apareixeria un node nou en dos minuts. El símptoma en local és idèntic a una fallada greu en producció, cosa que despista.

10.5 Resum de mitigacions

Risc Mitigació en local Prova definitiva
Balancejador absent Fes servir Ingress; minikube tunnel si cal rutas-norte-pre
StorageClass diferent Anomena la classe al manifest, no confiïs en la de per defecte rutas-norte-pre
NetworkPolicies ignorades Instal·la Calico o Cilium en local rutas-norte-pre amb prova negativa
Topologia i zones Etiqueta nodes per validar selectors rutas-norte-pro
Escalat de nodes No simulable rutas-norte-pre
Recursos i límits Ajusta límits baixos a propòsit per veure què s'estrangula Proves de càrrega amb k6 (09-06)

  1. Recepta reproduïble: l'entorn complet de Rutas Norte en local

El pitjor d'un entorn local és que cada persona de l'equip el tingui diferent. La solució és un script versionat al repositori, al costat dels manifestos.

#!/usr/bin/env bash
# k8s/local/aixecar-local.sh
# Aixeca l'entorn local complet de Rutas Norte sobre minikube.
# Ús:  ./aixecar-local.sh           (crea i configura)
#      ./aixecar-local.sh esborrar  (destrueix el perfil)

set -euo pipefail

PERFIL="rutas-norte"
# Ha de coincidir amb la versió menor de rutas-norte-pro.
VERSIO_K8S="v1.30.4"
NODES=3
CPUS=2
MEMORIA=4096
DISC="30g"

if [[ "${1:-}" == "esborrar" ]]; then
  echo "==> Esborrant el perfil ${PERFIL}"
  minikube delete --profile="${PERFIL}"
  exit 0
fi

echo "==> 1/6 Creant el clúster ${PERFIL} (Kubernetes ${VERSIO_K8S})"
minikube start \
  --profile="${PERFIL}" \
  --driver=docker \
  --kubernetes-version="${VERSIO_K8S}" \
  --nodes="${NODES}" \
  --cpus="${CPUS}" \
  --memory="${MEMORIA}" \
  --disk-size="${DISC}" \
  --cni=calico          # imprescindible perquè les NetworkPolicies s'apliquin

echo "==> 2/6 Activant addons"
for addon in ingress metrics-server csi-hostpath-driver volumesnapshots; do
  minikube addons enable "${addon}" --profile="${PERFIL}"
done

echo "==> 3/6 Etiquetant nodes com a zones simulades"
kubectl label node "${PERFIL}-m02" topology.kubernetes.io/zone=zona-a --overwrite
kubectl label node "${PERFIL}-m03" topology.kubernetes.io/zone=zona-b --overwrite

echo "==> 4/6 Creant el namespace de desenvolupament"
kubectl create namespace rutas-norte-dev --dry-run=client -o yaml | kubectl apply -f -
kubectl label namespace rutas-norte-dev \
  app.kubernetes.io/part-of=rutas-norte entorn=dev --overwrite

echo "==> 5/6 Construint i carregant les imatges locals"
for comp in botiga-web api-reserves worker-notificacions; do
  docker build -t "registry.rutasnorte.example/${comp}:dev-local" "./${comp}"
  minikube image load "registry.rutasnorte.example/${comp}:dev-local" --profile="${PERFIL}"
done

echo "==> 6/6 Esperant que el controlador d'Ingress estigui llest"
kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=180s

echo
echo "Clúster llest. Per arribar a l'Ingress:"
echo "  echo \"\$(minikube ip --profile=${PERFIL}) www.rutasnorte.example api.rutasnorte.example\" | sudo tee -a /etc/hosts"
echo "Desplega l'aplicació amb:  kubectl apply -k k8s/entorns/dev"

Explicació de les decisions de l'script:

  • set -euo pipefail: avorta a la primera ordre que falli, en comptes de continuar deixant un clúster a mitges.
  • Versió de Kubernetes en una variable a dalt: quan pro puja de versió, es canvia una línia.
  • --cni=calico: la diferència entre provar de debò les NetworkPolicies i enganyar-se.
  • --dry-run=client -o yaml | kubectl apply -f -: el patró idempotent de 01-06; crea el namespace si no existeix i no falla si ja existeix.
  • kubectl wait: l'script no acaba fins que el clúster és realment usable. Sense això, qui l'executa prova de desplegar i falla perquè l'Ingress encara no hi és.
  • L'avís final sobre /etc/hosts: els dominis www.rutasnorte.example i api.rutasnorte.example no existeixen en cap DNS; cal resoldre'ls a mà contra la IP del node.

L'equivalent amb kind és encara més curt, perquè tota la configuració del clúster ja és a kind-rutas-norte.yaml: n'hi ha prou amb kind create cluster --config ... --wait 180s, aplicar Calico i ingress-nginx, esperar el controlador i carregar les imatges amb kind load docker-image. I no cal tocar /etc/hosts: gràcies a extraPortMappings, l'Ingress respon a http://localhost amb la capçalera Host adequada.

Errors Comuns i Consells

1. Donar a minikube gairebé tota la memòria del portàtil. Amb 16 GB físics, --memory=12288 deixa el sistema operatiu sense marge i tot va a batzegades. Regla: no més de la meitat de la RAM física, i recorda que en multinode el valor es multiplica pel nombre de nodes.

2. Oblidar que --cpus i --memory queden gravats al perfil. Executes minikube start --profile=rutas-norte --memory=8192 un dia, i l'endemà minikube start --profile=rutas-norte sense flags: continua fent servir 8192. Si creus que vas canviar el valor i no va canviar res, és això. Per canviar-ho cal recrear el perfil.

3. ImagePullBackOff amb una imatge que "sí que has construït". Gairebé sempre són dues causes: no vas fer minikube image load / kind load docker-image, o l'etiqueta és latest i l'imagePullPolicy implícit és Always. Fes servir etiquetes explícites (dev-local) i imagePullPolicy: IfNotPresent.

4. Creure que una NetworkPolicy aplicada està funcionant. Comprova sempre el CNI i fes la prova negativa: intenta la connexió que ha d'estar bloquejada i verifica que dona timeout. Sense aquesta prova, no has provat res.

5. Tancar el terminal de minikube tunnel o minikube mount. Tots dos són processos en primer pla. Si desapareix la IP externa o el directori muntat, mira si el procés continua viu abans de buscar causes exòtiques.

6. Descobrir tard que faltava un extraPortMapping a kind. No es poden afegir a un clúster ja creat. Tingues el fitxer de configuració amb els ports 80, 443 i potser algun més des del principi.

7. Fer servir latest de la imatge del node. Tant kindest/node com la versió de minikube han d'estar fixades. Un company amb v1.31 i tu amb v1.29 produïu resultats diferents sobre els mateixos manifestos.

8. Acumular perfils oblidats. Cada perfil aturat continua ocupant disc. minikube profile list de tant en tant i minikube delete --profile=X del que no facis servir.

9. Tractar el clúster local com si fos valuós. Si dubtes que alguna cosa estigui en un estat estrany, esborra'l i recrea'l. L'script de l'apartat 11 fa que això costi tres minuts; investigar un estat corrupte costa una tarda.

10. Provar el rendiment en local. Un benchmark de postgres-reserves al teu SSD no diu res del disc de xarxa de producció. Per a això hi ha rutas-norte-pre i k6 (09-06).

Exercicis

Exercici 1: clúster multinode amb zones simulades

Crea un perfil de minikube anomenat rutas-norte-topologia amb 3 nodes, Kubernetes v1.30.4 i Calico com a CNI. Etiqueta els dos nodes de treball com a zona-a i zona-b. Desplega api-reserves amb 4 rèpliques i un topologySpreadConstraint que reparteixi entre zones amb maxSkew: 1, i comprova amb kubectl get pods -o wide que el repartiment és 2 i 2.

Exercici 2: demostrar que el CNI importa

Crea dos clústers de kind: un amb el CNI per defecte (kindnet) i un altre amb disableDefaultCNI: true i Calico instal·lat. En tots dos, aplica una NetworkPolicy de denegació total d'entrada al namespace rutas-norte-dev i comprova, amb un pod busybox intentant connectar a un Service, quin dels dos la respecta de debò.

Exercici 3: bucle de desenvolupament amb imatge local

Amb el perfil rutas-norte en marxa, construeix una imatge registry.rutasnorte.example/botiga-web:dev-local, carrega-la a minikube i desplega-la amb un Ingress per a www.rutasnorte.example. Després, canvia el contingut de la pàgina, reconstrueix amb la mateixa etiqueta, torna a carregar la imatge i aconsegueix que el pod serveixi el contingut nou. Explica per què un simple kubectl apply no n'hi ha prou.

Solucions

Solució 1

minikube start --profile=rutas-norte-topologia \
  --driver=docker --kubernetes-version=v1.30.4 \
  --nodes=3 --cpus=2 --memory=3072 --cni=calico

kubectl label node rutas-norte-topologia-m02 topology.kubernetes.io/zone=zona-a
kubectl label node rutas-norte-topologia-m03 topology.kubernetes.io/zone=zona-b
kubectl create namespace rutas-norte-dev
# api-reserves-topologia.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-reserves
  namespace: rutas-norte-dev
spec:
  replicas: 4
  selector:
    matchLabels: { app: api-reserves }
  template:
    metadata:
      labels:
        app: api-reserves
        app.kubernetes.io/part-of: rutas-norte
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels: { app: api-reserves }
      containers:
        - name: api
          image: nginx:1.27-alpine
          resources:
            requests: { cpu: 50m, memory: 64Mi }
kubectl apply -f api-reserves-topologia.yaml
kubectl get pods -n rutas-norte-dev -o wide

Han de sortir 2 pods a -m02 i 2 a -m03. El node del pla de control no rep pods perquè té el taint corresponent (06-05).

Solució 2

# kind-sense-netpol.yaml -> nodes: [{role: control-plane}], sense networking
# kind-amb-netpol.yaml:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: amb-netpol
networking:
  disableDefaultCNI: true
  podSubnet: "192.168.0.0/16"
nodes: [{role: control-plane}]
---
# denegar-tot.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: denegar-entrada, namespace: rutas-norte-dev }
spec:
  podSelector: {}
  policyTypes: [Ingress]
for c in sense-netpol amb-netpol; do
  kind create cluster --config kind-${c}.yaml
  [ "$c" = "amb-netpol" ] && kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/calico.yaml && sleep 60
  kubectl create ns rutas-norte-dev
  kubectl -n rutas-norte-dev create deploy web --image=nginx:1.27-alpine
  kubectl -n rutas-norte-dev expose deploy web --port=80
  kubectl apply -f denegar-tot.yaml
  echo "--- $c ---"
  kubectl -n rutas-norte-dev run p --rm -i --restart=Never --image=busybox:1.36 -- \
    timeout 5 wget -qO- http://web || echo "BLOQUEJAT (correcte)"
done

A sense-netpol retorna l'HTML de nginx: la política es va ignorar. A amb-netpol dona timeout: Calico l'aplica.

Solució 3

docker build -t registry.rutasnorte.example/botiga-web:dev-local ./botiga-web
minikube image load registry.rutasnorte.example/botiga-web:dev-local --profile=rutas-norte
kubectl apply -f k8s/base/botiga-web.yaml   # amb imagePullPolicy: IfNotPresent

# --- després d'editar el contingut ---
docker build -t registry.rutasnorte.example/botiga-web:dev-local ./botiga-web
minikube image load registry.rutasnorte.example/botiga-web:dev-local --profile=rutas-norte
kubectl rollout restart deploy/botiga-web -n rutas-norte-dev

Per què kubectl apply no n'hi ha prou: el manifest no ha canviat (la mateixa etiqueta d'imatge), així que l'objecte a l'API és idèntic i el Deployment no genera un nou ReplicaSet. rollout restart afegeix una anotació amb la marca de temps a la plantilla del pod, cosa que sí que provoca el desplegament. Aquesta és exactament la raó per la qual en producció es fan servir etiquetes immutables amb digest (08-05): la imatge nova té un identificador nou i el canvi es propaga sol.

Conclusió

Ja saps muntar i destruir clústers locals amb criteri. Els punts que convé endur-se:

  • minikube brilla pels seus addons: ingress, metrics-server, storage-provisioner i csi-hostpath-driver t'estalvien instal·lar a mà mitja plataforma. Els perfils permeten tenir diversos clústers alhora, --kubernetes-version iguala el teu entorn a producció, i --nodes obre la porta a provar planificació i topologia.
  • kind guanya en velocitat i reproduïbilitat: els nodes són contenidors, tot el clúster es declara en un fitxer versionat amb extraPortMappings i extraMounts, i per això és l'elecció natural de la canalització ci-rutasnorte.
  • El bucle de treball amb imatges locals es resol amb minikube image load o kind load docker-image, sempre amb imagePullPolicy: IfNotPresent i etiquetes que no siguin latest.
  • I el més important: un clúster local valida correcció, no realisme. No hi ha balancejador de núvol, la StorageClass és una altra, el CNI per defecte pot ignorar les teves NetworkPolicies en silenci, i no hi ha zones ni escalat de nodes. Saber exactament què no estàs provant és el que evita el «a la meva màquina funciona».

Ens queda una pregunta pendent: els clústers locals són joguines controlades, però com es munta un clúster de veritat, en màquines pròpies, sense que ho faci un proveïdor de núvol per tu? A la lliçó següent, Kubeadm, veurem l'eina oficial per arrencar un clúster conforme: preparar les màquines, instal·lar containerd, executar kubeadm init amb un fitxer de configuració, unir nodes, muntar un pla de control en alta disponibilitat, renovar certificats i actualitzar de versió. I descobrirem per què kind, per dins, no és més que kubeadm dins d'un contenidor.

Curs de Kubernetes

Mòdul 1: Introducció a Kubernetes

Mòdul 2: Components Principals de Kubernetes

Mòdul 3: Gestió de Configuració i Secrets

Mòdul 4: Xarxes a Kubernetes

Mòdul 5: Emmagatzematge a Kubernetes

Mòdul 6: Conceptes Avançats de Kubernetes

Mòdul 7: Monitoratge i Registre

Mòdul 8: Seguretat a Kubernetes

Mòdul 9: Escalat i Rendiment

Mòdul 10: Ecosistema i Eines de Kubernetes

Mòdul 11: Estudis de Cas i Aplicacions del Món Real

Mòdul 12: Preparació per a la Certificació de Kubernetes

© Copyright 2026. Tots els drets reservats