CKA · Módulo 3CKA · Module 3CKA · Modulo 3 K8s v1.34 parte de Cluster Arch 25%part of Cluster Arch 25%parte di Cluster Arch 25%

Helm, Kustomize y CRDs

Helm, Kustomize and CRDs

Helm, Kustomize e CRD

Las tres formas de manejar aplicaciones y extender Kubernetes: paquetes con plantillas (Helm), personalización sin plantillas (Kustomize), y cómo el cluster aprende recursos nuevos (CRDs y Operators).

The three ways to manage applications and extend Kubernetes: templated packages (Helm), template-free customisation (Kustomize), and how the cluster learns new resource types (CRDs and Operators).

I tre modi di gestire le applicazioni ed estendere Kubernetes: pacchetti con template (Helm), personalizzazione senza template (Kustomize), e come il cluster impara nuovi tipi di risorsa (CRD e Operator).

Duración60 min
Duration60 min
Durata60 min
ContenidoNuevo en CKA
ContentNew in the CKA
ContenutoNuovo nel CKA
DificultadMedia
DifficultyMedium
DifficoltàMedia
EnfoqueUso, no autoría
FocusUsing, not authoring
FocusUsare, non scrivere
Tres herramientas que agregaron al CKA hace poco. La buena noticia: te piden usarlas, no ser un experto. Con Helm instalás, actualizás y revertís charts; con Kustomize aplicás overlays; con CRDs entendés cómo el cluster aprende tipos nuevos. Una regla transversal las une: el orden importa — el CRD va antes que el CR, la base antes que el overlay.
Three tools recently added to the CKA. The good news: you are asked to use them, not to be an expert. With Helm you install, upgrade and roll back charts; with Kustomize you apply overlays; with CRDs you understand how the cluster learns new types. One rule runs through all three: order matters — the CRD before the CR, the base before the overlay.
Tre strumenti aggiunti da poco al CKA. La buona notizia: ti chiedono di usarli, non di esserne esperto. Con Helm installi, aggiorni e fai rollback di chart; con Kustomize applichi overlay; con i CRD capisci come il cluster impara tipi nuovi. Una regola li attraversa tutti: l'ordine conta — il CRD prima del CR, la base prima dell'overlay.
3.1
Helm
El gestor de paquetes de K8s. install, upgrade, rollback, values.
The K8s package manager. install, upgrade, rollback, values.
Il gestore di pacchetti di K8s. install, upgrade, rollback, values.
3.2
Kustomize
Personalizar manifiestos sin plantillas. Bases + overlays.
Customise manifests without templates. Bases + overlays.
Personalizzare i manifest senza template. Base + overlay.
3.3
CRDs y Operators
CRDs and Operators
CRD e Operator
Enseñarle recursos nuevos al cluster. El patrón operator.
Teaching the cluster new resources. The operator pattern.
Insegnare risorse nuove al cluster. Il pattern operator.
★
Práctica · 7 ejercicios
Practice · 7 exercises
Pratica · 7 esercizi
Ciclo Helm, overlays y CRDs, con 3 de troubleshooting.
Helm cycle, overlays and CRDs, including 3 troubleshooting drills.
Ciclo Helm, overlay e CRD, con 3 di troubleshooting.
3.1
Gestor de paquetes · 25 min
Package manager · 25 min
Gestore di pacchetti · 25 min

Helm

Si apt instala paquetes en Linux, Helm instala aplicaciones en Kubernetes.
If apt installs packages on Linux, Helm installs applications on Kubernetes.
Se apt installa pacchetti su Linux, Helm installa applicazioni su Kubernetes.
Práctica · Comandos
Practice · Commands
Pratica · Comandi

Repos: de dónde salen los charts

Repos: where charts come from

Repo: da dove vengono i chart

helm repo add podinfo https://stefanprodan.github.io/podinfo
helm repo update
helm search repo nginx

El ciclo de vida completo

The full lifecycle

Il ciclo di vita completo

# instalar un chart como un "release" con nombre# install a chart as a named "release"# installare un chart come "release" con un nome
helm install web podinfo/podinfo -n m3 --set replicaCount=2

helm list -n m3
helm list -A                      # todos los namespaces# every namespace# tutti i namespace

# actualizar: cada upgrade crea una revisión nueva# upgrade: each one creates a new revision# upgrade: ognuno crea una nuova revisione
helm upgrade web podinfo/podinfo -n m3 --set replicaCount=4
helm history web -n m3

helm rollback web 1 -n m3
helm uninstall web -n m3

Values: personalizar la instalación

Values: customising the install

Values: personalizzare l'installazione

# el "menú" de lo que podés tocar# the "menu" of what you can change# il "menu" di ciò che puoi cambiare
helm show values podinfo/podinfo | head -40

# archivo → clave: valor   ·   flag → clave=valor# file → key: value   ·   flag → key=value# file → chiave: valore   ·   flag → chiave=valore
helm install api podinfo/podinfo -n m3 -f myvalues.yaml
helm install api podinfo/podinfo -n m3 --set replicaCount=3

Ver sin aplicar

Look without applying

Guardare senza applicare

helm template api podinfo/podinfo --set replicaCount=3
helm install api podinfo/podinfo -n m3 --dry-run --debug
★
helm template y helm install --dry-run --debug renderizan los manifiestos sin tocar el cluster. Es lo que usás para ver qué va a generar un chart antes de instalarlo, y para debug cuando algo no sale como esperabas.
helm template and helm install --dry-run --debug render the manifests without touching the cluster. That is how you see what a chart will produce before installing it, and how you debug when something comes out wrong.
helm template e helm install --dry-run --debug generano i manifest senza toccare il cluster. È così che vedi cosa produrrà un chart prima di installarlo, e come fai debug quando qualcosa non torna.
⚠
Helm también usa -n. Sin él todo cae en default: vale para install, upgrade, rollback, uninstall y list. Un release en el namespace equivocado = 0 puntos aunque el comando esté perfecto. Y Error: release: not found casi siempre es eso o un nombre mal escrito.
Helm takes -n too. Without it everything lands in default: that covers install, upgrade, rollback, uninstall and list. A release in the wrong namespace scores zero even if the command was perfect. And Error: release: not found is almost always that, or a typo in the name.
Anche Helm vuole -n. Senza, tutto finisce in default: vale per install, upgrade, rollback, uninstall e list. Un release nel namespace sbagliato vale zero anche se il comando è perfetto. E Error: release: not found è quasi sempre questo, o un nome scritto male.
Teoría · Conceptos
Theory · Concepts
Teoria · Concetti

El vocabulario

The vocabulary

Il vocabolario

TérminoQué es≈ apt
TermWhat it is≈ apt
TermineCos'è≈ apt
ChartEl paquete: plantillas + valores por defectoun .deb
ChartThe package: templates + default valuesa .deb
ChartIl pacchetto: template + valori di defaultun .deb
ReleaseUna instalación con nombre de un chartel paquete instalado
ReleaseA named installation of a chartthe installed package
ReleaseUn'installazione con nome di un chartil pacchetto installato
ValuesParámetros que lo personalizanopciones de config
ValuesParameters that customise itconfig options
ValuesParametri che lo personalizzanoopzioni di config
RepoColección de chartsun repo apt
RepoCollection of chartsan apt repo
RepoRaccolta di chartun repo apt
RevisionCada versión de un release—
RevisionEach version of a release—
RevisionOgni versione di un release—

Por qué existe

Why it exists

Perché esiste

Una app real son muchos manifiestos (deployment, service, configmap, ingress…). Helm los empaqueta con plantillas parametrizables: instalás todo con un comando y personalizás con values, en vez de editar diez YAMLs a mano.

A real app is many manifests (deployment, service, configmap, ingress…). Helm packages them with parameterisable templates: one command installs everything and values customise it, instead of hand-editing ten YAMLs.

Un'app reale sono molti manifest (deployment, service, configmap, ingress…). Helm li impacchetta con template parametrizzabili: un comando installa tutto e i values lo personalizzano, invece di modificare dieci YAML a mano.

Diagnosticar un release enfermo

Diagnosing a sick release

Diagnosticare un release malato

  1. helm history REL -n NS — ¿qué revisiones hay y cuál rompió?
  2. helm get values REL -n NS --revision N — ¿qué cambió esa revisión?
  3. helm rollback REL N -n NS — volver a la última buena.
  1. helm history REL -n NS — which revisions exist, and which one broke it?
  2. helm get values REL -n NS --revision N — what did that revision change?
  3. helm rollback REL N -n NS — go back to the last good one.
  1. helm history REL -n NS — quali revisioni esistono e quale ha rotto?
  2. helm get values REL -n NS --revision N — cosa ha cambiato quella revisione?
  3. helm rollback REL N -n NS — tornare all'ultima buona.
★
El rollback no borra la revisión mala: crea una revisión nueva idéntica a la buena. El historial queda como bitácora — exactamente igual que el rollout undo de un Deployment.
rollback does not delete the bad revision: it creates a new one identical to the good one. The history stays as a log — exactly like a Deployment's rollout undo.
Il rollback non cancella la revisione sbagliata: ne crea una nuova identica a quella buona. Lo storico resta come registro — esattamente come il rollout undo di un Deployment.
⚠
Meter = (sintaxis de --set) dentro de un archivo de values da cannot unmarshal string into … map. En el archivo siempre clave: valor. Y si -f y --set se pisan, gana --set.
Putting = (the --set syntax) inside a values file gives cannot unmarshal string into … map. In the file it is always key: value. And when -f and --set collide, --set wins.
Mettere = (la sintassi di --set) dentro un file di values dà cannot unmarshal string into … map. Nel file è sempre chiave: valore. E se -f e --set si sovrappongono, vince --set.
3.2
Personalización sin plantillas · 20 min
Template-free customisation · 20 min
Personalizzazione senza template · 20 min

Kustomize

Adaptar manifiestos por entorno (dev/prod) sin plantillas ni variables.
Adapt manifests per environment (dev/prod) with no templates and no variables.
Adattare i manifest per ambiente (dev/prod) senza template né variabili.
Práctica · Estructura y comandos
Practice · Structure and commands
Pratica · Struttura e comandi

La estructura: base + overlays

The structure: base + overlays

La struttura: base + overlay

base/
  kustomization.yaml
  deployment.yaml
  service.yaml
overlays/
  dev/   kustomization.yaml
  prod/  kustomization.yaml

El kustomization.yaml de la base

The base kustomization.yaml

Il kustomization.yaml della base

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml

Un overlay que la personaliza

An overlay that customises it

Un overlay che la personalizza

# overlays/prod/kustomization.yaml# overlays/prod/kustomization.yaml# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base            # relativo a ESTE archivo# relative to THIS file# relativo a QUESTO file
namePrefix: prod-
replicas:
  - name: miapp
    count: 5
images:
  - name: nginx
    newTag: "1.27"
labels:                  # forma moderna# modern form# forma moderna
  - pairs:
      env: prod
    includeSelectors: false

Aplicar con kubectl (viene integrado)

Apply with kubectl (built in)

Applicare con kubectl (già integrato)

k kustomize overlays/prod      # ver renderizado, sin aplicar# see it rendered, without applying# vederlo renderizzato, senza applicare
k apply -k overlays/prod       # -k, no -f# -k, not -f# -k, non -f
k delete -k overlays/prod
★
Lo que cae en el examen es kubectl apply -k <dir>. La -k le dice a kubectl "esto es un directorio kustomize, no un archivo". No instalás nada: Kustomize ya viene dentro de kubectl.
What shows up in the exam is kubectl apply -k <dir>. The -k tells kubectl "this is a kustomize directory, not a file". Nothing to install: Kustomize ships inside kubectl.
Quello che cade all'esame è kubectl apply -k <dir>. La -k dice a kubectl "questa è una directory kustomize, non un file". Non installi nulla: Kustomize è già dentro kubectl.
⚠
Los paths de resources: son relativos al propio kustomization.yaml. Desde overlays/dev/ la base está en ../../base, no ../base. Síntoma: accumulating resources … no such file or directory. Es el error de kustomize número uno.
resources: paths are relative to the kustomization.yaml itself. From overlays/dev/ the base is at ../../base, not ../base. Symptom: accumulating resources … no such file or directory. The number-one kustomize error.
I path di resources: sono relativi al kustomization.yaml stesso. Da overlays/dev/ la base sta in ../../base, non ../base. Sintomo: accumulating resources … no such file or directory. È l'errore numero uno di kustomize.
Teoría · La idea central
Theory · The core idea
Teoria · L'idea centrale

Base + Overlay

Base + Overlay

Base + Overlay

La base son los manifiestos genéricos comunes a todos los entornos; el overlay son los cambios de cada uno. El overlay referencia la base y le aplica parches encima: no copiás manifiestos, los reutilizás.

The base is the generic manifests common to every environment; the overlay is each one's differences. The overlay references the base and patches on top: you do not copy manifests, you reuse them.

La base sono i manifest generici comuni a tutti gli ambienti; l'overlay sono le differenze di ciascuno. L'overlay referenzia la base e ci applica patch sopra: non copi i manifest, li riusi.

Los transformers que apila un overlay

The transformers an overlay stacks

I transformer che un overlay impila

TransformerQué hace
TransformerWhat it does
TransformerCosa fa
replicas / imagesCambian réplicas y tags sin tocar la base
replicas / imagesChange replicas and tags without touching the base
replicas / imagesCambiano repliche e tag senza toccare la base
namePrefix / nameSuffixRenombran todo y ajustan las referencias cruzadas
namePrefix / nameSuffixRename everything and fix cross-references
namePrefix / nameSuffixRinominano tutto e sistemano i riferimenti incrociati
labels (moderno)Estampa labels; includeSelectors decide si toca el selector
labels (modern)Stamps labels; includeSelectors decides whether it touches the selector
labels (moderno)Applica label; includeSelectors decide se tocca il selector
commonLabels (viejo)Igual, pero SIEMPRE toca el selector; en deprecación
commonLabels (old)Same, but ALWAYS touches the selector; being deprecated
commonLabels (vecchio)Uguale, ma tocca SEMPRE il selector; in deprecazione
⚠
includeSelectors: true mete el label en el selector, y los selectors son inmutables: sobre un Deployment que ya corre, el apply falla. Por eso el default es false. En un recurso nuevo no hay problema.
includeSelectors: true puts the label into the selector, and selectors are immutable: on a Deployment already running, the apply fails. That is why the default is false. On a fresh resource it is fine.
includeSelectors: true mette la label nel selector, e i selector sono immutabili: su un Deployment già in esecuzione, l'apply fallisce. Per questo il default è false. Su una risorsa nuova non è un problema.

Kustomize vs Helm

Kustomize vs Helm

Kustomize vs Helm

KustomizeHelm
Sin plantillasCon plantillas
No templatesTemplates
Senza templateCon template
Parches sobre YAML realVariables en templates
Patches over real YAMLVariables in templates
Patch su YAML realeVariabili nei template
Integrado en kubectlHerramienta aparte
Built into kubectlSeparate tool
Integrato in kubectlStrumento separato
Bueno para variantesBueno para empaquetar y distribuir
Good for variantsGood for packaging and distributing
Buono per le variantiBuono per impacchettare e distribuire
★
Kustomize no usa plantillas ni variables: trabaja sobre YAML válido de verdad. Por eso los archivos de la base son manifiestos normales que también podés aplicar solos con kubectl apply -f.
Kustomize uses no templates and no variables: it works on genuinely valid YAML. That is why the base files are ordinary manifests you can also apply on their own with kubectl apply -f.
Kustomize non usa template né variabili: lavora su YAML davvero valido. Per questo i file della base sono manifest normali che puoi anche applicare da soli con kubectl apply -f.
Práctica · Patches y generadores
Practice · Patches and generators
Pratica · Patch e generatori

Un overlay completo, de punta a punta. Base: un Deployment api (nginx, con una anotación example.com/owner) y un Service api. Todo lo que sigue va en overlays/prod/.

A complete overlay, end to end. Base: a Deployment api (nginx, with an example.com/owner annotation) and a Service api. Everything below lives in overlays/prod/.

Un overlay completo, da capo a fondo. Base: un Deployment api (nginx, con un'annotazione example.com/owner) e un Service api. Tutto quello che segue sta in overlays/prod/.

overlays/prod/
  kustomization.yaml
  patch-api.yaml      # patch estratégico# strategic patch# patch strategica
  app.env             # fuente del configMapGenerator# source for configMapGenerator# sorgente del configMapGenerator
  default.conf        # archivo que va como volumen# file mounted as a volume# file montato come volume

1 · El kustomization.yaml del overlay

1 · The overlay's kustomization.yaml

1 · Il kustomization.yaml dell'overlay

resources:
  - ../../base
namePrefix: prod-

configMapGenerator:
  - name: api-env
    envs:                  # archivo KEY=VALUE → una clave por línea# KEY=VALUE file → one key per line# file KEY=VALUE → una chiave per riga
      - app.env
  - name: api-files
    files:                 # el archivo entero → clave = nombre del archivo# the whole file → key = file name# il file intero → chiave = nome del file
      - default.conf

secretGenerator:
  - name: api-secret
    literals:              # KEY=VALUE en línea, sin comillas# inline KEY=VALUE, no quotes# KEY=VALUE in linea, senza virgolette
      - DB_PASS=s3cr3t

patches:
  - path: patch-api.yaml    # estratégico: en archivo aparte# strategic: separate file# strategica: file a parte
  - target:                # JSON 6902: a QUÉ recurso# JSON 6902: WHICH resource# JSON 6902: a QUALE risorsa
      kind: Service
      name: api            # nombre de la BASE, sin prefijo# BASE name, no prefix# nome della BASE, senza prefisso
    patch: |-
      - op: add
        path: /spec/type
        value: NodePort
      - op: add
        path: /spec/ports/0/nodePort   # 0 = primer elemento de la lista# 0 = first element of the list# 0 = primo elemento della lista
        value: 30180
  - target:
      kind: Deployment
      name: api
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 3
      - op: remove           # "/" dentro de la clave se escribe ~1# a "/" inside the key is written ~1# "/" dentro la chiave si scrive ~1
        path: /metadata/annotations/example.com~1owner

2 · El patch estratégico: conectar ConfigMaps y Secret al pod

2 · The strategic patch: wiring ConfigMaps and the Secret into the pod

2 · La patch strategica: collegare ConfigMap e Secret al pod

# patch-api.yaml — YAML de Kubernetes normal, pero solo lo que cambia# patch-api.yaml — ordinary Kubernetes YAML, only what changes# patch-api.yaml — YAML Kubernetes normale, solo ciò che cambia
apiVersion: apps/v1
kind: Deployment                # ┐ identifican QUÉ recurso# ┐ identify WHICH resource# ┐ identificano QUALE risorsa
metadata:                       #  │
  name: api                      # ┘ nombre de la base# ┘ base name# ┘ nome della base
spec:
  template:
    spec:
      containers:
        - name: api                # identifica QUÉ contenedor de la lista# identifies WHICH container in the list# identifica QUALE container della lista
          envFrom:                 # a) TODAS las claves del ConfigMap como env# a) ALL ConfigMap keys as env vars# a) TUTTE le chiavi del ConfigMap come env
            - configMapRef:
                name: api-env      # nombre del GENERADOR, sin hash# GENERATOR name, no hash# nome del GENERATORE, senza hash
          env:                     # b) UNA clave del Secret, con el nombre que elijas# b) ONE Secret key, under the name you choose# b) UNA chiave del Secret, col nome che scegli
            - name: DB_PASS
              valueFrom:
                secretKeyRef:
                  name: api-secret
                  key: DB_PASS
          volumeMounts:            # c) un ConfigMap como ARCHIVOS# c) a ConfigMap as FILES# c) un ConfigMap come FILE
            - name: conf
              mountPath: /etc/nginx/conf.d
      volumes:
        - name: conf
          configMap:
            name: api-files

3 · Verlo antes de aplicarlo

3 · See it before applying it

3 · Vederlo prima di applicarlo

k kustomize overlays/prod | grep -E "kind:|name: prod-|nodePort|replicas"
# kind: ConfigMap   name: prod-api-env-89m87m749m     ← hash del contenido# kind: ConfigMap   name: prod-api-env-89m87m749m     ← content hash# kind: ConfigMap   name: prod-api-env-89m87m749m     ← hash del contenuto
# kind: Secret      name: prod-api-secret-7kttbck6c5  ← data en base64, automático# kind: Secret      name: prod-api-secret-7kttbck6c5  ← data in base64, automatically# kind: Secret      name: prod-api-secret-7kttbck6c5  ← data in base64, automatico
# en el Deployment: configMapRef → prod-api-env-89m87m749m  (reescrito solo)# in the Deployment: configMapRef → prod-api-env-89m87m749m  (rewritten for you)# nel Deployment: configMapRef → prod-api-env-89m87m749m  (riscritto da solo)
k apply -k overlays/prod --dry-run=server   # valida contra el apiserver# validates against the apiserver# valida contro l'apiserver
k apply -k overlays/prod
★
Regla práctica: patch estratégico por defecto (es YAML que ya sabés escribir y k explain te ayuda). JSON 6902 solo si la consigna lo pide, para borrar un campo o para tocar un elemento de lista por posición. Y antes de aplicar, siempre k kustomize <dir>: es tu dry-run.
Rule of thumb: strategic patch by default (it is YAML you already know, and k explain helps). JSON 6902 only when the task asks for it, to delete a field, or to touch a list element by position. And before applying, always k kustomize <dir>: that is your dry run.
Regola pratica: patch strategica di default (è YAML che sai già scrivere e k explain aiuta). JSON 6902 solo se la consegna lo chiede, per cancellare un campo o toccare un elemento di lista per posizione. E prima di applicare, sempre k kustomize <dir>: è il tuo dry run.
⚠
Dos tropiezos clásicos: en los literals, DB_PASS="s3cr3t" puede terminar con las comillas como parte del valor, así que escribilo sin comillas. Y el name de target y del patch estratégico es el de la base (api), nunca el prefijado (prod-api).
Two classic slips: in literals, DB_PASS="s3cr3t" can end up with the quotes as part of the value, so write it without quotes. And the name in target and in the strategic patch is the base one (api), never the prefixed one (prod-api).
Due inciampi classici: nei literals, DB_PASS="s3cr3t" può finire con le virgolette dentro il valore, quindi scrivilo senza virgolette. E il name di target e della patch strategica è quello della base (api), mai quello col prefisso (prod-api).
Teoría · Tres sintaxis en un archivo
Theory · Three syntaxes in one file
Teoria · Tre sintassi in un file

Por qué Kustomize confunde

Why Kustomize is confusing

Perché Kustomize confonde

En un mismo overlay conviven tres lenguajes distintos. Separarlos es la mitad del trabajo:

Three different languages live side by side in one overlay. Telling them apart is half the job:

In uno stesso overlay convivono tre linguaggi diversi. Separarli è metà del lavoro:

Lo que escribísSintaxis¿k explain?
What you writeSyntaxk explain?
Cosa scriviSintassik explain?
Campos del kustomization.yamlLa de KustomizeNo → kubernetes.io
kustomization.yaml fieldsKustomize's ownNo → kubernetes.io
Campi del kustomization.yamlQuella di KustomizeNo → kubernetes.io
Patch estratégicoYAML de Kubernetes, parcialSí
Strategic patchKubernetes YAML, partialYes
Patch strategicaYAML Kubernetes, parzialeSì
Patch JSON 6902Estándar RFC 6902: lista de operacionesNo
JSON 6902 patchRFC 6902 standard: a list of operationsNo
Patch JSON 6902Standard RFC 6902: lista di operazioniNo

Patch estratégico: una fusión, no un reemplazo

Strategic patch: a merge, not a replacement

Patch strategica: una fusione, non una sostituzione

Kustomize fusiona tu fragmento con el recurso: lo que no escribís queda como estaba. Para saber dónde fusionar necesita encontrar el recurso (kind + metadata.name) y, en las listas, el elemento: los contenedores se fusionan por su name. Por eso - name: api es obligatorio aunque no lo cambies: sin él, Kustomize no sabe a cuál contenedor sumarle los campos.

Kustomize merges your fragment into the resource: whatever you do not write stays as it was. To know where to merge, it must find the resource (kind + metadata.name) and, in lists, the element: containers are merged by their name. That is why - name: api is mandatory even if you do not change it: without it, Kustomize cannot tell which container gets the fields.

Kustomize fonde il tuo frammento con la risorsa: ciò che non scrivi resta com'era. Per sapere dove fondere deve trovare la risorsa (kind + metadata.name) e, nelle liste, l'elemento: i container si fondono per il loro name. Per questo - name: api è obbligatorio anche se non lo cambi: senza, Kustomize non sa a quale container aggiungere i campi.

JSON 6902: operaciones sobre un camino

JSON 6902: operations on a path

JSON 6902: operazioni su un percorso

No es de Kustomize: es un estándar genérico de JSON, el mismo de kubectl patch --type=json. Cada operación tiene tres partes: op (qué), path (dónde) y value (con qué).

It is not Kustomize's: it is a generic JSON standard, the same one behind kubectl patch --type=json. Every operation has three parts: op (what), path (where) and value (with what).

Non è di Kustomize: è uno standard JSON generico, lo stesso di kubectl patch --type=json. Ogni operazione ha tre parti: op (cosa), path (dove) e value (con cosa).

opQué hace
opWhat it does
opCosa fa
addCrea el campo; si ya existe, lo pisa. En una lista, inserta en esa posición (/- = al final)
addCreates the field; if it exists, overwrites it. In a list, inserts at that position (/- = at the end)
addCrea il campo; se esiste, lo sovrascrive. In una lista, inserisce in quella posizione (/- = in fondo)
replaceCambia un campo que tiene que existir (si no, error)
replaceChanges a field that must exist (error otherwise)
replaceCambia un campo che deve esistere (altrimenti errore)
removeBorra el campo. Es lo que el patch estratégico no hace fácil
removeDeletes the field. The thing a strategic patch does not do easily
removeCancella il campo. È ciò che la patch strategica non fa facilmente

El path recorre el YAML con barras; las listas van por índice desde 0 (/spec/template/spec/containers/0/image). Si una clave tiene una barra adentro, como las anotaciones example.com/owner, la barra se escribe ~1.

The path walks the YAML with slashes; lists go by index from 0 (/spec/template/spec/containers/0/image). If a key contains a slash, like the example.com/owner annotation, the slash is written ~1.

Il path percorre lo YAML con le barre; le liste vanno per indice da 0 (/spec/template/spec/containers/0/image). Se una chiave ha una barra dentro, come l'annotazione example.com/owner, la barra si scrive ~1.

Generadores: por qué el hash en el nombre

Generators: why the hash in the name

Generatori: perché l'hash nel nome

configMapGenerator y secretGenerator son campos de Kustomize, el equivalente de kubectl create cm/secret --from-literal / --from-file / --from-env-file (ver M4 §4.3). Le agregan al nombre un hash del contenido y reescriben solos todas las referencias en los pods. La cadena es:

configMapGenerator and secretGenerator are Kustomize fields, the equivalent of kubectl create cm/secret --from-literal / --from-file / --from-env-file (see M4 §4.3). They append a content hash to the name and rewrite every reference in the pods on their own. The chain is:

configMapGenerator e secretGenerator sono campi di Kustomize, l'equivalente di kubectl create cm/secret --from-literal / --from-file / --from-env-file (vedi M4 §4.3). Aggiungono al nome un hash del contenuto e riscrivono da soli tutti i riferimenti nei pod. La catena è:

# cambiás un valor → cambia el hash → cambia el nombre# you change a value → the hash changes → the name changes# cambi un valore → cambia l'hash → cambia il nome
# → cambia el pod template → rollout AUTOMÁTICO# → the pod template changes → AUTOMATIC rollout# → cambia il pod template → rollout AUTOMATICO

Sin generador, editar un ConfigMap no reinicia los pods que lo leen como env: hace falta rollout restart (lo que hubo que hacer con kube-proxy). Los ConfigMaps viejos quedan en el cluster; si no querés el hash, options: {disableNameSuffixHash: true}, pero perdés el rollout automático.

Without a generator, editing a ConfigMap does not restart the pods that read it as env: you need a rollout restart (what kube-proxy needed). The old ConfigMaps stay in the cluster; if you do not want the hash, options: {disableNameSuffixHash: true}, but you lose the automatic rollout.

Senza generatore, modificare un ConfigMap non riavvia i pod che lo leggono come env: serve un rollout restart (come con kube-proxy). I ConfigMap vecchi restano nel cluster; se non vuoi l'hash, options: {disableNameSuffixHash: true}, ma perdi il rollout automatico.

Las tres formas de meterlos en el pod

The three ways into the pod

I tre modi di metterli nel pod

Querés…Campo del contenedor
You want…Container field
Vuoi…Campo del container
Todas las claves como variablesenvFrom: - configMapRef / secretRef
Every key as variablesenvFrom: - configMapRef / secretRef
Tutte le chiavi come variabilienvFrom: - configMapRef / secretRef
Una clave, con el nombre que elijasenv: - valueFrom: configMapKeyRef / secretKeyRef
One key, under the name you chooseenv: - valueFrom: configMapKeyRef / secretKeyRef
Una chiave, col nome che sceglienv: - valueFrom: configMapKeyRef / secretKeyRef
Como archivos en un directoriovolumes: configMap / secret + volumeMounts
As files in a directoryvolumes: configMap / secret + volumeMounts
Come file in una directoryvolumes: configMap / secret + volumeMounts
★
El secretGenerator codifica en base64 por vos, pero el valor queda en texto plano en tu kustomization.yaml. En un repo real eso es una fuga: para el examen alcanza, en producción se usa un gestor de secretos.
secretGenerator base64-encodes for you, but the value sits in plain text in your kustomization.yaml. In a real repo that is a leak: fine for the exam, in production you use a secrets manager.
Il secretGenerator codifica in base64 per te, ma il valore resta in chiaro nel tuo kustomization.yaml. In un repo vero è una fuga: per l'esame va bene, in produzione si usa un gestore di segreti.
3.3
Extender Kubernetes · 15 min
Extending Kubernetes · 15 min
Estendere Kubernetes · 15 min

CRDs y Operators

CRDs and Operators

CRD e Operator

Cómo el cluster aprende tipos de recursos que no vienen de fábrica.
How the cluster learns resource types it did not ship with.
Come il cluster impara tipi di risorsa che non arrivano di serie.
Práctica · Ver y usar
Practice · Look and use
Pratica · Guardare e usare

Ver los CRDs instalados

See the installed CRDs

Vedere i CRD installati

k get crds
k get crds | grep calico     # Calico instaló varios en tu cluster# Calico installed several in your cluster# Calico ne ha installati diversi nel tuo cluster
k api-resources | grep -i backup
k explain backup.spec         # funciona con tipos custom# works with custom types# funziona con i tipi custom

Anatomía de un CRD

Anatomy of a CRD

Anatomia di un CRD

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: backups.demo.cka.io    # plural.grupo — obligatorio así# plural.group — must be exactly this# plurale.gruppo — dev'essere esattamente così
spec:
  group: demo.cka.io
  names:
    kind: Backup                # ↔ el kind que usarás en el CR# ↔ the kind you will use in the CR# ↔ il kind che userai nel CR
    plural: backups
  scope: Namespaced             # o Cluster# or Cluster# o Cluster
  versions:
  - name: v1
    served: true
    storage: true

Usar el tipo nuevo

Use the new type

Usare il tipo nuovo

k apply -f backup-crd.yaml   # 1 · la DEFINICIÓN (el molde)# 1 · the DEFINITION (the mould)# 1 · la DEFINIZIONE (lo stampo)
k apply -f mybackup.yaml     # 2 · la INSTANCIA (el objeto)# 2 · the INSTANCE (the object)# 2 · l'ISTANZA (l'oggetto)
k get backups -n m3
★
En el examen te van a pedir k get crds, o instalar un CRD desde un manifiesto dado y después crear un recurso de ese tipo. No te van a pedir escribir un CRD desde cero.
In the exam you will be asked for k get crds, or to install a CRD from a given manifest and then create a resource of that type. You will not be asked to write a CRD from scratch.
All'esame ti chiederanno k get crds, oppure di installare un CRD da un manifest fornito e poi creare una risorsa di quel tipo. Non ti chiederanno di scrivere un CRD da zero.
Teoría · El concepto
Theory · The concept
Teoria · Il concetto

CRD vs Custom Resource

CRD vs Custom Resource

CRD vs Custom Resource

  • CRD: la definición del tipo nuevo — el molde.
  • CR: una instancia de ese tipo — el objeto concreto.
  • CRD: the definition of the new type — the mould.
  • CR: an instance of that type — the concrete object.
  • CRD: la definizione del tipo nuovo — lo stampo.
  • CR: un'istanza di quel tipo — l'oggetto concreto.

Igual que Deployment (el tipo) vs "mi-deployment" (la instancia). Una vez instalado el CRD, el tipo se comporta como si fuera nativo: get, describe, apply, RBAC, todo.

Just like Deployment (the type) vs "my-deployment" (the instance). Once the CRD is installed, the type behaves as if it were native: get, describe, apply, RBAC, all of it.

Come Deployment (il tipo) contro "mio-deployment" (l'istanza). Una volta installato il CRD, il tipo si comporta come se fosse nativo: get, describe, apply, RBAC, tutto.

Qué es un Operator

What an Operator is

Cos'è un Operator

Un Operator = CRD + un controller que lo vigila. El controller observa los CR de ese tipo y actúa (crea pods, hace backups, lo que sea). Lleva la lógica de "estado deseado" del Módulo 1 a recursos propios.

An Operator = CRD + a controller that watches it. The controller observes CRs of that type and acts (creates pods, takes backups, whatever). It carries Module 1's "desired state" logic over to your own resources.

Un Operator = CRD + un controller che lo sorveglia. Il controller osserva i CR di quel tipo e agisce (crea pod, fa backup, qualunque cosa). Porta la logica dello "stato desiderato" del Modulo 1 sulle tue risorse.

⚠
no matches for kind "X" = el API server no conoce ese tipo → falta instalar el CRD. El propio kubectl lo sugiere: "ensure CRDs are installed first". Es el error número uno de CRDs.
no matches for kind "X" = the API server does not know that type → the CRD is not installed. kubectl itself hints at it: "ensure CRDs are installed first". The number-one CRD error.
no matches for kind "X" = l'API server non conosce quel tipo → manca il CRD. Lo suggerisce kubectl stesso: "ensure CRDs are installed first". È l'errore numero uno dei CRD.
⚠
Borrar un CRD borra en cascada TODOS sus CR — irreversible y silencioso. En producción, un delete crd por error te limpia todos los objetos de ese tipo. Tratá los CRDs como infraestructura, no como un objeto más.
Deleting a CRD cascade-deletes ALL its CRs — irreversible and silent. In production, one accidental delete crd wipes every object of that type. Treat CRDs as infrastructure, not as just another object.
Cancellare un CRD cancella a cascata TUTTI i suoi CR — irreversibile e silenzioso. In produzione, un delete crd per sbaglio ti azzera ogni oggetto di quel tipo. Tratta i CRD come infrastruttura, non come un oggetto qualsiasi.
★
k explain funciona con tipos custom porque lee el mismo openAPIV3Schema del CRD que valida tus spec. Un CRD bien hecho documenta y valida a la vez.
k explain works on custom types because it reads the very openAPIV3Schema from the CRD that validates your spec. A well-built CRD documents and validates at once.
k explain funziona con i tipi custom perché legge lo stesso openAPIV3Schema del CRD che valida i tuoi spec. Un CRD fatto bene documenta e valida insieme.
★
Cierre del módulo
Module wrap-up
Chiusura del modulo

Lo que te llevás del Módulo 3

What you take from Module 3

Cosa porti via dal Modulo 3

Resumen · Comandos clave
Summary · Key commands
Riassunto · Comandi chiave
### HELM
helm repo add NAME URL && helm repo update
helm install REL repo/chart -n NS --set key=val
helm upgrade REL repo/chart -n NS -f values.yaml
helm history REL -n NS
helm get values REL -n NS --revision N
helm rollback REL N -n NS
helm template REL repo/chart        # sin aplicar# without applying# senza applicare

### KUSTOMIZE
k kustomize DIR                    # ver renderizado# see it rendered# vederlo renderizzato
k apply -k DIR

### CRDs
k get crds
k api-resources | grep TIPO
k explain TIPO.spec
k apply -f crd.yaml && k apply -f cr.yaml
Teoría · Lo esencial
Theory · The essentials
Teoria · L'essenziale

Las 3 ideas que no se negocian

The 3 non-negotiable ideas

Le 3 idee non negoziabili

  • Helm = gestor de paquetes. Chart → Release → Revisiones. install / upgrade / rollback / uninstall, siempre con -n.
  • Kustomize = base + overlays, sin plantillas. kubectl apply -k. Ya viene en kubectl.
  • CRD = tipo nuevo; CR = instancia; Operator = CRD + controller que actúa.
  • Helm = package manager. Chart → Release → Revisions. install / upgrade / rollback / uninstall, always with -n.
  • Kustomize = base + overlays, no templates. kubectl apply -k. Already in kubectl.
  • CRD = new type; CR = instance; Operator = CRD + a controller that acts.
  • Helm = gestore di pacchetti. Chart → Release → Revisioni. install / upgrade / rollback / uninstall, sempre con -n.
  • Kustomize = base + overlay, senza template. kubectl apply -k. È già in kubectl.
  • CRD = tipo nuovo; CR = istanza; Operator = CRD + controller che agisce.
★
Para el examen: Helm y Kustomize son ejecutar operaciones; CRDs es reconocer y usar tipos custom. Nada de autoría compleja. Y la regla de oro común: el orden importa.
For the exam: Helm and Kustomize are about running operations; CRDs are about recognising and using custom types. No complex authoring. And the shared golden rule: order matters.
Per l'esame: Helm e Kustomize sono eseguire operazioni; i CRD sono riconoscere e usare tipi custom. Niente scrittura complessa. E la regola d'oro comune: l'ordine conta.
Checkpoint Módulo 3: Helm (install/upgrade/rollback), Kustomize (apply -k) y CRDs/Operators. Cierra Cluster Architecture (25%). Siguiente: Módulo 4 — Workloads.
Module 3 checkpoint: Helm (install/upgrade/rollback), Kustomize (apply -k) and CRDs/Operators. Closes Cluster Architecture (25%). Next: Module 4 — Workloads.
Checkpoint Modulo 3: Helm (install/upgrade/rollback), Kustomize (apply -k) e CRD/Operator. Chiude Cluster Architecture (25%). Prossimo: Modulo 4 — Workload.
★
Fase 2 · resolver en vivo
Phase 2 · solve it live
Fase 2 · risolvere dal vivo

Práctica — 7 ejercicios

Practice — 7 exercises

Pratica — 7 esercizi

3 de Helm, 2 de Kustomize, 2 de CRDs. Tres son de troubleshooting.
3 on Helm, 2 on Kustomize, 2 on CRDs. Three are troubleshooting.
3 su Helm, 2 su Kustomize, 2 sui CRD. Tre sono di troubleshooting.
0 / 7
⚙
Setup. Namespaces m3-helm, m3-kustomize y m3-crd. Hace falta el binario helm en el nodo (curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash) y conectividad al repo de charts. Kustomize no se instala: viene en kubectl.
Setup. Namespaces m3-helm, m3-kustomize and m3-crd. You need the helm binary on the node (curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash) and connectivity to the chart repo. Kustomize needs no install: it ships in kubectl.
Setup. Namespace m3-helm, m3-kustomize e m3-crd. Serve il binario helm sul nodo (curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash) e connettività al repo dei chart. Kustomize non si installa: è già in kubectl.
🧠
Modelo mental. Helm = paquete: install crea un release, cada upgrade es una revisión, rollback vuelve a una previa. Kustomize = base + overlays, se aplica con -k. CRD = tipo nuevo → CR = instancia. Regla transversal: el orden importa — CRD antes que CR, base antes que overlay.
Mental model. Helm = package: install creates a release, each upgrade is a revision, rollback returns to an earlier one. Kustomize = base + overlays, applied with -k. CRD = new type → CR = instance. Cross-cutting rule: order matters — CRD before CR, base before overlay.
Modello mentale. Helm = pacchetto: install crea un release, ogni upgrade è una revisione, rollback torna a una precedente. Kustomize = base + overlay, si applica con -k. CRD = tipo nuovo → CR = istanza. Regola trasversale: l'ordine conta — CRD prima del CR, base prima dell'overlay.
E1

Helm — ciclo de vida completo

Helm — the full lifecycle

Helm — ciclo di vita completo

~5 min
  1. Agregá el repo podinfo (https://stefanprodan.github.io/podinfo) y actualizá el índice.
  2. Instalá podinfo/podinfo en m3-helm como release web, con 2 réplicas.
  3. Verificá el release y los pods.
  4. Upgrade a 4 réplicas y mostrá el historial.
  5. Rollback a la revisión de 2 réplicas y confirmá.
  6. Desinstalá web.
  1. Add the podinfo repo (https://stefanprodan.github.io/podinfo) and refresh the index.
  2. Install podinfo/podinfo in m3-helm as release web, with 2 replicas.
  3. Verify the release and the pods.
  4. Upgrade to 4 replicas and show the history.
  5. Roll back to the 2-replica revision and confirm.
  6. Uninstall web.
  1. Aggiungi il repo podinfo (https://stefanprodan.github.io/podinfo) e aggiorna l'indice.
  2. Installa podinfo/podinfo in m3-helm come release web, con 2 repliche.
  3. Verifica il release e i pod.
  4. Upgrade a 4 repliche e mostra lo storico.
  5. Rollback alla revisione con 2 repliche e conferma.
  6. Disinstalla web.
Ver soluciónShow solutionMostra soluzione
helm repo add podinfo https://stefanprodan.github.io/podinfo
helm repo update

helm install web podinfo/podinfo -n m3-helm --set replicaCount=2
helm list -n m3-helm
k get pods -n m3-helm

helm upgrade web podinfo/podinfo -n m3-helm --set replicaCount=4
helm history web -n m3-helm            # REV 1 y REV 2# REV 1 and REV 2# REV 1 e REV 2

helm rollback web 1 -n m3-helm
k get deploy web-podinfo -n m3-helm    # READY 2/2# READY 2/2# READY 2/2
helm uninstall web -n m3-helm
Claves
Key points
Punti chiave
  • El deployment se llama <release>-<chart> → web-podinfo. Si buscás web a secas no lo encontrás.
  • El value de réplicas de este chart es replicaCount: sale de helm show values, no se adivina.
  • Cada upgrade es una revisión nueva; el propio rollback genera otra. Es el historial de toda la app, no de un objeto.
  • Todo lleva -n m3-helm.
  • The deployment is named <release>-<chart> → web-podinfo. Looking for plain web finds nothing.
  • This chart's replica value is replicaCount: it comes from helm show values, you do not guess it.
  • Each upgrade is a new revision; the rollback itself creates another. It is the history of the whole app, not of one object.
  • Everything takes -n m3-helm.
  • Il deployment si chiama <release>-<chart> → web-podinfo. Cercando solo web non trovi nulla.
  • Il value delle repliche di questo chart è replicaCount: viene da helm show values, non si indovina.
  • Ogni upgrade è una revisione nuova; il rollback stesso ne crea un'altra. È lo storico di tutta l'app, non di un oggetto.
  • Tutto vuole -n m3-helm.
E2

Troubleshooting — un deploy rompió la app

Troubleshooting — a deploy broke the app

Troubleshooting — un deploy ha rotto l'app

~6 min

En m3-helm-ts corre el release shop. Después del último deploy los pods nuevos no arrancan. Diagnosticá con herramientas de Helm, identificá la última revisión buena y volvé a ella. Después contestá: ¿qué cambió el deploy que la rompió?

Para plantarlo vos mismo: instalá el chart y hacé un upgrade --set image.tag=9.9.9-doesnotexist.

Release shop runs in m3-helm-ts. After the last deploy the new pods will not start. Diagnose it with Helm's own tools, find the last good revision and go back to it. Then answer: what did the breaking deploy change?

To plant it yourself: install the chart and run an upgrade --set image.tag=9.9.9-doesnotexist.

In m3-helm-ts gira il release shop. Dopo l'ultimo deploy i pod nuovi non partono. Diagnostica con gli strumenti di Helm, individua l'ultima revisione buona e tornaci. Poi rispondi: cosa ha cambiato il deploy che l'ha rotta?

Per prepararlo da solo: installa il chart e fai un upgrade --set image.tag=9.9.9-doesnotexist.

Ver soluciónShow solutionMostra soluzione
helm list -n m3-helm-ts          # shop figura "deployed"… pero# shop shows as "deployed"… but# shop risulta "deployed"… ma
k get pods -n m3-helm-ts        # ImagePullBackOff# ImagePullBackOff# ImagePullBackOff

helm history shop -n m3-helm-ts  # REV 1 sana, REV 2 la que rompió# REV 1 healthy, REV 2 the culprit# REV 1 sana, REV 2 la colpevole
helm get values shop -n m3-helm-ts --revision 2
#   image.tag=9.9.9-doesnotexist  ← el culpable#   image.tag=9.9.9-doesnotexist  ← the culprit#   image.tag=9.9.9-doesnotexist  ← il colpevole
helm get values shop -n m3-helm-ts --revision 1

helm rollback shop 1 -n m3-helm-ts
k get pods -n m3-helm-ts        # todos Running# all Running# tutti Running
helm history shop -n m3-helm-ts  # REV 3 = "Rollback to 1"# REV 3 = "Rollback to 1"# REV 3 = "Rollback to 1"
Claves
Key points
Punti chiave
  • helm list te miente tranquilamente: dice deployed porque el apply salió bien. Que los pods arranquen es otra cosa.
  • helm history es el primer comando ante un release enfermo; helm get values --revision N te da el diff exacto que lo rompió.
  • Mismo patrón que el rollout undo de M4: el rollback crea una revisión nueva, no borra la mala.
  • helm list lies to your face: it says deployed because the apply succeeded. Whether the pods start is another matter.
  • helm history is the first command for a sick release; helm get values --revision N gives you the exact diff that broke it.
  • Same pattern as M4's rollout undo: the rollback creates a new revision, it does not delete the bad one.
  • helm list ti mente serenamente: dice deployed perché l'apply è riuscito. Che i pod partano è un'altra faccenda.
  • helm history è il primo comando davanti a un release malato; helm get values --revision N ti dà il diff esatto che l'ha rotto.
  • Stesso pattern del rollout undo di M4: il rollback crea una revisione nuova, non cancella quella sbagliata.
E3

Helm — values e inspección sin aplicar

Helm — values and inspection without applying

Helm — values e ispezione senza applicare

~5 min
  1. Mostrá los values por defecto de podinfo/podinfo.
  2. Sin instalar nada, mostrá el YAML que generaría con replicaCount=3.
  3. Instalá un release api usando un archivo de values propio, verificá y desinstalá.
  1. Show the default values of podinfo/podinfo.
  2. Without installing anything, show the YAML it would generate with replicaCount=3.
  3. Install a release api using your own values file, verify, and uninstall.
  1. Mostra i values di default di podinfo/podinfo.
  2. Senza installare nulla, mostra lo YAML che genererebbe con replicaCount=3.
  3. Installa un release api usando un tuo file di values, verifica e disinstalla.
Ver soluciónShow solutionMostra soluzione
helm show values podinfo/podinfo | head -40

helm template api podinfo/podinfo --set replicaCount=3
#   equivalente como pre-chequeo de un install:#   equivalent as a pre-check of an install:#   equivalente come pre-controllo di un install:
helm install api podinfo/podinfo -n m3-helm --set replicaCount=3 --dry-run --debug

cat > myvalues.yaml <<'EOF'
replicaCount: 3
EOF
helm install api podinfo/podinfo -n m3-helm -f myvalues.yaml
k get deploy api-podinfo -n m3-helm      # READY 3/3# READY 3/3# READY 3/3
helm uninstall api -n m3-helm
Claves
Key points
Punti chiave
  • helm show values es el menú de lo que podés tocar. Sin eso, adivinás nombres de values.
  • -f archivo para muchos values, --set k=v para overrides puntuales. Si se pisan, gana --set.
  • En el archivo va clave: valor. Poner clave=valor da cannot unmarshal string into … map.
  • helm show values is the menu of what you can change. Without it you are guessing value names.
  • -f file for many values, --set k=v for one-off overrides. When they collide, --set wins.
  • The file takes key: value. Writing key=value gives cannot unmarshal string into … map.
  • helm show values è il menu di ciò che puoi cambiare. Senza, indovini i nomi dei values.
  • -f file per molti values, --set k=v per override puntuali. Se si sovrappongono, vince --set.
  • Nel file va chiave: valore. Scrivere chiave=valore dà cannot unmarshal string into … map.
E4

Kustomize — base + overlay con transformers apilados

Kustomize — base + overlay with stacked transformers

Kustomize — base + overlay con transformer impilati

~7 min

En ~/m3/kustomize/ hay una base (deployment store con nginx + service, ns m3-kustomize). Sin tocarla, creá dos overlays:

  1. overlays/prod: 4 réplicas e imagen nginx:1.27.
  2. overlays/staging: prefijo de nombre staging-, label env: staging en todos los recursos y 3 réplicas.

Renderizá antes de aplicar, aplicá los dos y verificá.

~/m3/kustomize/ holds a base (deployment store with nginx + service, ns m3-kustomize). Without touching it, create two overlays:

  1. overlays/prod: 4 replicas and image nginx:1.27.
  2. overlays/staging: name prefix staging-, label env: staging on every resource, and 3 replicas.

Render before applying, apply both, and verify.

In ~/m3/kustomize/ c'è una base (deployment store con nginx + service, ns m3-kustomize). Senza toccarla, crea due overlay:

  1. overlays/prod: 4 repliche e immagine nginx:1.27.
  2. overlays/staging: prefisso di nome staging-, label env: staging su ogni risorsa e 3 repliche.

Renderizza prima di applicare, applica entrambi e verifica.

Ver soluciónShow solutionMostra soluzione
# overlays/prod/kustomization.yaml# overlays/prod/kustomization.yaml# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
replicas:
  - name: store
    count: 4
images:
  - name: nginx
    newTag: "1.27"

# overlays/staging/kustomization.yaml# overlays/staging/kustomization.yaml# overlays/staging/kustomization.yaml
resources:
  - ../../base
namePrefix: staging-
labels:
  - pairs:
      env: staging
    includeSelectors: true      # recurso nuevo: acá sí se puede# new resource: safe here# risorsa nuova: qui si può
replicas:
  - name: store
    count: 3

k kustomize overlays/prod            # mirar antes de aplicar# look before applying# guardare prima di applicare
k apply -k overlays/prod
k apply -k overlays/staging
k get deploy -n m3-kustomize -l env=staging   # staging-store 3/3# staging-store 3/3# staging-store 3/3
Claves
Key points
Punti chiave
  • El overlay referencia la base con resources: - ../../base: no copia manifiestos.
  • namePrefix renombra todo y actualiza las referencias cruzadas — el Service sigue apuntando bien al Deployment renombrado.
  • Un overlay apila transformers: acá conviven namePrefix + labels + replicas, y podrías sumar images.
  • includeSelectors: true solo sobre recursos nuevos. Sobre uno que ya corre, el selector es inmutable y el apply falla.
  • The overlay references the base with resources: - ../../base: it copies no manifests.
  • namePrefix renames everything and fixes cross-references — the Service still points correctly at the renamed Deployment.
  • An overlay stacks transformers: here namePrefix + labels + replicas coexist, and you could add images.
  • includeSelectors: true only on fresh resources. On one already running the selector is immutable and the apply fails.
  • L'overlay referenzia la base con resources: - ../../base: non copia manifest.
  • namePrefix rinomina tutto e sistema i riferimenti incrociati — il Service continua a puntare bene al Deployment rinominato.
  • Un overlay impila transformer: qui convivono namePrefix + labels + replicas, e potresti aggiungere images.
  • includeSelectors: true solo su risorse nuove. Su una già in esecuzione il selector è immutabile e l'apply fallisce.
E5

Troubleshooting — el overlay que no aplica

Troubleshooting — the overlay that will not apply

Troubleshooting — l'overlay che non si applica

~4 min

Un compañero dejó ~/m3/kustomize/overlays/dev/. Al aplicarlo falla con accumulating resources … no such file or directory. Diagnosticá y hacé que apply -k overlays/dev funcione.

A colleague left ~/m3/kustomize/overlays/dev/. Applying it fails with accumulating resources … no such file or directory. Diagnose it and make apply -k overlays/dev work.

Un collega ha lasciato ~/m3/kustomize/overlays/dev/. Applicandolo fallisce con accumulating resources … no such file or directory. Diagnostica e fai funzionare apply -k overlays/dev.

Ver soluciónShow solutionMostra soluzione
k apply -k overlays/dev                 # reproducir el error# reproduce the error# riprodurre l'errore
cat overlays/dev/kustomization.yaml
#   resources:  - ../base    ← un nivel de menos#   resources:  - ../base    ← one level short#   resources:  - ../base    ← un livello di meno

sed -i 's#\.\./base#../../base#' overlays/dev/kustomization.yaml
k apply -k overlays/dev
k get deploy store -n m3-kustomize
Claves
Key points
Punti chiave
  • Los paths de resources: son relativos al directorio del kustomization.yaml que los declara, no a donde estás parado.
  • Desde overlays/dev/ hay que subir dos niveles: ../../base.
  • Es el error de paths más común de kustomize, y el mensaje lo dice literal: accumulating resources.
  • resources: paths are relative to the directory of the kustomization.yaml that declares them, not to where you are standing.
  • From overlays/dev/ you must climb two levels: ../../base.
  • It is kustomize's most common path error, and the message says so literally: accumulating resources.
  • I path di resources: sono relativi alla directory del kustomization.yaml che li dichiara, non a dove ti trovi.
  • Da overlays/dev/ devi salire di due livelli: ../../base.
  • È l'errore di path più comune di kustomize, e il messaggio lo dice alla lettera: accumulating resources.
E6

CRDs — instalar un tipo nuevo, usarlo y explorarlo

CRDs — install a new type, use it and explore it

CRD — installare un tipo nuovo, usarlo ed esplorarlo

~6 min

En ~/m3/crd/ hay backup-crd.yaml (define el tipo Backup) y mybackup.yaml (un recurso de ese tipo).

  1. Instalá el CRD y confirmá que el cluster conoce el tipo.
  2. Creá el recurso en m3-crd y listalo.
  3. Mostrá los campos del spec de Backup sin abrir el YAML del CRD.
  4. Creá un segundo Backup weekly-backup.

~/m3/crd/ holds backup-crd.yaml (defines the Backup type) and mybackup.yaml (a resource of that type).

  1. Install the CRD and confirm the cluster knows the type.
  2. Create the resource in m3-crd and list it.
  3. Show the fields of Backup's spec without opening the CRD's YAML.
  4. Create a second Backup called weekly-backup.

In ~/m3/crd/ ci sono backup-crd.yaml (definisce il tipo Backup) e mybackup.yaml (una risorsa di quel tipo).

  1. Installa il CRD e conferma che il cluster conosce il tipo.
  2. Crea la risorsa in m3-crd ed elencala.
  3. Mostra i campi dello spec di Backup senza aprire lo YAML del CRD.
  4. Crea un secondo Backup chiamato weekly-backup.
Ver soluciónShow solutionMostra soluzione
k apply -f ~/m3/crd/backup-crd.yaml     # la DEFINICIÓN primero# the DEFINITION first# prima la DEFINIZIONE
k get crds | grep backups
k api-resources | grep -i backup

k apply -f ~/m3/crd/mybackup.yaml       # después la INSTANCIA# then the INSTANCE# poi l'ISTANZA
k get backups -n m3-crd
k describe backup daily-backup -n m3-crd

k explain backup.spec                   # destination, schedule# destination, schedule# destination, schedule

apiVersion: demo.cka.io/v1
kind: Backup
metadata:
  name: weekly-backup
  namespace: m3-crd
spec:
  schedule: "0 3 * * 0"
  destination: s3://backups/weekly
Claves
Key points
Punti chiave
  • CRD = definición, CR = instancia. Primero uno, después el otro; sin el CRD el kind no existe para el API server.
  • k explain anda con tipos custom porque lee el openAPIV3Schema del CRD — el mismo que valida tus manifiestos.
  • k get crds y k api-resources son la forma de descubrir qué tipos aprendió el cluster.
  • CRD = definition, CR = instance. One then the other; without the CRD the kind does not exist for the API server.
  • k explain works on custom types because it reads the CRD's openAPIV3Schema — the same one that validates your manifests.
  • k get crds and k api-resources are how you discover which types the cluster has learned.
  • CRD = definizione, CR = istanza. Prima uno, poi l'altro; senza il CRD il kind non esiste per l'API server.
  • k explain funziona sui tipi custom perché legge l'openAPIV3Schema del CRD — lo stesso che valida i tuoi manifest.
  • k get crds e k api-resources sono il modo di scoprire quali tipi ha imparato il cluster.
E7

Troubleshooting — no matches for kind (y el borrado en cascada)

Troubleshooting — no matches for kind (and the cascade delete)

Troubleshooting — no matches for kind (e la cancellazione a cascata)

~5 min

Te pasan ~/m3/crd/widget.yaml. Al aplicarlo: no matches for kind "Widget" in version "demo.cka.io/v1" — ensure CRDs are installed first. Diagnosticá y hacé que el recurso se cree.

Después, el gotcha: borrá el CRD widgets.demo.cka.io y fijate qué pasó con el CR w1. ¿Sigue vivo? ¿Por qué?

You are handed ~/m3/crd/widget.yaml. Applying it: no matches for kind "Widget" in version "demo.cka.io/v1" — ensure CRDs are installed first. Diagnose it and get the resource created.

Then, the gotcha: delete the CRD widgets.demo.cka.io and see what happened to the CR w1. Is it still alive? Why?

Ti passano ~/m3/crd/widget.yaml. Applicandolo: no matches for kind "Widget" in version "demo.cka.io/v1" — ensure CRDs are installed first. Diagnostica e fai creare la risorsa.

Poi il gotcha: cancella il CRD widgets.demo.cka.io e guarda cosa è successo al CR w1. È ancora vivo? Perché?

Ver soluciónShow solutionMostra soluzione
k apply -f ~/m3/crd/widget.yaml       # no matches for kind "Widget"# no matches for kind "Widget"# no matches for kind "Widget"
k get crds | grep widgets            # vacío → el cluster no lo conoce# empty → the cluster does not know it# vuoto → il cluster non lo conosce

k apply -f ~/m3/crd/widget-crd.yaml   # falta la DEFINICIÓN# the DEFINITION was missing# mancava la DEFINIZIONE
k apply -f ~/m3/crd/widget.yaml
k get widgets -n m3-crd

# el gotcha: borrar el CRD arrastra TODAS sus instancias# the gotcha: deleting the CRD drags ALL its instances with it# il gotcha: cancellare il CRD si porta via TUTTE le sue istanze
k delete crd widgets.demo.cka.io
k get widgets -n m3-crd
#   error: the server doesn't have a resource type "widgets"#   error: the server doesn't have a resource type "widgets"#   error: the server doesn't have a resource type "widgets"
Claves
Key points
Punti chiave
  • no matches for kind "X" = el API server no conoce el tipo → falta el CRD. El mensaje lo sugiere solo.
  • w1 no sobrevive: se fue con su tipo. Borrar un CRD borra en cascada todos sus CR, sin preguntar y sin vuelta atrás.
  • Por eso los CRDs son infraestructura. En producción, un delete crd distraído es un incidente.
  • no matches for kind "X" = the API server does not know the type → the CRD is missing. The message hints at it by itself.
  • w1 does not survive: it went with its type. Deleting a CRD cascade-deletes every CR, without asking and without undo.
  • That is why CRDs are infrastructure. In production, a careless delete crd is an incident.
  • no matches for kind "X" = l'API server non conosce il tipo → manca il CRD. Il messaggio lo suggerisce da solo.
  • w1 non sopravvive: se n'è andato con il suo tipo. Cancellare un CRD cancella a cascata ogni CR, senza chiedere e senza ritorno.
  • Ecco perché i CRD sono infrastruttura. In produzione, un delete crd distratto è un incidente.
✕

Limpieza

Cleanup

Pulizia

~1 min

Los CRDs son cluster-scoped: no se van con el namespace, hay que borrarlos aparte. Los releases de Helm sí viven en su namespace, pero conviene desinstalarlos para que no queden secrets huérfanos.

CRDs are cluster-scoped: they do not go away with the namespace, you delete them separately. Helm releases do live in their namespace, but uninstall them anyway so no orphan secrets are left behind.

I CRD sono cluster-scoped: non se ne vanno con il namespace, vanno cancellati a parte. I release Helm invece vivono nel loro namespace, ma conviene disinstallarli per non lasciare secret orfani.

helm list -A                                  # ¿queda algo?# anything left?# è rimasto qualcosa?
helm uninstall web api -n m3-helm 2>/dev/null
k delete crd backups.demo.cka.io widgets.demo.cka.io 2>/dev/null
k delete ns m3-helm m3-helm-ts m3-kustomize m3-crd

Autoevaluación — antes de marcar M3 como ★ dominado

Self-check — before marking M3 as ★ mastered

Autovalutazione — prima di segnare M3 come ★ padroneggiato

  • Ciclo Helm completo (install → upgrade → history → rollback → uninstall) con -n, en menos de 4 minutos.
  • Diagnosticar un release roto con helm history y helm get values --revision.
  • Renderizar sin aplicar (helm template / --dry-run) y combinar -f con --set.
  • Escribir un overlay que apile réplicas, imagen, prefijo y labels, y aplicarlo con apply -k.
  • Resolver un path roto de kustomize sabiendo que es relativo al kustomization.yaml.
  • Instalar un CRD y crear su CR en el orden correcto; leer el schema con explain.
  • Reconocer no matches for kind como CRD faltante, y saber que borrar el CRD se lleva los CR.
  • Full Helm cycle (install → upgrade → history → rollback → uninstall) with -n, in under 4 minutes.
  • Diagnose a broken release with helm history and helm get values --revision.
  • Render without applying (helm template / --dry-run) and combine -f with --set.
  • Write an overlay stacking replicas, image, prefix and labels, and apply it with apply -k.
  • Fix a broken kustomize path knowing it is relative to the kustomization.yaml.
  • Install a CRD and create its CR in the right order; read the schema with explain.
  • Recognise no matches for kind as a missing CRD, and know that deleting the CRD takes the CRs with it.
  • Ciclo Helm completo (install → upgrade → history → rollback → uninstall) con -n, in meno di 4 minuti.
  • Diagnosticare un release rotto con helm history e helm get values --revision.
  • Renderizzare senza applicare (helm template / --dry-run) e combinare -f con --set.
  • Scrivere un overlay che impila repliche, immagine, prefisso e label, e applicarlo con apply -k.
  • Risolvere un path rotto di kustomize sapendo che è relativo al kustomization.yaml.
  • Installare un CRD e creare il suo CR nell'ordine giusto; leggere lo schema con explain.
  • Riconoscere no matches for kind come CRD mancante, e sapere che cancellare il CRD si porta via i CR.
Módulo 3 completado · Cierra Cluster Architecture (25% del examen) · Siguiente: Workloads & Scheduling
Module 3 complete · Closes Cluster Architecture (25% of the exam) · Next: Workloads & Scheduling
Modulo 3 completato · Chiude Cluster Architecture (25% dell'esame) · Prossimo: Workloads & Scheduling