Saltar al contenido
NyverraNyverra
⌘K
InicioArtículosSitio institucional
🇪🇸
Nyverra

Canal editorial

Artículos sobre tecnología, operaciones y partners — infraestructura, monitorización y entornos críticos.

Redes sociales

Explorar

  • Inicio
  • Artículos
  • Categorías
  • Etiquetas
  • Autores
  • Sobre
  • Contacto
  • RSS
  • Sitio institucional

Nyverra

  • Nuestros servicios
  • Casos de éxito
  • Socios

Contacto

Correo[email protected]WhatsApp(62) 99309-1592Portal del clienteITSM · tickets y SLA

Rua RB 18, S/N — Casa 01, Sala 01 · Residencial Buriti · Senador Canedo – GO, Brasil · CEP 75260-459

Horario: lun–vie, 08–18 h

© 2026 Nyverra. Todos los derechos reservados.

CNPJ: 61.571.209/0001-08 · Registro estatal: 20.291.265-5 · D-U-N-S®: 57-323-5796

blog.nyverra.com.br

Términos de usoPrivacidadCookies
Volver arriba

En el capítulo anterior el clúster quedó Ready. Ahora vamos a poner algo dentro de él.

La tentación es crear un pod directamente. Resístete. El pod es efímero: si muere, nadie lo recrea. El nivel correcto para una aplicación es el Deployment, que crea un ReplicaSet, que crea los pods.

Deployment -> ReplicaSet -> Pod(s)

El camino del kubectl apply

Cuando ejecutas:

kubectl apply -f app.yaml

Sucede esto:

  1. kubectl lee el YAML y lo envía al API server.
  2. El API server lo valida y lo guarda en etcd.
  3. El controller manager ve el Deployment y crea un ReplicaSet.
  4. El ReplicaSet ve que faltan pods y crea los objetos Pod.
  5. El scheduler elige un nodo para cada pod.
  6. El kubelet del nodo descarga la imagen e inicia el contenedor.
  7. El CNI asigna IP al pod.
  8. El kube-proxy actualiza las reglas del Service.

Si algo falla en cualquier etapa, el estado aparece en kubectl get y kubectl describe. Aprender a leer estos dos comandos vale más que memorizar YAML.

Un Deployment completo

Crea app.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:1.27
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              cpu: 200m
              memory: 128Mi
          readinessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 2
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 10
            periodSeconds: 10

Aplica:

kubectl apply -f app.yaml
kubectl get deploy,rs,pods -o wide

Deberías ver 3 pods Running y Ready.

¿Por qué labels y selector?

El Deployment no busca pods por nombre. Selecciona por label. El selector.matchLabels debe coincidir con template.metadata.labels. Si no coincide, el Deployment no encuentra los pods y el clúster se queja. Es uno de los errores más comunes en YAML.

El Service

Los pods nacen y mueren con IPs diferentes. El Service proporciona un nombre y una IP estable:

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80
  type: ClusterIP
kubectl apply -f service.yaml
kubectl get svc web

Prueba desde dentro del clúster:

kubectl run curl --image=curlimages/curl:8.10.1 --rm -it --restart=Never -- \
  curl -s http://web

ClusterIP solo es accesible dentro del clúster. Para acceso externo, usamos NodePort, LoadBalancer o Ingress — el capítulo 09 lo cubre.

Para probar localmente sin exponer nada:

kubectl port-forward svc/web 8080:80
# em outro terminal
curl -I http://localhost:8080

Rollout y rollback

Actualiza la imagen:

kubectl set image deployment/web web=nginx:1.28
kubectl rollout status deployment/web
kubectl rollout history deployment/web

Si la nueva versión falla:

kubectl rollout undo deployment/web
kubectl rollout status deployment/web

Kubernetes mantiene ReplicaSets antiguos para el rollback. Eso es el revisionHistoryLimit.

Escalado

kubectl scale deployment/web --replicas=5
kubectl get pods -l app=web

En producción, quien escala solo es el HPA (Horizontal Pod Autoscaler), que veremos en la temporada 3. El escalado manual es excelente para entender; el HPA es para operar.

Probes: lo que separa “corriendo” de “listo”

  • readinessProbe: ¿el pod puede recibir tráfego?
  • livenessProbe: ¿el contenedor está vivo? Si falla, el kubelet lo reinicia.
  • startupProbe: para aplicaciones lentas; retiene el liveness hasta que la app inicie.

Una aplicación Java con Spring Boot puede tardar entre 90 y 120 segundos en arrancar. Si el liveness tiene initialDelaySeconds: 10, el kubelet mata el contenedor antes de que termine, y entras en CrashLoopBackOff sin ningún error de aplicación. Ya he visto esto suceder en un deploy real; el log mostraba la app iniciando normalmente y siendo asesinada.

Regla práctica:

  • readiness: generosa al principio, corta después.
  • liveness: solo después de que la app comprobadamente inicia.
  • startup: ideal para apps lentas.

Diagnóstico: los tres estados que vas a ver

Pending

El pod fue creado, pero no fue programado.

kubectl describe pod <pod> | tail -30

Causas: recursos insuficientes, nodeSelector/affinity imposible, taint sin toleration, PVC no vinculado.

ImagePullBackOff / ErrImagePull

El nodo no pudo descargar la imagen.

kubectl describe pod <pod> | grep -A5 Events

Causas: imagen/tag inexistente, registro privado sin imagePullSecret, límite de velocidad del Docker Hub, o imagen eliminada del registro.

Caso real: una imagen que solo existía en caché en dos nodos falló cuando el pod fue reprogramado a un tercero. El clúster estuvo “funcionando” hasta el día en que cambió el nodo. La imagen debe estar disponible en el registro (o en todos los nodos), no solo en caché.

CrashLoopBackOff

El contenedor inicia y muere repetidamente.

kubectl logs <pod>
kubectl logs <pod> --previous
kubectl describe pod <pod> | tail -20

Causas: configuración ausente, variable de entorno incorrecta, dependencia no disponible, permisos, OOMKilled (mira Last State: OOMKilled).

Limpieza

kubectl delete -f service.yaml
kubectl delete -f app.yaml

Lista de verificación

  • [ ] Entendí Deployment → ReplicaSet → Pod.
  • [ ] Sé que selector y labels deben coincidir.
  • [ ] Creé un Deployment con 3 réplicas y un Service.
  • [ ] Probé con port-forward y/o curl interno.
  • [ ] Hice rollout y rollback.
  • [ ] Configuré readiness y liveness con tiempos realistas.
  • [ ] Sé diagnosticar Pending, ImagePullBackOff y CrashLoopBackOff.

Glosario

  • ReplicaSet: garantiza N pods de una versión.
  • Service: nombre/IP estable para un conjunto de pods.
  • ClusterIP: IP interno del Service.
  • NodePort: puerto expuesto en cada nodo.
  • readinessProbe: define si el pod entra en el balanceo.
  • livenessProbe: define si el contenedor debe reiniciarse.
  • OOMKilled: contenedor asesinado por exceso de memoria.

Siguiente

Ahora que sabes crear y diagnosticar un deploy, vamos a usar kubeadm para montar el clúster de verdad, con control plane y workers separados.

Siguiente: Curso Kubernetes 04 — kubeadm por dentro: certificados, static pods y el join

Compartir

Seguir leyendo

Lea también

  • Manual LSI / Broadcom MegaRAID — MegaCli y StorCLI
    Tutoriais

    Manual LSI / Broadcom MegaRAID — MegaCli y StorCLI

    Con esta guía, su equipo gana autonomía para diagnosticar rebuilds, resolver foreign configurations, gestionar BBU y CacheCade — con escenarios reales de producción documentados.

    31 de outubro de 202620 min de leitura
  • Nginx Cheatsheet

    Nginx Cheatsheet

    Guía de bolsillo con ejemplos listos para configurar Nginx en producción: desde instalación y virtual hosts hasta ajuste de rendimiento y resolución de problemas.

    31 de outubro de 202612 min de leitura
  • Curso Kubernetes 27 — SLO/SLI, on-call y postmortem sin culpa
    Kubernetes

    Curso Kubernetes 27 — SLO/SLI, on-call y postmortem sin culpa

    Qué prometer, cómo medir y qué hacer cuando el error se dispara: SLI, SLO, presupuesto de error, alertas que despiertan a alguien y postmortem sin caza de brujas.

    31 de outubro de 20265 min de leitura

Comentarios

Aún sin comentarios

Sea el primero en compartir su opinión sobre este artículo.

Deje un comentario

Newsletter

Reciba nuevos artículos

Suscríbase para recibir publicaciones del blog Nyverra en su correo. Enviaremos un enlace de confirmación.

​
  1. Inicio
  2. Kubernetes
  3. Curso Kubernetes 03 — El primer pod y el primer deploy: YAML, kubectl y lo que realmente sucede
Kubernetes
#Probes#Kubectl#Deployment#K8S#Kubernetes#Curso Kubernetes

Curso Kubernetes 03 — El primer pod y el primer deploy: YAML, kubectl y lo que realmente sucede

Wedson LopesWedson Lopes
31 de outubro de 20265 min de leitura