Kubernetes · Cheatsheet 04

Red, configuración y datos

Cómo llega el tráfico a tus Pods, cómo se encuentran entre sí, cómo reciben configuración y dónde guardan datos.

1

Tipos de Service y sus puertos

Cada tipo agrega una capa sobre el anterior.

LoadBalancer IP externa (cloud · localhost en Docker Desktop) NodePort puerto 30000–32767 en cada nodo ClusterIP solo dentro del cluster (default) Cliente navegador Balanceador IP-externa:80 Nodo nodePort 30080 Service port 80 Pods targetPort 3000 Tu PC port-forward 3000:80 otro Pod http://chanchito

¿Cuál uso?

TipoAccesible desdeUso típico
ClusterIPSolo dentro del clusterBases de datos, APIs internas (monguito)
NodePortIP del nodo : 30000–32767Pruebas locales sin Ingress
LoadBalancerIP externaProducción en cloud (AKS, EKS, GKE)
Ingress / GatewayDominio HTTP(S)Varias apps web detrás de una sola entrada
Headless (clusterIP: None)DNS directo a cada PodStatefulSets (réplicas de DB)

Los 4 puertos

CampoDóndeEjemplo
containerPortDeployment: donde escucha la app3000
targetPortService: a qué puerto del Pod manda3000
portService: el puerto “público” del Service80
nodePortService NodePort: puerto en el nodo30080
!

El error más común: targetPort distinto del puerto real de la app. El Service existe pero responde connection refused.

2

DNS interno

Cada Service tiene un nombre resoluble desde cualquier Pod. Igual que el nombre de servicio en compose.

Formas del nombre

NombreFunciona desde
monguitoPods del mismo namespace
monguito.datosCualquier namespace (<service>.<namespace>)
monguito.datos.svc.cluster.localNombre completo (FQDN)
mongodb://mati:<password>@monguito:27017/miapp?authSource=admin
✓

Si el Service de Mongo se llama monguito, tu app.js no cambia al pasar de compose a Kubernetes.

Probar la resolución

kubectl run tmp --rm -it --image=busybox -- nslookup monguito
¿El nombre resuelve a la IP del Service?
kubectl run tmp --rm -it --image=busybox -- wget -qO- http://chanchito
¿El Service responde desde adentro del cluster?
kubectl get endpoints chanchito
IPs de los Pods detrás del Service. Vacío = selector mal o Pods no Ready.
3

Ingress: una entrada, varios destinos

Rutea por host y path. El YAML está en Manifiestos.

Navegador :80 / :443 Ingress controller Traefik (u otro) lee las reglas Ingress y rutea svc/frontend app.localhost / svc/chanchito app.localhost /api svc/grafana grafana.localhost Pods Pods Pods
i

El objeto Ingress son solo reglas; sin un controller instalado no hace nada. El proyecto Kubernetes retiró ingress-nginx en 2026: para algo nuevo usá Traefik u otro controller, o directamente Gateway API.

4

ConfigMap y Secret: tres formas de usarlos

Como variables sueltas, como todas las variables juntas, o como archivos.

ConfigMap MONGO_HOST=monguito LOG_LEVEL=info Secret MONGO_USER=mati MONGO_PASSWORD=*** env: valueFrom una clave → una variable envFrom todas las claves → variables volumes + volumeMounts cada clave → un archivo Contenedor process.env.MONGO_HOST process.env.MONGO_USER /etc/config/LOG_LEVEL /etc/secret/MONGO_PASSWORD

env (una variable)

env:
  - name: MONGO_PASSWORD
    valueFrom:
      secretKeyRef:
        name: mongo-secret
        key: MONGO_PASSWORD
  - name: MONGO_HOST
    valueFrom:
      configMapKeyRef:
        name: chanchito-config
        key: MONGO_HOST

envFrom (todas)

envFrom:
  - configMapRef:
      name: chanchito-config
  - secretRef:
      name: mongo-secret
i

Armar la URL con variables: value: mongodb://$(MONGO_USER):$(MONGO_PASSWORD)@monguito:27017/miapp?authSource=admin (declarando antes las variables).

Como archivos

containers:
  - name: chanchito
    volumeMounts:
      - name: config
        mountPath: /etc/config
        readOnly: true
volumes:
  - name: config
    configMap:
      name: chanchito-config
!

Si cambiás un ConfigMap/Secret, las variables de entorno no se actualizan solas: hacé kubectl rollout restart deploy/chanchito. Los archivos montados sí se actualizan (con algo de demora).

5

Almacenamiento: PVC → PV → disco

El Pod pide, el cluster provee. Vos normalmente solo escribís el PVC.

Pod monguito /data/db PVC mongo-data “quiero 1Gi RWO” lo escribís vos PV pvc-3f2a… 1Gi · Bound lo crea el cluster Disco real carpeta local / EBS monta bind StorageClass aprovisiona automáticamente

accessModes

ModoSignificado
ReadWriteOnce (RWO)Lectura/escritura desde un nodo. Lo normal para DBs
ReadOnlyMany (ROX)Solo lectura desde varios nodos
ReadWriteMany (RWX)Escritura desde varios nodos (requiere NFS o similar)
ReadWriteOncePodUn único Pod

Comandos y cuidados

kubectl get pvc
kubectl get pv
kubectl get storageclass
PVC debe quedar Bound. Si queda Pending: no hay StorageClass default o no hay espacio.
!

Con reclaimPolicy: Delete (el default en la mayoría), borrar el PVC borra los datos. kubectl delete -f k8s/ incluye el PVC si está en esa carpeta.

i

emptyDir: volumen temporal que vive lo que vive el Pod (caché, archivos compartidos entre contenedores del mismo Pod).

6

Deployment vs StatefulSet

Para una base de datos con réplicas, StatefulSet.

Diferencias

DeploymentStatefulSet
Nombres de PodsAleatorios (-x2k4)Fijos y ordenados (-0, -1)
DiscoUn PVC compartidoUn PVC por réplica (volumeClaimTemplates)
Orden de arranqueTodos a la vezDe a uno, en orden
DNS por PodNoSí, con Service headless
Ideal paraAPIs, frontends, workersMongo/Postgres con réplicas, Kafka
✓

Para aprender y en local, Mongo con Deployment + PVC + 1 réplica alcanza. En producción, mejor una base gestionada o un operator.

StatefulSet mínimo

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: monguito
spec:
  serviceName: monguito          # Service headless
  replicas: 1
  selector:
    matchLabels: { app: monguito }
  template:
    metadata:
      labels: { app: monguito }
    spec:
      containers:
        - name: mongo
          image: mongo:7
          ports: [{ containerPort: 27017 }]
          volumeMounts:
            - { name: datos, mountPath: /data/db }
  volumeClaimTemplates:          # un PVC por Pod
    - metadata: { name: datos }
      spec:
        accessModes: [ReadWriteOnce]
        resources: { requests: { storage: 1Gi } }