Portem tot el mòdul escrivint rutas-norte-dev a cada manifest i a cada ordre, sense haver-nos aturat a explicar què és exactament aquell namespace ni què ens dona. I al final de la lliçó anterior va aparèixer una propietat molt interessant: la configuració d'api-reserves apunta a redis-cache i a postgres-reserves pel seu nom curt, sense esmentar l'entorn, perquè el DNS ho resol dins del namespace on corre el pod. Aquella propietat és la que permet desplegar el mateix manifest tres vegades i obtenir tres plataformes independents. En aquesta lliçó muntem els tres entorns de Rutas Norte —rutas-norte-dev, rutas-norte-pre i rutas-norte-pro—, veurem què aïlla un namespace i què no aïlla en absolut (que és la part que més incidents provoca), distingirem els recursos amb i sense namespace, coneixerem els namespaces del sistema i per què mai no es desplega a default, treballarem còmodament amb -n i amb el context, resoldrem noms DNS entre namespaces, i acabarem amb un advertiment molt seriós sobre el que s'endú per davant un kubectl delete namespace.
Contingut
- Què és un namespace i què aïlla
- Recursos amb i sense namespace
- Els namespaces del sistema i per què no es desplega a
default - Els tres entorns de Rutas Norte
- El mateix manifest en diversos entorns
- Treballar amb namespaces sense tornar-se boig
- DNS entre namespaces
- Què NO garanteix un namespace
- Esborrar un namespace: l'ordre més perillosa de kubectl
- Namespaces enfront de clústers separats
- Què és un namespace i què aïlla
Un namespace és una partició lògica del clúster que agrupa recursos. La definició operativa, la que de debò serveix:
Un namespace és, sobretot, un espai de noms: dins d'ell, el nom de cada objecte ha de ser únic; fora, es pot repetir lliurement.
Això permet que existeixin simultàniament tres objectes anomenats api-reserves, un a cada entorn, sense col·lidir. I a partir d'aquí se'n deriven la resta d'usos.
El que un namespace sí que aporta:
| Funció | Què significa a la pràctica |
|---|---|
| Unicitat de noms | api-reserves pot existir a dev, pre i pro alhora |
| Àmbit de les consultes | kubectl get pods només mostra els del namespace actual |
| Punt d'ancoratge de les quotes | Un ResourceQuota limita el consum total d'un namespace (03-04) |
| Unitat de permisos de RBAC | Un Role concedeix permisos dins d'un namespace (08-01) |
| Subjecte de les polítiques de xarxa | Una NetworkPolicy pot seleccionar per namespace (04-06) |
| Àmbit del DNS curt | redis-cache resol al Service del namespace del pod que pregunta |
| Àmbit dels selectors | Un Service o un ReplicaSet només veuen pods del seu propi namespace |
| Esborrat en bloc | Esborrar el namespace elimina tot el que conté |
I el que no aporta, que veurem en detall a l'apartat 8: no aïlla la xarxa, no limita recursos per si sol, no impedeix l'accés i no separa els nodes.
flowchart TB
subgraph CL["Clúster minikube · perfil rutas-norte"]
subgraph DEV["namespace rutas-norte-dev"]
D1["Deployment api-reserves"]
D2["Service api-reserves"]
D3["Deployment postgres-reserves"]
end
subgraph PRE["namespace rutas-norte-pre"]
E1["Deployment api-reserves"]
E2["Service api-reserves"]
E3["Deployment postgres-reserves"]
end
subgraph SYS["namespace kube-system"]
S1["CoreDNS"]
S2["kube-proxy"]
end
NODES["Nodes, PersistentVolumes, StorageClasses<br/>(sense namespace: comuns a tot el clúster)"]
end
Fixa't en el detall clau del diagrama: els objectes amb el mateix nom conviuen en namespaces diferents, però els nodes són compartits. Un pod de rutas-norte-dev i un altre de rutas-norte-pre poden acabar a la mateixa màquina.
- Recursos amb i sense namespace
No tots els objectes de Kubernetes viuen dins d'un namespace. N'hi ha que pertanyen al clúster sencer, i confondre'ls genera errors desconcertants.
La manera de saber-ho amb certesa, sense memoritzar res:
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
pods po v1 true Pod
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSetNAME SHORTNAMES APIVERSION NAMESPACED KIND
componentstatuses cs v1 false ComponentStatus
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumes pv v1 false PersistentVolume
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
customresourcedefinitions crd apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
tokenreviews authentication.k8s.io/v1 false TokenReview
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
csidrivers storage.k8s.io/v1 false CSIDriver
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachmentLa lògica del repartiment és coherent: allò que representa infraestructura física o configuració global del clúster no porta namespace; allò que representa càrrega de treball o configuració d'aplicació, sí.
| Amb namespace | Sense namespace |
|---|---|
| Pod, Deployment, ReplicaSet, StatefulSet, DaemonSet, Job, CronJob | Node |
| Service, Endpoints, EndpointSlice, Ingress, NetworkPolicy | Namespace |
| ConfigMap, Secret, ServiceAccount | PersistentVolume, StorageClass, CSIDriver |
| PersistentVolumeClaim | ClusterRole, ClusterRoleBinding |
| Role, RoleBinding | CustomResourceDefinition, PriorityClass |
| ResourceQuota, LimitRange, HorizontalPodAutoscaler | IngressClass |
Dues parelles mereixen atenció perquè són font constant de confusió:
- PersistentVolume (sense namespace) enfront de PersistentVolumeClaim (amb namespace). El disc és un recurs del clúster; la reclamació d'aquell disc pertany a una aplicació concreta en un namespace. Mòdul 5.
- Role/RoleBinding (amb namespace) enfront de ClusterRole/ClusterRoleBinding (sense namespace). Els primers concedeixen permisos dins d'un namespace; els segons, a tot el clúster. Mòdul 8.
Un error pràctic derivat d'això:
El -n s'ha ignorat en silenci. Els nodes no tenen namespace, així que el flag no filtra res. No és un error, però pot fer-te creure que estàs veient alguna cosa filtrada quan no ho està.
- Els namespaces del sistema i per què no es desplega a
default
defaultTot clúster neix amb quatre namespaces:
NAME STATUS AGE
default Active 3d
kube-node-lease Active 3d
kube-public Active 3d
kube-system Active 3d
rutas-norte-dev Active 2d| Namespace | Contingut | L'has de tocar? |
|---|---|---|
default |
Buit al principi. És on van els objectes si no indiques namespace | No despleguis aquí |
kube-system |
Els components del mateix Kubernetes: CoreDNS, kube-proxy, controladors CSI, addons | Mai no despleguis aquí; mirar sí, tocar no |
kube-public |
Llegible sense autenticar; conté un ConfigMap amb dades públiques del clúster | Gairebé mai no es fa servir |
kube-node-lease |
Un objecte Lease per node, que el kubelet renova com a batec de vida |
Mai |
Fes una ullada a kube-system per veure el clúster per dins:
NAME READY STATUS RESTARTS AGE
coredns-668d6bf9bc-x8k2m 1/1 Running 0 3d
etcd-rutas-norte 1/1 Running 0 3d
kube-apiserver-rutas-norte 1/1 Running 0 3d
kube-controller-manager-rutas-norte 1/1 Running 0 3d
kube-proxy-7wfnz 1/1 Running 0 3d
kube-scheduler-rutas-norte 1/1 Running 0 3d
metrics-server-6d94bc8694-p4rzt 1/1 Running 0 3d
storage-provisioner 1/1 Running 0 3dAquí els tens, corrent com a pods, tots els components que vas estudiar a Arquitectura de Kubernetes. El pla de control del teu minikube és visible i palpable.
kube-node-lease explica una cosa que potser et vas preguntar: com sap el pla de control si un node continua viu.
El kubelet renova aquell objecte cada pocs segons. Si deixa de fer-ho, el node es marca NotReady.
Per què no es desplega a default
És el namespace que Kubernetes fa servir quan no dius res, i precisament per això és un mal lloc per treballar:
- És l'abocador del clúster. Tot el que algú apliqui sense
-nhi acaba. En pocs mesos és un calaix de sastre on ningú no sap què és de qui. - No es pot esborrar. Els namespaces del sistema són indestructibles, així que no el pots netejar d'un cop com faries amb
rutas-norte-dev. - Els accidents són fàcils. Un
kubectl delete deploy --allsense-n, executat creient ser en un altre lloc, s'endú per davant el que hi hagi adefault. - Impossibilita l'aïllament. Si tot és a
default, no pots aplicar quotes per equip, ni RBAC per entorn, ni polítiques de xarxa diferenciades. - Impedeix reutilitzar noms. Amb tot en un mateix namespace,
api-reservesde desenvolupament i de producció no poden coexistir.
La regla del projecte és explícita:
A Rutas Norte,
defaultestà prohibit. Tot objecte viu en un namespace anomenat, declarat al seu propi manifest.
- Els tres entorns de Rutas Norte
Ha arribat el moment de crear l'estructura completa. Ja coneixes rutas-norte-dev del mòdul 1; hi afegim preproducció i producció, de forma declarativa i en un sol fitxer.
En YAML, --- separa diversos documents dins d'un mateix fitxer. És la manera habitual d'agrupar objectes relacionats:
# k8s/base/namespaces.yaml
apiVersion: v1
kind: Namespace
metadata:
name: rutas-norte-dev
labels:
app.kubernetes.io/part-of: rutas-norte
entorn: dev
---
apiVersion: v1
kind: Namespace
metadata:
name: rutas-norte-pre
labels:
app.kubernetes.io/part-of: rutas-norte
entorn: pre
---
apiVersion: v1
kind: Namespace
metadata:
name: rutas-norte-pro
labels:
app.kubernetes.io/part-of: rutas-norte
entorn: pro
annotations:
rutasnorte.example/responsable: [email protected]
rutasnorte.example/avis: "Entorn productiu. Canvis només per canalització."kubectl apply -f k8s/base/namespaces.yaml
kubectl get namespaces -l app.kubernetes.io/part-of=rutas-nortenamespace/rutas-norte-dev configured
namespace/rutas-norte-pre created
namespace/rutas-norte-pro created
NAME STATUS AGE
rutas-norte-dev Active 2d
rutas-norte-pre Active 4s
rutas-norte-pro Active 4sFixa't en dues decisions deliberades:
- Els namespaces porten etiquetes. No és decoratiu: al mòdul 4, les NetworkPolicies seleccionaran namespaces per l'etiqueta
entorn, i així una política podrà dir "només accepto trànsit de pods del mateix entorn". - Producció porta anotacions informatives. Qualsevol que faci
kubectl describe ns rutas-norte-prosabrà a qui avisar i quines regles hi regeixen.
L'estructura del repositori que ja tenim definida hi encaixa de manera natural:
k8s/
├── base/ # manifests comuns als tres entorns
│ ├── namespaces.yaml
│ ├── botiga-web-deployment.yaml
│ ├── botiga-web-service.yaml
│ ├── api-reserves-deployment.yaml
│ └── ...
└── entorns/
├── dev/ # diferències de l'entorn de desenvolupament
├── pre/
└── pro/Com es combinen base i entorns sense duplicar YAML és feina de Kustomize o Helm, a 10-04 i 10-03. En aquest mòdul ho farem de la manera més simple possible.
- El mateix manifest en diversos entorns
Aquí hi ha la propietat que fa valuosos els namespaces. Desplegarem botiga-web i el seu Service a preproducció fent servir exactament els mateixos fitxers que a desenvolupament.
Els nostres manifests porten namespace: rutas-norte-dev escrit a dins, així que hi ha dues maneres de portar-los a un altre entorn.
Opció A: treure el namespace del manifest i decidir-lo en aplicar.
# k8s/base/botiga-web-deployment.yaml (fragment, sense namespace)
apiVersion: apps/v1
kind: Deployment
metadata:
name: botiga-web
# sense camp namespace: el decideix qui aplica
labels:
app: botiga-web
app.kubernetes.io/part-of: rutas-nortekubectl apply -f k8s/base/botiga-web-deployment.yaml -n rutas-norte-pre
kubectl apply -f k8s/base/botiga-web-service.yaml -n rutas-norte-preOpció B: mantenir el namespace al manifest i substituir-lo en desplegar. És el que faran Kustomize o Helm per tu; a mà es veuria així:
sed 's/rutas-norte-dev/rutas-norte-pre/g' k8s/base/botiga-web-deployment.yaml | kubectl apply -f -
sed 's/rutas-norte-dev/rutas-norte-pre/g' k8s/base/botiga-web-service.yaml | kubectl apply -f -Hi ha una regla important que convé conèixer: si un manifest declara metadata.namespace i a més hi passes -n amb un valor diferent, kubectl dona error en lloc de triar pel seu compte.
error: the namespace from the provided object "rutas-norte-dev" does not match
the namespace "rutas-norte-pre". You must pass '--namespace=rutas-norte-dev' to perform this operation.És un comportament desitjable: evita desplegar a producció per accident.
Fem-ho amb l'opció B, que respecta els nostres manifests actuals:
for f in botiga-web-deployment botiga-web-service api-reserves-deployment api-reserves-service redis-cache-deployment redis-cache-service; do
sed 's/rutas-norte-dev/rutas-norte-pre/g' k8s/base/$f.yaml | kubectl apply -f -
done
kubectl get deploy,svc -n rutas-norte-preNAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/api-reserves 2/2 2 2 25s
deployment.apps/botiga-web 3/3 3 3 26s
deployment.apps/redis-cache 1/1 1 1 24s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/api-reserves ClusterIP 10.96.229.14 <none> 3000/TCP 25s
service/botiga-web ClusterIP 10.96.44.71 <none> 80/TCP 26s
service/redis-cache ClusterIP 10.96.88.107 <none> 6379/TCP 24sAra observa la situació completa del clúster:
NAMESPACE NAME READY STATUS RESTARTS AGE
rutas-norte-dev api-reserves-7f1d3e942-b8mrs 1/1 Running 0 48m
rutas-norte-dev api-reserves-7f1d3e942-n4jvt 1/1 Running 0 48m
rutas-norte-dev botiga-web-6f9c4b8d7-42kxr 1/1 Running 0 55m
rutas-norte-dev botiga-web-6f9c4b8d7-8vnwq 1/1 Running 0 55m
rutas-norte-dev botiga-web-6f9c4b8d7-t9mzd 1/1 Running 0 55m
rutas-norte-dev postgres-reserves-59d7c4b8f-k3xqp 1/1 Running 0 40m
rutas-norte-dev redis-cache-6c8f9d745-w2mtb 1/1 Running 0 52m
rutas-norte-pre api-reserves-7f1d3e942-c9plk 1/1 Running 0 1m
rutas-norte-pre api-reserves-7f1d3e942-r5vwj 1/1 Running 0 1m
rutas-norte-pre botiga-web-6f9c4b8d7-d3jbx 1/1 Running 0 1m
rutas-norte-pre botiga-web-6f9c4b8d7-m7kwr 1/1 Running 0 1m
rutas-norte-pre botiga-web-6f9c4b8d7-p2fst 1/1 Running 0 1m
rutas-norte-pre redis-cache-6c8f9d745-h8nqz 1/1 Running 0 1mDues plataformes Rutas Norte completes, amb els mateixos noms de Deployment i de Service, convivint sense la menor col·lisió. Aquest és el valor central del namespace.
I una comprovació que il·lustra l'aïllament de noms:
kubectl get svc api-reserves -n rutas-norte-dev -o jsonpath='{.spec.clusterIP}{"\n"}'
kubectl get svc api-reserves -n rutas-norte-pre -o jsonpath='{.spec.clusterIP}{"\n"}'Mateix nom, dos objectes diferents, dues IPs virtuals diferents.
- Treballar amb namespaces sense tornar-se boig
Escriure -n rutas-norte-dev cent vegades al dia és tediós i, pitjor, oblidar-ho és la via ràpida a un accident.
El flag -n i -A
kubectl get pods -n rutas-norte-pre # un namespace concret
kubectl get pods --all-namespaces # tots
kubectl get pods -A # abreviatura de l'anterior-A és imprescindible quan busques alguna cosa i no recordes on és:
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
rutas-norte-dev api-reserves 2/2 2 2 50m
rutas-norte-pre api-reserves 2/2 2 2 3mFixar el namespace del context
És l'opció que més temps estalvia. Modifica el teu kubeconfig perquè totes les ordres facin servir aquell namespace per defecte:
Context "rutas-norte" modified.
NAME READY STATUS RESTARTS AGE
api-reserves-7f1d3e942-c9plk 1/1 Running 0 4m
api-reserves-7f1d3e942-r5vwj 1/1 Running 0 4m
botiga-web-6f9c4b8d7-d3jbx 1/1 Running 0 4m
botiga-web-6f9c4b8d7-m7kwr 1/1 Running 0 4m
botiga-web-6f9c4b8d7-p2fst 1/1 Running 0 4m
redis-cache-6c8f9d745-h8nqz 1/1 Running 0 4mI la comprovació que hauries de convertir en un reflex abans de qualsevol ordre destructiva:
Consell molt recomanable: configura el prompt de la teva terminal perquè mostri context i namespace. Eines com kube-ps1 ho fan, i veure (rutas-norte:rutas-norte-pro) a la pantalla abans de teclejar delete ha salvat moltes tardes.
kubens
Del conjunt kubectx, kubens canvia de namespace de forma interactiva:
kubens # llista els namespaces i marca l'actual
kubens rutas-norte-pro # canvia a produccio
kubens - # torna a l'anteriorÉs sucre sintàctic sobre kubectl config set-context, però amb llistat interactiu i salt ràpid a l'anterior. S'instal·la com a binari solt o mitjançant krew, el gestor de connectors de kubectl que vam veure a La CLI de Kubernetes.
Torna a desenvolupament abans de continuar:
- DNS entre namespaces
Ja coneixes el nom complet d'un Service: <servei>.<namespace>.svc.cluster.local. Els namespaces són la raó que existeixi aquella estructura.
Quan un pod resol un nom, el DNS del clúster prova una sèrie de sufixos de cerca en ordre. Mira'ls en un pod real:
search rutas-norte-dev.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5La primera línia explica tot el comportament: en buscar redis-cache, el pod prova primer redis-cache.rutas-norte-dev.svc.cluster.local. Com que existeix, allà s'acaba. El nom curt sempre resol dins del propi namespace.
Des d'un pod de rutas-norte-dev, si escriu... |
Resol a... |
|---|---|
redis-cache |
redis-cache.rutas-norte-dev.svc.cluster.local |
redis-cache.rutas-norte-pre |
redis-cache.rutas-norte-pre.svc.cluster.local |
redis-cache.rutas-norte-pro.svc.cluster.local |
Aquest mateix, sense ambigüitat |
Comprova-ho:
kubectl run test-dns --rm -it --image=busybox:1.36 --restart=Never -n rutas-norte-dev -- \
sh -c 'nslookup api-reserves; nslookup api-reserves.rutas-norte-pre'Name: api-reserves.rutas-norte-dev.svc.cluster.local
Address: 10.96.184.22
Name: api-reserves.rutas-norte-pre.svc.cluster.local
Address: 10.96.229.14
pod "test-dns" deletedAquí hi ha dues notícies. La bona: el mateix manifest d'api-reserves, amb DATABASE_HOST: postgres-reserves, funciona als tres entorns i cadascun parla amb la seva pròpia base de dades, sense condicionals ni plantilles.
La dolenta, i és important: un pod de desenvolupament acaba de resoldre i es podria connectar a un Service de preproducció. No hi ha res que ho impedeixi. Això ens porta directament a l'apartat següent.
- Què NO garanteix un namespace
Aquest és l'apartat que evita incidents. La creença que "cada equip al seu namespace i així estan aïllats" és perillosament falsa.
No és una frontera de xarxa
Per defecte, qualsevol pod de qualsevol namespace es pot connectar a qualsevol pod o Service de qualsevol altre namespace. El model de xarxa pla de Kubernetes és explícit en això: tots els pods es veuen entre ells.
Demostració incòmoda: un pod de desenvolupament escrivint a la memòria cau de preproducció.
kubectl run intrus --rm -it --image=redis:7.2-alpine --restart=Never -n rutas-norte-dev -- \
redis-cli -h redis-cache.rutas-norte-pre SET places:BIL-SAN:2026-08-14 0Acabem de posar a zero les places disponibles a la memòria cau de preproducció des de desenvolupament. Si hagués estat rutas-norte-pro, seria un incident seriós. I ningú no ha necessitat permisos especials: n'hi ha hagut prou amb conèixer el nom.
La solució no és el namespace, són les NetworkPolicies de 04-06, que sí que permeten declarar regles del tipus "postgres-reserves només accepta connexions de pods amb l'etiqueta app=api-reserves del mateix namespace".
No és una frontera de seguretat ni de permisos
Crear un namespace no restringeix qui pot fer què dins d'ell. Si les teves credencials tenen permisos amplis sobre el clúster, els tens sobre tots els namespaces, existents i futurs.
Amb un usuari d'administrador, la resposta és yes per a qualsevol namespace. L'aïllament de permisos el donen els Role i RoleBinding de RBAC. El namespace és només l'àmbit sobre el qual aquelles regles s'apliquen: necessari, però no suficient.
No limita el consum de recursos
Un namespace no imposa cap sostre. Un Deployment mal configurat a rutas-norte-dev pot consumir tota la CPU i la memòria del clúster i deixar sense recursos els pods de rutas-norte-pro, perquè comparteixen els mateixos nodes.
Name: rutas-norte-dev
Labels: app.kubernetes.io/part-of=rutas-norte
entorn=dev
Status: Active
No resource quota.
No LimitRange resource.Aquelles dues línies finals ho diuen tot: sense quota i sense límits. Posar-los és matèria de Quotes i Límits de Recursos i LimitRanges i QoS.
No aïlla els nodes
Els pods de tots els namespaces es reparteixen pels mateixos nodes. Un pod de desenvolupament i un de producció poden ser veïns a la mateixa màquina, compartint CPU, memòria i disc.
kubectl get pods -A -l app=botiga-web -o custom-columns=NS:.metadata.namespace,POD:.metadata.name,NODE:.spec.nodeNameNS POD NODE
rutas-norte-dev botiga-web-6f9c4b8d7-42kxr rutas-norte
rutas-norte-pre botiga-web-6f9c4b8d7-d3jbx rutas-norteSeparar càrregues per nodes requereix taints, toleracions i afinitat (06-05).
Resum honest
| Creença habitual | Realitat |
|---|---|
| "Els namespaces aïllen la xarxa" | Fals. Tot es veu amb tot. Calen NetworkPolicies |
| "Els namespaces aïllen permisos" | Fals per si sols. Calen Roles i RoleBindings |
| "Un namespace no pot consumir recursos d'un altre" | Fals. Cal ResourceQuota |
| "Producció està protegida per ser en un altre namespace" | Fals. És una separació organitzativa, no una barrera |
| "Els namespaces separen els nodes" | Fals. Els nodes són comuns |
| "Els namespaces eviten col·lisions de noms" | Cert. Aquesta sí que és la seva funció nativa |
La frase que resumeix l'apartat: el namespace és l'àmbit sobre el qual s'apliquen els mecanismes d'aïllament, no el mecanisme d'aïllament. Sense quotes, RBAC i polítiques de xarxa a sobre, un namespace és només una carpeta.
- Esborrar un namespace: l'ordre més perillosa de kubectl
Aquella ordre esborra tot el que hi ha a dins: Deployments, ReplicaSets, Pods, Services, ConfigMaps, Secrets, PersistentVolumeClaims, ServiceAccounts, Roles... I amb els PVC se'n van, segons la política de recuperació, les dades.
Característiques que la fan especialment perillosa:
- No demana confirmació. Cap.
- No hi ha desfer. No existeix paperera ni
kubectl undelete. - És asíncrona. El namespace passa a estat
Terminatingmentre s'esborra el contingut, i en aquell estat no admet objectes nous. - Un error de teclat és catastròfic.
rutas-norte-proen lloc derutas-norte-presón tres caràcters de diferència.
Mira-ho en acció, amb un namespace d'usar i llençar:
kubectl create namespace prova-esborrat
kubectl run temporal --image=nginx:1.27-alpine -n prova-esborrat
kubectl delete namespace prova-esborrat
kubectl get namespace prova-esborratnamespace/prova-esborrat created
pod/temporal created
namespace "prova-esborrat" deleted
Error from server (NotFound): namespaces "prova-esborrat" not foundEl pod se'n va anar amb ell, sense preguntar res.
Namespaces encallats en Terminating
Un problema que trobaràs tard o d'hora: un namespace que es queda en Terminating indefinidament. La causa és gairebé sempre un finalizer —aquells ganxos que vam estudiar a Objectes i Manifests— que no es pot completar, típicament el d'una API estesa el servidor de la qual ja no existeix.
kubectl get namespace rutas-norte-pre -o jsonpath='{.spec.finalizers}{"\n"}'
kubectl get namespace rutas-norte-pre -o jsonpath='{.status.conditions}' | python3 -m json.toolAbans de forçar res, esbrina quin recurs està bloquejant, perquè treure el finalizer a la brava deixa objectes orfes a etcd. La manera correcta és eliminar el recurs conflictiu o restaurar el servei que l'ha de processar.
Mesures de protecció per a Rutas Norte
- Etiquetar i anotar producció, com vam fer a
namespaces.yaml: en descriure el namespace es llegeix l'avís. - RBAC restrictiu: ningú no té permís de
delete namespacesarutas-norte-protret d'un parell de persones (08-01). - Verificar el context abans de qualsevol esborrat, amb el reflex de l'apartat 6.
- Còpies de seguretat: l'única xarxa real. Eines com Velero permeten restaurar un namespace sencer, i és matèria de Còpies de Seguretat i Restauració.
- Comprovar abans de disparar, sempre:
Un bon hàbit addicional: fer servir --dry-run=client mentalment. Abans d'esborrar, pregunta't en veu alta quin namespace estàs mirant.
Deixa preproducció muntada, la continuarem fent servir:
- Namespaces enfront de clústers separats
La pregunta estratègica: han de viure els tres entorns de Rutas Norte en un clúster amb tres namespaces, o en tres clústers separats?
| Criteri | Namespaces en un clúster | Clústers separats |
|---|---|---|
| Cost | Un pla de control, nodes compartits: molt més barat | Multiplicat pel nombre de clústers |
| Aïllament real | Lògic; requereix quotes, RBAC i NetworkPolicies ben fetes | Total: infraestructura diferent |
| Radi d'impacte d'una fallada | Un problema del pla de control afecta tot | Un clúster caigut no toca els altres |
| Versió de Kubernetes | La mateixa per a tots els entorns | Cadascun la seva: es pot provar una actualització a pre |
| Complexitat operativa | Baixa: un kubeconfig, un joc d'eines | Alta: multiplica monitoratge, actualitzacions i accessos |
| Risc d'error humà | Alt: un -n mal posat toca producció |
Baix: canviar de clúster és un acte conscient |
| Compliment normatiu | Difícil de justificar davant d'un auditor | Fàcil de justificar |
| Latència entre entorns | Nul·la, comparteixen xarxa | Requereix connectivitat externa |
Criteris pràctics de decisió:
Namespaces en un clúster quan:
- Els entorns són de confiança equivalent (dev i pre del mateix equip).
- L'equip és petit i el pressupost limitat.
- Es domina RBAC, quotes i polítiques de xarxa.
Clústers separats quan:
- Hi ha dades regulades: personals, sanitàries, financeres.
- S'ofereix servei a clients que no es fien entre ells (multi-tenant real).
- Calen versions diferents de Kubernetes o de components del clúster.
- Una fallada de producció no pot dependre de la salut d'un entorn de proves.
La decisió de Rutas Norte
L'empresa té dades personals de clients —nom, DNI, telèfon i correu— a postgres-reserves. La decisió, i el seu perquè:
| Entorn | Ubicació | Justificació |
|---|---|---|
rutas-norte-dev |
Namespace al clúster de no producció | Dades anonimitzades, cost mínim, iteració ràpida |
rutas-norte-pre |
Namespace al mateix clúster que dev | Rèplica funcional de producció amb dades fictícies |
rutas-norte-pro |
Clúster propi i separat | Dades personals reals, requisits de disponibilitat i auditoria, radi d'impacte acotat |
És a dir: dos clústers, tres namespaces. El namespace rutas-norte-pro existeix també al clúster de no producció perquè els manifests siguin idèntics i es pugui assajar el desplegament, però la producció real viu a part.
Durant el curs treballarem amb un sol minikube i els tres namespaces, que és el pràctic per aprendre. La gestió de diversos clústers alhora, amb els seus contextos i les seves eines, es tracta a Gestió Multi-Clúster.
Un últim apunt sobre com organitzar namespaces: per entorn (el que fem), per equip (equip-pagaments, equip-rutes) o per aplicació (rutas-norte, intranet). L'habitual és combinar dos eixos: rutas-norte-pro, intranet-pro. El que mai no funciona és un namespace per microservei: multiplica la burocràcia sense aportar aïllament útil.
Errors Comuns i Consells
- Desplegar a
defaultper oblit. El símptoma éskubectl get podssense resultats on esperaves veure'ls. Comprova-ho ambkubectl get pods -A -l app=<component>. - Creure que un namespace aïlla la xarxa. No ho fa. Qualsevol pod es pot connectar a qualsevol Service d'un altre namespace coneixent-ne el nom.
- Creure que un namespace aïlla permisos o recursos. Calen RBAC i ResourceQuota. El namespace és l'àmbit, no el mecanisme.
- Posar
-na un recurs sense namespace.kubectl get nodes -n elquesiguiignora el flag en silenci i et pot confondre. - Discrepància entre
metadata.namespacei-n.kubectldona error en lloc de decidir per tu. És una protecció, no una molèstia. - Buscar al namespace equivocat i concloure que alguna cosa no existeix. Davant del dubte,
-A. - Esborrar un namespace sense mirar què conté. No hi ha confirmació ni desfer.
kubectl get all -n <ns>abans, sempre. - Forçar l'esborrat d'un namespace encallat traient-li els finalizers. Deixa objectes orfes a etcd. Investiga primer quin recurs el bloqueja.
- Un namespace per microservei. Multiplica la càrrega administrativa sense aportar aïllament real. Organitza per entorn, equip o aplicació.
- Consell: configura el prompt perquè mostri context i namespace (
kube-ps1). Veure(rutas-norte:rutas-norte-pro)abans de teclejardeleteevita accidents. - Consell: declara
metadata.namespaceals manifests que siguin específics d'un entorn i omet-lo als que siguin genèrics. L'ambigüitat és el que provoca desplegaments al lloc equivocat. - Consell: etiqueta sempre els teus namespaces. Les NetworkPolicies del mòdul 4 seleccionaran namespaces per etiqueta, i sense elles hauràs de tornar enrere a posar-les.
Exercicis
Exercici 1: Classificar recursos i explorar el sistema
- Amb una sola ordre, compta quants tipus de recursos tenen namespace i quants no.
- Determina, sense consultar taules, si aquests recursos porten namespace:
PersistentVolume,PersistentVolumeClaim,Role,ClusterRole,Ingress,StorageClass. - Llista els pods de
kube-systemi identifica quins són els cinc components del pla de control que vas estudiar al mòdul 1. - Esbrina què hi ha dins de
kube-publici explica què té de particular aquell namespace.
Exercici 2: Desplegar la plataforma a producció i comprovar l'aïllament
- Desplega
botiga-web(Deployment i Service) arutas-norte-pro, amb l'etiquetaentorn: proen lloc dedev. - Demostra amb una sola ordre que existeixen tres Deployments anomenats
botiga-webal clúster, en namespaces diferents. - Comprova que les
ClusterIPdels tres Servicesbotiga-websón diferents. - Des d'un pod efímer a
rutas-norte-dev, fes una petició HTTP albotiga-webderutas-norte-profent servir el nom DNS complet. Funciona? Explica què implica això i quin objecte caldria crear per impedir-ho.
Exercici 3: Auditoria de namespaces
T'incorpores a l'equip de plataforma de Rutas Norte i t'encarreguen una auditoria ràpida del clúster. Respon amb ordres i la seva sortida:
- Quins namespaces existeixen i quins pertanyen a la plataforma Rutas Norte?
- Hi ha algun objecte desplegat a
default? Si n'hi ha, mou-lo al namespace correcte. - Quins namespaces tenen
ResourceQuotadefinida? Què implica que no en tinguin? - Pots esborrar el namespace de producció amb les teves credencials actuals? Quin mecanisme ho hauria d'impedir i en quina lliçó s'estudia?
- Elabora una taula amb els tres entorns indicant: nombre de pods, nombre de Services i si tenen quota.
Solucions
Solució 1
echo "Amb namespace: $(kubectl api-resources --namespaced=true --no-headers | wc -l)"
echo "Sense namespace: $(kubectl api-resources --namespaced=false --no-headers | wc -l)"Els números varien segons els CRDs i els addons instal·lats al teu clúster.
- El raonament, abans de comprovar-ho: porta namespace allò que pertany a una aplicació concreta; no en porta allò que és infraestructura o configuració global.
| Recurs | Namespace? | Raonament |
|---|---|---|
PersistentVolume |
No | És un disc del clúster, existeix abans que ningú el reclami |
PersistentVolumeClaim |
Sí | És la petició d'una aplicació concreta |
Role |
Sí | Concedeix permisos dins d'un namespace |
ClusterRole |
No | Concedeix permisos a tot el clúster |
Ingress |
Sí | Enruta cap a Services, que tenen namespace |
StorageClass |
No | Defineix un tipus d'emmagatzematge disponible per a tot el clúster |
kubectl api-resources --no-headers | grep -E "^(persistentvolumes|persistentvolumeclaims|roles|clusterroles|ingresses|storageclasses) "persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
storageclasses sc storage.k8s.io/v1 false StorageClass
ingresses ing networking.k8s.io/v1 true Ingress
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
roles rbac.authorization.k8s.io/v1 true Role# 3. Components del pla de control
kubectl get pods -n kube-system --no-headers | awk '{print $1}' | grep -E "apiserver|etcd|scheduler|controller-manager|coredns"coredns-668d6bf9bc-x8k2m
etcd-rutas-norte
kube-apiserver-rutas-norte
kube-controller-manager-rutas-norte
kube-scheduler-rutas-norteEls cinc: kube-apiserver (l'única porta a l'API), etcd (el magatzem d'estat), kube-scheduler (assigna pods a nodes), kube-controller-manager (on viuen els controladors de ReplicaSet, Deployment, endpoints...) i CoreDNS (que resol els noms de Service que vam fer servir a la lliçó anterior).
# 4. kube-public
kubectl get configmaps -n kube-public
kubectl get configmap cluster-info -n kube-public -o jsonpath='{.data.jws-kubeconfig-*}' | head -3kube-public és l'únic namespace llegible sense autenticar-se: qualsevol que arribi a l'apiserver pot llegir-ne el contingut. Conté cluster-info, amb les dades que un node necessita per unir-se al clúster durant el procés de kubeadm join. Per això mai no s'hi ha de guardar res sensible.
Solució 2
# 1. Desplegar a produccio
for f in botiga-web-deployment botiga-web-service; do
sed -e 's/rutas-norte-dev/rutas-norte-pro/g' -e 's/entorn: dev/entorn: pro/g' \
k8s/base/$f.yaml | kubectl apply -f -
done
kubectl get deploy,svc -n rutas-norte-prodeployment.apps/botiga-web created
service/botiga-web created
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/botiga-web 3/3 3 3 15s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/botiga-web ClusterIP 10.96.171.55 <none> 80/TCP 15sNAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
rutas-norte-dev botiga-web 3/3 3 3 1h
rutas-norte-pre botiga-web 3/3 3 3 35m
rutas-norte-pro botiga-web 3/3 3 3 1m# 3. Tres ClusterIP diferents
kubectl get svc botiga-web -A -o custom-columns=NS:.metadata.namespace,NOM:.metadata.name,IP:.spec.clusterIPNS NOM IP
rutas-norte-dev botiga-web 10.96.12.209
rutas-norte-pre botiga-web 10.96.44.71
rutas-norte-pro botiga-web 10.96.171.55# 4. Des de dev cap a pro
kubectl run intrus --rm -it --image=curlimages/curl:8.8.0 --restart=Never -n rutas-norte-dev -- \
curl -s -o /dev/null -w "%{http_code}\n" http://botiga-web.rutas-norte-pro.svc.cluster.local/Funciona. Un pod de desenvolupament ha accedit sense cap obstacle a un servei de producció. Implicació directa: el namespace no és una frontera de xarxa. En el model per defecte de Kubernetes, tots els pods es veuen entre ells, i n'hi ha prou amb conèixer el nom DNS per connectar-s'hi.
Per impedir-ho cal una NetworkPolicy a rutas-norte-pro que rebutgi tot el trànsit entrant tret del que provingui de namespaces amb l'etiqueta entorn: pro (per això vam etiquetar els namespaces en crear-los). És el contingut de Polítiques de Xarxa i Seguretat de Xarxa.
Solució 3
# 1. Namespaces existents i els de la plataforma
kubectl get ns
kubectl get ns -l app.kubernetes.io/part-of=rutas-norteNAME STATUS AGE
default Active 3d
kube-node-lease Active 3d
kube-public Active 3d
kube-system Active 3d
rutas-norte-dev Active 2d
rutas-norte-pre Active 40m
rutas-norte-pro Active 40m
NAME STATUS AGE
rutas-norte-dev Active 2d
rutas-norte-pre Active 40m
rutas-norte-pro Active 40mL'etiqueta comuna permet distingir d'un cop d'ull els namespaces de la plataforma dels del sistema.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3dNomés apareix service/kubernetes, que és el Service del mateix apiserver i ha de ser-hi: és el que permet als pods parlar amb l'API. Si hi hagués qualsevol altra cosa, el procediment seria exportar-la, corregir-ne el namespace i tornar-la a aplicar:
kubectl get deploy <nom> -n default -o yaml > /tmp/objecte.yaml
# editar metadata.namespace i treure metadata.uid, resourceVersion i status
kubectl apply -f /tmp/objecte.yaml -n rutas-norte-dev
kubectl delete deploy <nom> -n defaultCap namespace no té quota. Implicació: qualsevol Deployment de rutas-norte-dev pot consumir tota la CPU i la memòria del clúster i deixar sense recursos els pods de rutas-norte-pro, perquè comparteixen nodes. Un bucle mal escrit a desenvolupament pot tombar la producció. Es corregeix amb ResourceQuota i LimitRange a 03-04 i 03-05.
Sí que el puc esborrar, i amb ell tota la producció, sense confirmació i sense desfer. El que ho hauria d'impedir és RBAC: un Role/ClusterRole que no inclogui el verb delete sobre namespaces per a les credencials habituals, deixant aquell permís a un rol d'emergència fet servir per dues persones. S'estudia a Control d'Accés Basat en Rols. Com a xarxa de seguretat complementària, còpies de seguretat amb Velero (05-06).
# 5. Taula resum
for ns in rutas-norte-dev rutas-norte-pre rutas-norte-pro; do
pods=$(kubectl get pods -n $ns --no-headers 2>/dev/null | wc -l)
svcs=$(kubectl get svc -n $ns --no-headers 2>/dev/null | wc -l)
quota=$(kubectl get resourcequota -n $ns --no-headers 2>/dev/null | wc -l)
echo "$ns | $pods pods | $svcs services | quotes: $quota"
donerutas-norte-dev | 7 pods | 4 services | quotes: 0
rutas-norte-pre | 6 pods | 3 services | quotes: 0
rutas-norte-pro | 3 pods | 1 services | quotes: 0| Entorn | Pods | Services | Quota? | Observació |
|---|---|---|---|---|
rutas-norte-dev |
7 | 4 | No | Entorn complet: els quatre components desplegats |
rutas-norte-pre |
6 | 3 | No | Falta postgres-reserves |
rutas-norte-pro |
3 | 1 | No | Només botiga-web; sense quota és el risc més greu del clúster |
Conclusió
Els namespaces han deixat de ser aquella paraula que repetíem a cada ordre. Saps que la seva funció nativa és la unicitat de noms, i que d'ella se'n deriven l'àmbit de les consultes, dels selectors, del DNS curt, de les quotes, del RBAC i de les polítiques de xarxa. Distingeixes els recursos que porten namespace —pods, Deployments, Services, ConfigMaps, Secrets, PVCs— dels que pertanyen al clúster sencer —nodes, PersistentVolumes, StorageClasses, ClusterRoles—, i saps esbrinar-ho en qualsevol moment amb kubectl api-resources --namespaced. Coneixes els quatre namespaces del sistema, has vist el pla de control corrent com a pods a kube-system, i tens clar per què default és un abocador on Rutas Norte no desplega res.
Has muntat els tres entorns del projecte de forma declarativa i amb etiquetes que les NetworkPolicies aprofitaran després, i has desplegat els mateixos manifests en diversos d'ells comprovant que botiga-web i api-reserves conviuen amb idèntic nom en namespaces diferents, cadascun amb la seva pròpia ClusterIP i parlant amb la seva pròpia base de dades gràcies al DNS curt. Treballes amb -n, amb -A i fixant el namespace del context, amb el reflex de verificar on ets abans de qualsevol ordre destructiva.
I t'emportes els dos advertiments que més incidents eviten. El primer: un namespace no aïlla res per si sol. No és frontera de xarxa —ho has demostrat escrivint a la memòria cau de preproducció des de desenvolupament i cridant producció des d'un pod de dev—, no és frontera de permisos, no limita recursos i no separa nodes. És l'àmbit sobre el qual s'apliquen quotes, RBAC i polítiques de xarxa, que arribaran als mòduls 3, 4 i 8. El segon: kubectl delete namespace s'ho endú tot sense confirmació i sense marxa enrere, motiu pel qual la producció real de Rutas Norte viu en un clúster a part.
Queda un fil solt que ha recorregut tot el mòdul. Els selectors dels ReplicaSets, els selectors dels Services, l'etiqueta entorn dels namespaces, l'anotació kubernetes.io/change-cause de l'historial de revisions, el pod-template-hash que el Deployment afegeix sol, les consultes amb -l que fem servir des de la primera lliçó... Tot això són etiquetes i anotacions, i fins ara les hem anat fent servir sense sistematitzar. A Etiquetes, Selectors i Anotacions, la lliçó que tanca el mòdul, hi posarem ordre: sintaxi i restriccions, etiquetes recomanades per Kubernetes, l'esquema d'etiquetatge definitiu dels sis components de Rutas Norte als seus tres entorns, selectors d'igualtat i de conjunt, i les consultes del dia a dia que converteixen un clúster gran en una cosa navegable.
Curs de Kubernetes
Mòdul 1: Introducció a Kubernetes
- Què és Kubernetes?
- Arquitectura de Kubernetes
- Conceptes i Terminologia Clau
- Configuració d'un Clúster de Kubernetes
- La CLI de Kubernetes: kubectl
- Objectes, Manifests YAML i el Model Declaratiu
- El Projecte del Curs: la Plataforma Rutas Norte
Mòdul 2: Components Principals de Kubernetes
- Pods
- ReplicaSets
- Deployments
- Actualitzacions, Rollbacks i Estratègies de Desplegament
- Serveis
- Namespaces
- Etiquetes, Selectors i Anotacions
Mòdul 3: Gestió de Configuració i Secrets
- ConfigMaps
- Secrets
- Variables d'Entorn
- Quotes i Límits de Recursos
- LimitRanges i Classes de Qualitat de Servei (QoS)
- ServiceAccounts i Accés a l'API des dels Pods
Mòdul 4: Xarxes a Kubernetes
- Xarxes de Clúster
- Tipus de Serveis
- DNS Intern i Descobriment de Serveis
- Controladors d'Ingress
- TLS i Gestió de Certificats amb cert-manager
- Polítiques de Xarxa
Mòdul 5: Emmagatzematge a Kubernetes
- Volums
- Volums Persistents
- Reclamacions de Volums Persistents
- Classes d'Emmagatzematge
- Aprovisionament Dinàmic, Expansió i Snapshots
- Còpies de Seguretat i Restauració de Dades
Mòdul 6: Conceptes Avançats de Kubernetes
- StatefulSets
- DaemonSets
- Treballs i CronJobs
- Init Containers, Sidecars i Patrons Multicontenidor
- Planificació: Afinitat, Taints i Toleracions
- Definicions de Recursos Personalitzats (CRDs)
- Operadors i el Patró Controlador
Mòdul 7: Monitoratge i Registre
- Verificacions de Salut i Sondes
- Servidor de Mètriques i kubectl top
- Monitoratge amb Prometheus
- Visualització i Alertes amb Grafana i Alertmanager
- Registre Centralitzat amb Elasticsearch, Fluentd i Kibana (EFK)
- Depuració d'Aplicacions i Esdeveniments del Clúster
Mòdul 8: Seguretat a Kubernetes
- Control d'Accés Basat en Rols (RBAC)
- Contextos de Seguretat i Enduriment del Contenidor
- Polítiques de Seguretat de Pods i Pod Security Standards
- Seguretat de Xarxa
- Seguretat d'Imatges
- Auditoria, Escaneig i Gestió de Vulnerabilitats
Mòdul 9: Escalat i Rendiment
- Autoescalat Horitzontal de Pods
- Autoescalat Vertical de Pods
- Autoescalat de Clúster
- Escalat per Esdeveniments i Mètriques Personalitzades amb KEDA
- Alta Disponibilitat: PodDisruptionBudgets i Topologia
- Ajust de Rendiment
Mòdul 10: Ecosistema i Eines de Kubernetes
- Minikube i Entorns Locals amb kind
- Kubeadm
- Helm
- Kustomize
- GitOps amb Argo CD i Flux
- Kubernetes Gestionat: EKS, AKS i GKE
Mòdul 11: Estudis de Cas i Aplicacions del Món Real
- Desplegament d'una Aplicació Web
- Execució d'Aplicacions amb Estat
- CI/CD amb Kubernetes
- Estratègies de Desplegament: Blue-Green i Canary
- Gestió Multi-Clúster
- Operació en Producció: Incidències, Runbooks i Costos
