Hai un'applicazione che gira in container su un server. Funziona. Poi arriva il traffico, i container cadono, devi scalare, aggiorni la versione e qualcosa si rompe. Il container è facile. Orchestrarlo in produzione è tutta un'altra storia. Per questo serve Kubernetes.
Noi, di Meteora Web, lavoriamo con Kubernetes dal 2017. Non perché sia di moda, ma perché abbiamo visto decine di progetti soffocare con stack fatti in casa quando il carico cresceva. Kubernetes non è semplice, ma è l'unico modo standard per gestire container in produzione in modo affidabile, scalabile e riproducibile. In questa guida pillar copriamo tutto ciò che serve per passare da zero a un cluster pronto al carico di lavoro reale.
Kubernetes da zero: Architettura, Pod, Deployment, Service, Namespace
Kubernetes è un orchestratore. Prende i tuoi container e decide dove metterli, quando farli ripartire, come esporli. L'unità minima è il Pod: uno o più container che condividono rete e storage. I Pod sono effimeri; non li gestisci direttamente ma tramite un Deployment, che dichiara lo stato desiderato (repliche, immagine, risorse) e Kubernetes mantiene quella realtà. Per connetterti ai Pod serve un Service: stabile indirizzo IP e bilanciamento del carico. I Namespace isolano risorse tra team o ambienti.
Errore comune: usare Pod direttamente
Vediamo spesso chi crea Pod a mano. Non si fa. Un Deployment garantisce rolling update, self-healing, scalabilità. Il Pod è solo l'elemento atomico.
Esempio operativo: il tuo primo Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP
Cosa fare adesso: Crea un namespace di test con kubectl create namespace test e applica il file con kubectl apply -f deploy-service.yaml -n test.
Sponsored Protocol
kubectl: I comandi essenziali per la gestione del cluster
kubectl è il coltellino svizzero di Kubernetes. Ogni giorno lo usiamo per ispezionare, debug, deploy e troubleshooting. Ecco i comandi che contano davvero, oltre a quelli da manuale.
Get, Describe, Logs, Exec
# Elenco risorse
kubectl get pods -n production
kubectl get deploy,svc,ingress -A
# Dettaglio e troubleshooting
kubectl describe pod nginx-deployment-xxxx
kubectl logs -f deployment/nginx --tail=50
# Esecuzione in un container
kubectl exec -it deployment/nginx -- /bin/sh
# Port forwarding per debug locale
kubectl port-forward svc/nginx-service 8080:80
Pro tip: Usa alias kubectl get pods -w per watch continuo. Noi lo abbiamo in un tmux sempre aperto nei deploy critici.
Helm: Il package manager di Kubernetes
Helm è a Kubernetes quello che apt è per Debian o composer per PHP. Impacchetta risorse YAML in Chart con template e valori variabili. Gestisci release, rollback, upgrade. Non scrivere YAML da zero per ogni componente; usa o crea Chart.
Creare una Chart personalizzata
# Chart.yaml
apiVersion: v2
name: mia-app
description: Un deployment con servizio e ingress
version: 0.1.0
# values.yaml
replicaCount: 2
image:
repository: nginx
tag: 1.25
service:
port: 80
ingress:
enabled: true
host: app.miodominio.it
Template in templates/deployment.yaml usano {{ .Values.replicaCount }}. Installi con helm install mia-app ./chart -f values.prod.yaml.
Sponsored Protocol
Errore comune: non versionare i Chart in Git. Fallo. Ogni deploy è tracciabile.
Ingress Controller: Nginx, Traefik e routing HTTP/HTTPS
Il Service di tipo NodePort o LoadBalancer espone porte, ma per routing basato su hostname e path, terminazione TLS, serve un Ingress Controller. Non è incluso di default in Kubernetes; lo installi tu (Nginx, Traefik, HAProxy, Contour).
Configurare Ingress con Nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mia-app-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- app.miodominio.it
secretName: tls-secret
rules:
- host: app.miodominio.it
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
Cosa fare adesso: Installa l'Ingress Controller Nginx con Helm: helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx && helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx. Poi crea l'Ingress sopra.
Persistent Volumes e StatefulSet: Storage per applicazioni con stato
I Pod sono effimeri. I dati no. Per database, code, file storage, Kubernetes offre PersistentVolume (risorsa cluster) e PersistentVolumeClaim (richiesta del Pod). Per applicazioni che hanno bisogno di identità stabile (es. database) usa StatefulSet invece di Deployment.
Esempio: PVC montata su un Deployment
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
spec:
template:
spec:
containers:
- volumeMounts:
- mountPath: /data
name: storage
volumes:
- name: storage
persistentVolumeClaim:
claimName: data-pvc
Attenzione: StatefulSet richiede un servizio headless e gestisce l'ordine di avvio. Non usarlo per app senza stato.
Sponsored Protocol
Horizontal Pod Autoscaler: Scalabilità automatica sotto carico
HPA modifica il numero di repliche in base a CPU, memoria o metriche custom. Senza HPA paghi per capacità inutilizzata o collassi di performance. Impostalo sempre.
Configurazione HPA base
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Operativo: Assicurati che il cluster abbia il metrics-server installato (kubectl top pods). Altrimenti HPA non funziona.
ConfigMap e Secret: Gestione configurazioni e credenziali
Separare configurazione dal codice è una regola d'oro. ConfigMap per dati non sensibili (variabili d'ambiente, file di configurazione). Secret per credenziali, token, chiavi. Entrambi si montano come volumi o env.
Creare e usare un Secret
kubectl create secret generic db-credentials \
--from-literal=username=app_user \
--from-literal=password='S3cur3P@ss'
# Nel deployment
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
Errore comune: versionare Secret in chiaro su Git. Noi usiamo SealedSecrets per cifrare i dati nel repository.
Kubernetes RBAC: Sicurezza degli accessi e Service Account
Il cluster non è di proprietà di un singolo utente. Con RBAC (Role-Based Access Control) definisci chi può fare cosa su quali risorse. Usa ServiceAccount per i Pod (non admin) e Role/ClusterRole per umani o automazioni.
Sponsored Protocol
Esempio: ServiceAccount per un'app che legge i Pod
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-binding
namespace: production
subjects:
- kind: ServiceAccount
name: pod-reader
namespace: production
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Operativo: Controlla i log di audit: kubectl logs -n kube-system kube-apiserver --tail=100 | grep -i forbidden. Scoprirai chi tenta di fare cose non concesse.
Managed Kubernetes: GKE, EKS, AKS a confronto
Gestire il control plane da soli (kubeadm) è possibile, ma per la maggior parte delle aziende conviene un servizio managed: Google Kubernetes Engine (GKE), Amazon EKS, Azure AKS. Noi abbiamo clienti su tutti e tre. Ecco le differenze pratiche:
- GKE: upgrade automatici del control plane, integrazione nativa con Cloud Armor, nodi a costo zero. Ideale per chi usa Google Cloud.
- EKS: ecosistema AWS profondo (IAM roles for service accounts, ALB ingress controller). Più caro in termini di costi fissi (0.10$/ora control plane).
- AKS: buon rapporto qualità-prezzo, nodi gratuiti, integrazione con Azure AD. Ottimo per ambienti ibridi.
Cosa fare adesso: Valuta il provider. Se sei già su una nuvola, scegli il Kubernetes managed corrispondente. Altrimenti, GKE resta il più maturo.
ArgoCD e GitOps: Deployment dichiarativo e sincronizzazione
GitOps inverte il flusso: non lanci kubectl apply. Dichiarai lo stato desiderato in un repository Git, e un operatore (ArgoCD) lo applica e mantiene sincronizzato. Se qualcuno modifica a mano le risorse, ArgoCD le riporta allo stato del Git. Questo è il modo in cui gestiamo tutti i cluster in produzione.
Sponsored Protocol
Installazione rapida di ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Poi configuri una Application ArgoCD che punta al repo Git. Ogni push attiva la sincronizzazione. Per approfondire integrazioni CI/CD, leggi la nostra guida su CI Pipeline Automatica.
Errore comune: non impostare auto-sync. La differenza tra GitOps e deploy manuale è l'automazione. Imposta syncPolicy: con automated: {prune: true, selfHeal: true}.
In sintesi — Cosa fare adesso
Kubernetes non si impara in un giorno. Ma puoi iniziare subito con azioni concrete:
- Installa minikube o Kind sul tuo laptop per sperimentare. Nessun costo, nessun rischio.
- Leggi la documentazione ufficiale: kubernetes.io/docs è la bibbia.
- Riscrivi un deploy Docker Compose in Deployment + Service. Vedrai subito la differenza.
- Installa Helm e cerca chart ufficiali per PostgreSQL, Redis, Nginx. Studia i template.
- Configura RBAC anche se sei l'unico utente. Buona pratica.
- Imposta HPA su una app con carico. Usa
kubectl run load-generatorper testare. - Non aver paura di rompere in un ambiente di test. Rialza con
minikube delete.
Noi, di Meteora Web, accompagniamo team e aziende nel passaggio da stack artigianali a Kubernetes in produzione. Se vuoi un confronto operativo, contattaci. Il container è la materia prima; l'orchestrazione è l'arte.