Colloquio Kubernetes: Pod, Service e Deployment Spiegati nel Dettaglio

I tre pilastri di Kubernetes — Pod, Service e Deployment — con manifest YAML di produzione, networking interno e domande frequenti nei colloqui tecnici.

Architettura Kubernetes con pod, service e deployment

Le domande nei colloqui tecnici su Kubernetes si concentrano costantemente su tre oggetti fondamentali: Pod, Service e Deployment. Comprendere come interagiscono tra loro — dalla pianificazione dei container al routing di rete fino agli aggiornamenti graduali — distingue i candidati che memorizzano definizioni da quelli capaci di progettare sistemi di produzione.

Questa guida analizza ogni primitiva con YAML di livello production, spiega gli aspetti interni che interessano agli intervistatori e affronta le domande esatte che emergono nei colloqui DevOps e platform engineering.

Riferimento Rapido

Un Pod esegue uno o più container su un singolo nodo. Un Deployment gestisce le repliche dei Pod e i rollout. Un Service fornisce un endpoint di rete stabile per raggiungere quei Pod. Questi tre oggetti gestiscono l'80% del workload management in qualsiasi cluster Kubernetes dalla versione v1.35 in poi.

Comprendere i Pod Kubernetes: L'Unità Minima di Deploy

Il Pod rappresenta l'unità atomica di scheduling in Kubernetes. Incapsula uno o più container che condividono lo stesso namespace di rete, namespace IPC e volumi di storage. Ogni container all'interno di un Pod riceve lo stesso indirizzo IP e può comunicare con i container adiacenti tramite localhost.

Il Pod a singolo container costituisce il pattern più comune. I Pod multi-container esistono per scenari sidecar — raccoglitori di log, service mesh o init container che preparano il filesystem prima dell'avvio del processo principale.

yaml
# api-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: api-server
  labels:
    app: api
    version: v2
spec:
  containers:
    - name: api
      image: registry.example.com/api:3.1.0
      ports:
        - containerPort: 8080
      resources:
        requests:
          cpu: "250m"        # 0.25 CPU core reserved
          memory: "256Mi"    # 256 MB reserved
        limits:
          cpu: "500m"        # hard cap at 0.5 core
          memory: "512Mi"    # OOMKilled beyond this
      readinessProbe:
        httpGet:
          path: /healthz
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 10
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
        initialDelaySeconds: 15
        periodSeconds: 20

Il blocco resources risulta cruciale durante i colloqui. I requests determinano lo scheduling — lo scheduler posiziona il Pod su un nodo con capacità disponibile sufficiente. I limits impongono limiti massimi a runtime — superare il limite di memoria provoca un OOMKill, mentre superare il limite CPU causa throttling.

Trappola Comune nei Colloqui

Impostare limiti di memoria senza requests causa uno scheduling imprevedibile. Il kubelet potrebbe posizionare il Pod su un nodo che non riesce effettivamente a sostenere il carico di lavoro. Impostare sempre sia requests che limits per i Pod di produzione.

Fasi del Ciclo di Vita del Pod e Restart Policy

Kubernetes traccia ogni Pod attraverso cinque fasi: Pending, Running, Succeeded, Failed e Unknown. Gli intervistatori chiedono spesso cosa provoca ogni transizione.

| Fase | Significato | Causa Comune | |------|-------------|-------------| | Pending | Schedulato ma non in esecuzione | Pull dell'immagine, risorse insufficienti | | Running | Almeno un container attivo | Operazione normale | | Succeeded | Tutti i container terminati con exit 0 | Job batch, init container | | Failed | Almeno un container terminato con exit non-zero | Crash applicazione, OOMKill | | Unknown | Comunicazione con il nodo persa | Partizione di rete, failure del nodo |

Il campo restartPolicy controlla cosa accade dopo che un container termina. Always (il default per i Deployment) riavvia indipendentemente dal codice di uscita. OnFailure riavvia solo su uscite non-zero — utile per i Job. Never lascia il container fermo — utilizzato per Pod di debug one-shot.

yaml
# batch-job-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: data-migration
spec:
  restartPolicy: OnFailure   # restart only on crash
  containers:
    - name: migrate
      image: registry.example.com/migrate:1.0.0
      command: ["python", "migrate.py"]
      env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: connection-string

Il pattern valueFrom.secretKeyRef mantiene i dati sensibili fuori dal manifest. I Secret Kubernetes sono codificati in base64 di default — non cifrati. Per la produzione, abilitare la cifratura at rest tramite l'API EncryptionConfiguration oppure utilizzare un gestore di secret esterno come HashiCorp Vault.

Kubernetes Deployment: Rollout Dichiarativi e Scaling

Un Deployment crea e gestisce ReplicaSet, che a loro volta gestiscono i Pod. Il controller del Deployment osserva lo stato desiderato e lo riconcilia con la realtà — aggiungendo Pod durante lo scale up, sostituendoli durante i rollout e facendo rollback quando i controlli di salute falliscono.

La creazione diretta di Pod non risulta quasi mai appropriata in produzione. I Deployment forniscono gestione delle repliche, aggiornamenti graduali, cronologia dei rollback e capacità di pausa/ripresa.

yaml
# api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
  labels:
    app: api
spec:
  replicas: 3                    # run 3 identical Pods
  revisionHistoryLimit: 5        # keep 5 old ReplicaSets for rollback
  selector:
    matchLabels:
      app: api                   # must match Pod template labels
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1          # at most 1 Pod down during update
      maxSurge: 1                # at most 1 extra Pod during update
  template:
    metadata:
      labels:
        app: api
        version: v2
    spec:
      containers:
        - name: api
          image: registry.example.com/api:3.1.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10

La sezione strategy.rollingUpdate definisce il comportamento di deployment senza downtime. Con maxUnavailable: 1 e maxSurge: 1, Kubernetes crea un nuovo Pod, attende che superi i controlli di readiness, poi termina un vecchio Pod. Questo ciclo si ripete finché tutte le repliche eseguono la nuova versione.

Eseguire il Rollback di un Deployment Kubernetes Fallito

I rollback rappresentano un argomento ad alta frequenza nei colloqui. Il controller del Deployment mantiene i vecchi ReplicaSet (controllati da revisionHistoryLimit) quindi il rollback risulta istantaneo — nessun rebuild dell'immagine necessario.

bash
# Check rollout status
kubectl rollout status deployment/api-server

# View revision history
kubectl rollout history deployment/api-server

# Roll back to previous version
kubectl rollout undo deployment/api-server

# Roll back to specific revision
kubectl rollout undo deployment/api-server --to-revision=3

Il comando undo applica una patch alla spec del Deployment per farla corrispondere al template del Pod della revisione target. La strategia di rolling update si applica poi normalmente, sostituendo gradualmente i Pod correnti con la versione di rollback.

Pronto a superare i tuoi colloqui su DevOps?

Pratica con i nostri simulatori interattivi, flashcards e test tecnici.

Kubernetes Service: Networking Stabile per Pod Dinamici

I Pod sono effimeri. Ricevono nuovi indirizzi IP ogni volta che ripartono. Un Service risolve questo problema fornendo un IP virtuale stabile (ClusterIP) e un nome DNS che instrada il traffico verso Pod sani che corrispondono a un label selector.

Il componente kube-proxy su ogni nodo programma regole iptables o IPVS per distribuire il traffico tra i Pod backend. Quando un Pod fallisce il suo readiness probe, il controller degli Endpoints lo rimuove dal Service — nessun traffico raggiunge istanze non sane.

yaml
# api-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  type: ClusterIP               # internal-only by default
  selector:
    app: api                     # routes to Pods with this label
  ports:
    - name: http
      port: 80                   # Service port (what clients use)
      targetPort: 8080           # Pod port (where container listens)
      protocol: TCP

Una volta creato, qualsiasi Pod nel cluster può raggiungere questo Service all'indirizzo api-service.default.svc.cluster.local (oppure semplicemente api-service all'interno dello stesso namespace). CoreDNS gestisce la risoluzione.

Tipi di Service: ClusterIP, NodePort e LoadBalancer

Gli intervistatori si aspettano che i candidati spieghino i tre principali tipi di Service e quando si applica ciascuno.

| Tipo | Ambito di Accesso | Caso d'Uso | |------|-------------------|------------| | ClusterIP | Solo interno al cluster | API backend, database, cache | | NodePort | Esterno via <NodeIP>:<Port> | Sviluppo, cluster bare-metal | | LoadBalancer | Esterno via LB cloud | Traffico di produzione su AWS/GCP/Azure |

yaml
# api-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
  name: api-public
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"  # AWS NLB
spec:
  type: LoadBalancer
  selector:
    app: api
  ports:
    - name: https
      port: 443
      targetPort: 8080
      protocol: TCP

Il tipo LoadBalancer attiva il controller del load balancer del cloud provider per il provisioning di un endpoint esterno. Su AWS, questo crea un NLB o ALB a seconda delle annotation. Su cluster bare-metal senza integrazione cloud, MetalLB o kube-vip ricoprono questo ruolo.

Gateway API Sostituisce Ingress

A partire da Kubernetes v1.35, l'Ingress NGINX controller risulta ufficialmente deprecato. La Gateway API rappresenta ora l'approccio raccomandato per routing HTTP, terminazione TLS e traffic splitting. I nuovi cluster dovrebbero adottare Gateway API fin dall'inizio.

Collegare Deployment e Service con Label Selector

Il collegamento tra un Deployment e un Service avviene tramite il label selector — nient'altro. Non esiste alcun riferimento esplicito tra i due oggetti. Il Service osserva i Pod le cui label corrispondono al suo spec.selector e mantiene automaticamente una lista di Endpoints.

Questa architettura disaccoppiata significa che un singolo Service può instradare verso Pod di Deployment multipli (utile per canary release), e un Deployment può essere esposto da Service multipli (porte diverse, livelli di accesso diversi).

yaml
# canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api                   # same label as main Deployment
  template:
    metadata:
      labels:
        app: api                 # Service picks this up automatically
        version: v3-canary
    spec:
      containers:
        - name: api
          image: registry.example.com/api:3.2.0-rc1
          ports:
            - containerPort: 8080

Con il Deployment principale che esegue 3 repliche e il canary che ne esegue 1, il Service distribuisce circa il 25% del traffico al canary. Nessuna modifica alla configurazione del Service necessaria — il label matching gestisce tutto.

Horizontal Pod Autoscaling per Deployment Kubernetes

Conteggi di repliche statici sprecano risorse durante il traffico basso e cedono sotto i picchi. L'HorizontalPodAutoscaler (HPA) regola il numero di repliche in base alle metriche osservate.

yaml
# api-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70   # scale up above 70% CPU
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300  # wait 5 min before scaling down

L'HPA interroga il metrics server ogni 15 secondi di default. Kubernetes v1.35 ha introdotto la tolleranza HPA configurabile, sostituendo la soglia hardcoded del 10%. Questo significa che i team che eseguono workload sensibili alla latenza possono ora impostare trigger di scaling più precisi.

Il parametro behavior.scaleDown.stabilizationWindowSeconds previene il flapping — cicli rapidi di scale-up/scale-down causati da pattern di traffico a raffica.

Domande Comuni nei Colloqui Kubernetes con Risposte

Queste domande appaiono ripetutamente nei colloqui DevOps e platform engineering. Ogni risposta mira alla profondità che gli intervistatori si aspettano.

Cosa succede quando un Pod supera il suo limite di memoria? Il kubelet invia un SIGKILL tramite l'OOM killer. Il container termina con codice 137. Il controller del Deployment rileva il Pod fallito e crea un sostituto, soggetto alla restart policy e a eventuali delay di backoff.

Come instrada Kubernetes il traffico verso una specifica versione del Pod durante le canary release? Il selector del Service corrisponde su label condivise (es. app: api). Sia il Deployment stabile che quello canary usano questa label. La distribuzione del traffico risulta proporzionale al numero di endpoint pronti — 3 repliche stabili + 1 replica canary significa circa 25% di traffico canary. Per traffic splitting preciso (es. 5%), utilizzare Gateway API HTTPRoute con backend pesati.

Qual è la differenza tra readinessProbe e livenessProbe? Un readiness probe controlla se il Pod riceve traffico dal Service. Un readiness probe fallito rimuove il Pod dalla lista degli Endpoints ma non lo riavvia. Un liveness probe controlla se il container viene riavviato. Un liveness probe fallito provoca un restart del container. Entrambi possono usare controlli HTTP, TCP o exec.

Come garantiscono gli aggiornamenti graduali zero downtime? Il controller del Deployment crea nuovi Pod prima di terminare quelli vecchi, governato da maxSurge e maxUnavailable. I nuovi Pod devono superare i readiness probe prima che i vecchi Pod vengano drainati. Il terminationGracePeriodSeconds (default: 30s) dà alle richieste in corso tempo di completarsi prima del SIGKILL.

Prepararsi per un colloquio Kubernetes richiede pratica con YAML reali, non solo teoria. Le domande da colloquio DevOps su SharpSkill coprono questi argomenti con esercizi interattivi.

Inizia a praticare!

Metti alla prova le tue conoscenze con i nostri simulatori di colloquio e test tecnici.

Conclusione

  • I Pod rappresentano l'unità di scheduling — impostare sempre resource requests e limits, e configurare sia readiness che liveness probe
  • I Deployment gestiscono il conteggio delle repliche, gli aggiornamenti graduali e la cronologia dei rollback tramite ReplicaSet — mai creare Pod bare in produzione
  • I Service forniscono networking stabile attraverso label selector e IP virtuali — ClusterIP per traffico interno, LoadBalancer per esterno
  • Il collegamento tra Deployment e Service si basa puramente sulle label, abilitando pattern canary senza modifiche alla configurazione
  • L'HPA scala i Deployment basandosi su metriche CPU/memoria — usare stabilizationWindowSeconds per prevenire il flapping
  • Gateway API sostituisce Ingress NGINX a partire da Kubernetes v1.35 — i nuovi progetti dovrebbero adottarla fin dall'inizio
  • Esercitarsi con manifest YAML reali e comandi kubectl piuttosto che memorizzare definizioni

Tag

#kubernetes
#devops
#interview
#containers
#orchestration

Condividi

Articoli correlati