Kubernetes
Kubernetes è sembrato più facile dopo aver capito queste basi
Non ho ancora fatto il deploy di Kubernetes in un progetto vero, come la maggior parte di quello che so sul software design: guardato, capito, non ancora applicato. Le basi hanno smesso di sembrare un muro di YAML non appena ho avuto un modello mentale per loro.
Non ho ancora fatto il deploy di Kubernetes in nessun progetto vero, come la maggior parte di quello che so sul software design in .NET: guardato, capito, non ancora applicato. Ma le basi hanno smesso di sembrare un muro di YAML non appena ho avuto un modello mentale per cosa faceva davvero ogni pezzo.
Pod, Deployment, Service, file YAML, ConfigMap, Secret, probe, cluster, e decine di comandi. Da sviluppatore .NET junior, continuavo a pensare: perché mi servirebbe tutto questo solo per far girare un'API ASP.NET Core?
È diventato più facile non appena ho capito alcune idee di base.
Kubernetes fa girare container
Kubernetes non builda la mia applicazione C#. Prima deve essere pubblicata e impacchettata dentro un'immagine Docker:
ASP.NET Core API
→ Docker image
→ Kubernetes
Se l'applicazione non funziona dentro Docker, Kubernetes non la sistemerà.
I Pod fanno girare l'applicazione
Un Pod è dove gira un container. Un Pod può contenere un'istanza di un'API ASP.NET Core.
I Pod sono temporanei. Possono essere cancellati, riavviati, o sostituiti, quindi niente di importante dovrebbe vivere dentro uno di essi. Il database, le session, e i file importanti stanno fuori dal Pod.
I Deployment gestiscono i Pod
Un Deployment descrive quante istanze di un'applicazione dovrebbero essere in esecuzione:
spec:
replicas: 2
Se un Pod va in crash, Kubernetes ne crea un altro per sostituirlo. Questa è l'idea centrale: descrivi lo stato desiderato, e Kubernetes cerca di mantenerlo.
I Service espongono l'applicazione
I Pod possono cambiare indirizzo IP quando vengono ricreati. Un Service dà all'applicazione un indirizzo stabile e instrada i request verso qualunque Pod sia disponibile:
Client
→ Service
→ Pod
→ ASP.NET Core API
Senza un Service, i client dovrebbero conoscere l'indirizzo di ogni singolo Pod.
La configurazione dovrebbe essere esterna
Le connection string e le impostazioni d'ambiente non dovrebbero essere hardcoded nell'immagine. ConfigMap e Secret gestiscono questo, e ASP.NET Core li legge come environment variable:
var connectionString =
builder.Configuration.GetConnectionString("DefaultConnection");
È questo che permette alla stessa immagine container di girare in development, testing, e produzione con impostazioni diverse.
Gli health check contano
Kubernetes può controllare se un'API è sana. Una readiness probe chiede se l'applicazione può ricevere traffico. Una liveness probe chiede se sta ancora girando correttamente. ASP.NET Core espone questo tramite un health endpoint:
builder.Services.AddHealthChecks();
app.MapHealthChecks("/health");
Kubernetes usa questo per decidere se un Pod dovrebbe ricevere traffico o essere riavviato.
I comandi che contano di più
La manciata di comandi kubectl che ricorrono costantemente in ogni walkthrough:
kubectl get pods
kubectl get services
kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl apply -f deployment.yaml
Il flusso di debugging è quasi sempre lo stesso: get pods, poi describe pod, poi controllare i log.
A che punto sono davvero con questo
Capisco il modello mentale: Docker impacchetta l'applicazione, i Pod la fanno girare, i Deployment gestiscono i Pod, i Service li espongono, ConfigMap e Secret gestiscono la configurazione, le probe controllano la salute. Quello che non ho ancora è un progetto vero che gira davvero su Kubernetes. È lo stesso divario che ho con molti concetti di software design: capito abbastanza da spiegarlo, non ancora qualcosa che ho dovuto far funzionare in condizioni reali. Quello è il prossimo passo.