View a markdown version of this page

Esecuzione di applicazioni ad alta disponibilità - Amazon EKS

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Esecuzione di applicazioni ad alta disponibilità

I tuoi clienti si aspettano che la tua applicazione sia sempre disponibile, anche quando apporti modifiche e soprattutto durante i picchi di traffico. Un'architettura scalabile e resiliente consente alle applicazioni e ai servizi di funzionare senza interruzioni, garantendo la soddisfazione degli utenti. Un'infrastruttura scalabile cresce e si riduce in base alle esigenze aziendali. L'eliminazione dei singoli punti di errore è un passaggio fondamentale per migliorare la disponibilità di un'applicazione e renderla resiliente.

Con Kubernetes, puoi gestire le tue applicazioni ed eseguirle in modo altamente disponibile e resiliente. La sua gestione dichiarativa garantisce che, una volta configurata l'applicazione, Kubernetes cercherà continuamente di far corrispondere lo stato corrente con lo stato desiderato. https://kubernetes.io/docs/concepts/architecture/controller/#desired-vs-current

Raccomandazioni

Configura i budget per le interruzioni dei pod

I Pod Disruption Budget vengono utilizzati per limitare la quantità di interruzioni simultanee che un'applicazione subirà. Dovrebbero essere configurati per i carichi di lavoro se è importante avere sempre una parte di quel carico di lavoro disponibile. EKS Auto Mode, Karpenter e Cluster Autoscaler sono consapevoli e rispettano i Pod Disruption Budget configurati in fase di ridimensionamento. Anche EKS Auto Mode, Karpenter e Managed Node Groups aderiscono ai Pod Disruption Budgets durante l'aggiornamento dei nodi

Evita di utilizzare pod singleton

Se l'intera applicazione viene eseguita in un singolo Pod, l'applicazione non sarà disponibile se quel Pod viene chiuso. Invece di distribuire le applicazioni utilizzando singoli pod, crea Deployments. https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ Se un pod creato da un Deployment fallisce o viene terminato, il controller di distribuzione avvierà un nuovo pod per garantire che il numero specificato di pod di replica sia sempre in esecuzione.

Esegui più repliche

L'esecuzione di più pod di repliche di un'app tramite Deployment ne consente l'esecuzione in modo altamente disponibile. Se una replica fallisce, le repliche rimanenti continueranno a funzionare, anche se a capacità ridotta fino a quando Kubernetes non creerà un altro Pod per compensare la perdita. Inoltre, puoi utilizzare Horizontal Pod Autoscaler per scalare automaticamente le repliche in base alla richiesta del carico di lavoro.

Pianifica le repliche tra i nodi

L'esecuzione di più repliche non sarà molto utile se tutte le repliche sono in esecuzione sullo stesso nodo e il nodo diventa non disponibile. Prendi in considerazione l'utilizzo dei vincoli di diffusione dell'anti-affinità o della topologia pod per diffondere le repliche di una distribuzione su più nodi di lavoro.

Puoi migliorare ulteriormente l'affidabilità di un'applicazione tipica eseguendola su più AZ.

Utilizzo delle regole antiaffinità di Pod

Il seguente manifesto indica a Kubernetes Scheduler di preferire il posizionamento dei pod su nodi e AZ separati. Non richiede nodi distinti o AZ perché se lo facesse, Kubernetes non sarà in grado di pianificare alcun pod una volta che c'è un pod in esecuzione in ogni AZ. Se la tua applicazione richiede solo tre repliche, puoi utilizzare requiredDuringSchedulingIgnoredDuringExecution for topologyKey: topology.kubernetes.io/zone e Kubernetes Scheduler non pianificherà due pod nello stesso AZ.

apiVersion: apps/v1 kind: Deployment metadata: name: spread-host-az labels: app: web-server spec: replicas: 4 selector: matchLabels: app: web-server template: metadata: labels: app: web-server spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - web-server topologyKey: topology.kubernetes.io/zone weight: 100 - podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - web-server topologyKey: kubernetes.io/hostname weight: 99 containers: - name: web-app image: nginx:1.16-alpine

Utilizzo dei vincoli di diffusione della topologia Pod

Analogamente alle regole antiaffinità dei pod, i vincoli di diffusione della topologia dei pod consentono di rendere disponibile l'applicazione su diversi domini di errore (o topologia) come host o AZ. Questo approccio funziona molto bene quando si cerca di garantire la tolleranza ai guasti e la disponibilità disponendo di più repliche in ciascuno dei diversi domini di topologia. Le regole di antiaffinità dei pod, d'altra parte, possono facilmente produrre un risultato in cui si ha una singola replica in un dominio topologico perché i pod con un'antiaffinità reciproca hanno un effetto repellente. In questi casi, una singola replica su un nodo dedicato non è ideale per la tolleranza ai guasti né è un buon uso delle risorse. Con i vincoli di diffusione della topologia, hai un maggiore controllo sulla diffusione o sulla distribuzione che lo scheduler dovrebbe cercare di applicare nei domini della topologia. Ecco alcune proprietà importanti da utilizzare in questo approccio:

  1. maxSkewViene utilizzato per controllare o determinare il punto massimo in cui le cose possono essere irregolari nei domini della topologia. Ad esempio, se un'applicazione ha 10 repliche ed è distribuita su 3 AZ, non è possibile ottenere uno spread uniforme, ma è possibile influire sull'irregolarità della distribuzione. In questo caso, maxSkew può essere compreso tra 1 e 10. Un valore pari a 1 significa che si può potenzialmente ottenere uno spread simile 4,3,3 3,4,3 o 3,3,4 tra i 3 AZ. Al contrario, un valore pari a 10 significa che è possibile ottenere uno spread pari 10,0,0 0,10,0 o superiore a 3 0,0,10 AZ.

  2. topologyKeyÈ una chiave per una delle etichette dei nodi e definisce il tipo di dominio topologico da utilizzare per la distribuzione dei pod. Ad esempio, uno spread zonale avrebbe la seguente coppia chiave-valore:

    topologyKey: "topology.kubernetes.io/zone"
  3. La whenUnsatisfiable proprietà viene utilizzata per determinare come si desidera che lo scheduler risponda se i vincoli desiderati non possono essere soddisfatti.

  4. labelSelectorViene utilizzato per trovare i pod corrispondenti in modo che lo scheduler possa conoscerli quando decide dove posizionare i pod in base ai vincoli specificati.

Oltre a quelli sopra riportati, ci sono altri campi che puoi leggere ulteriormente nella documentazione di Kubernetes. https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/

La topologia dei pod diffonde i vincoli su 3 AZ

Pod topology spread constraints across 3 AZs

apiVersion: apps/v1 kind: Deployment metadata: name: spread-host-az labels: app: web-server spec: replicas: 10 selector: matchLabels: app: web-server template: metadata: labels: app: web-server spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: app: express-test containers: - name: web-app image: nginx:1.16-alpine

Esegui Kubernetes Metrics Server

Installa il server di metriche Kubernetes per scalare le tue applicazioni. I componenti aggiuntivi di Kubernetes autoscaler come HPA e VPA devono tenere traccia delle metriche delle applicazioni per scalarle. https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler Il metrics-server raccoglie le metriche delle risorse che possono essere utilizzate per prendere decisioni di scalabilità. Le metriche vengono raccolte da kubelets e fornite nel formato Metrics API. https://github.com/kubernetes/metrics

Il server delle metriche non conserva alcun dato e non è una soluzione di monitoraggio. Il suo scopo è esporre le metriche di utilizzo della CPU e della memoria ad altri sistemi. Se desideri monitorare lo stato della tua applicazione nel tempo, hai bisogno di uno strumento di monitoraggio come Prometheus o Amazon. CloudWatch

Segui la documentazione EKS per installare metrics-server nel tuo cluster EKS.

Horizontal Pod Autoscaler (HPA)

HPA è in grado di scalare automaticamente l'applicazione in base alla domanda e aiutarvi a evitare di avere un impatto sui clienti durante i picchi di traffico. È implementato come un ciclo di controllo in Kubernetes che interroga periodicamente le metriche delle API che forniscono metriche sulle risorse.

HPA è in grado di recuperare le metriche dalle seguenti API: 1. metrics.k8s.ionota anche come Resource Metrics API: fornisce l'utilizzo della CPU e della memoria per i pod 2. custom.metrics.k8s.io — Fornisce metriche provenienti da altri raccoglitori di metriche come Prometheus; queste metriche sono interne al tuo cluster Kubernetes. 3. external.metrics.k8s.io — Fornisce metriche esterne al cluster Kubernetes (E.g., SQS Queue Depth, latenza ELB).

È necessario utilizzare una di queste tre API per fornire la metrica necessaria per scalare l'applicazione.

Ridimensionamento delle applicazioni in base a metriche personalizzate o esterne

È possibile utilizzare metriche personalizzate o esterne per scalare l'applicazione in base a metriche diverse dall'utilizzo della CPU o della memoria. I server API Custom Metrics forniscono l'custom-metrics.k8s.ioAPI che HPA può utilizzare per scalare automaticamente le applicazioni.

Puoi utilizzare il Prometheus Adapter for Kubernetes Metrics API per raccogliere metriche da Prometheus e utilizzarle con l'HPA. In questo caso, l'adattatore Prometheus esporrà le metriche di Prometheus nel formato Metrics API. https://github.com/kubernetes/metrics/blob/master/pkg/apis/metrics/types.go

Una volta distribuito l'adattatore Prometheus, puoi interrogare le metriche personalizzate utilizzando kubectl. kubectl get —raw /apis/custom.metrics.k8s.io/v1beta1/

Le metriche esterne, come suggerisce il nome, forniscono a Horizontal Pod Autoscaler la capacità di scalare le implementazioni utilizzando metriche esterne al cluster Kubernetes. Ad esempio, nei carichi di lavoro di elaborazione in batch, è comune scalare il numero di repliche in base al numero di lavori in corso in una coda SQS.

Per scalare automaticamente i carichi di lavoro Kubernetes puoi utilizzare KEDA (Kubernetes Event-driven Autoscaling), un progetto open source in grado di favorire la scalabilità dei container in base a una serie di eventi personalizzati. Questo blog di AWS illustra come utilizzare Amazon Managed Service for Prometheus for Kubernetes per il ridimensionamento automatico dei carichi di lavoro.

Vertical Pod Autoscaler (VPA)

Il VPA regola automaticamente la riserva di CPU e memoria per i tuoi Pod per aiutarti a «dimensionare correttamente» le tue applicazioni. Per le applicazioni che devono essere scalate verticalmente, aumentando l'allocazione delle risorse, puoi utilizzare VPA per scalare automaticamente le repliche dei Pod o fornire consigli sulla scalabilità.

L'applicazione potrebbe diventare temporaneamente non disponibile se VPA deve scalarla perché l'attuale implementazione di VPA non esegue modifiche sul posto ai Pod; invece, ricreerà il Pod che deve essere ridimensionato.

La documentazione EKS include una procedura dettagliata per la configurazione del VPA.

https://github.com/FairwindsOps/goldilocks/Il progetto Fairwinds Goldilocks fornisce una dashboard per visualizzare i consigli VPA per le richieste e i limiti di CPU e memoria. La modalità di aggiornamento VPA consente di scalare automaticamente i pod in base ai consigli VPA.

Aggiornamento delle applicazioni

Le applicazioni moderne richiedono una rapida innovazione con un elevato grado di stabilità e disponibilità. Kubernetes ti offre gli strumenti per aggiornare continuamente le tue applicazioni senza interrompere le attività dei tuoi clienti.

Diamo un'occhiata ad alcune delle migliori pratiche che consentono di implementare rapidamente le modifiche senza sacrificare la disponibilità.

Disponi di un meccanismo per eseguire i rollback

Avere un pulsante Annulla può evitare i disastri. È consigliabile testare le distribuzioni in un ambiente inferiore separato (ambiente di test o sviluppo) prima di aggiornare il cluster di produzione. L'utilizzo di una CI/CD pipeline può aiutarti ad automatizzare e testare le distribuzioni. Con una pipeline di distribuzione continua, è possibile ripristinare rapidamente la versione precedente se l'aggiornamento risulta difettoso.

È possibile utilizzare Deployments per aggiornare un'applicazione in esecuzione. Questa operazione viene in genere eseguita aggiornando l'immagine del contenitore. Puoi usare kubectl per aggiornare una distribuzione come questa:

kubectl --record deployment.apps/nginx-deployment set image nginx-deployment nginx=nginx:1.16.1

L'--recordargomento registra le modifiche alla distribuzione e ti aiuta se devi eseguire un rollback. kubectl rollout history deploymentmostra le modifiche registrate alle distribuzioni nel cluster. Puoi annullare una modifica utilizzando. kubectl rollout undo deployment <DEPLOYMENT_NAME>

Per impostazione predefinita, quando si aggiorna una distribuzione che richiede la ricreazione dei pod, Deployment eseguirà un aggiornamento continuo. https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/ In altre parole, Kubernetes aggiornerà solo una parte dei pod in esecuzione in una distribuzione e non tutti i pod contemporaneamente. Puoi controllare il modo in cui Kubernetes esegue gli aggiornamenti continui tramite le proprietà. RollingUpdateStrategy

Quando si esegue un aggiornamento progressivo di una distribuzione, è possibile utilizzare la Max Unavailable proprietà per specificare il numero massimo di pod che possono non essere disponibili durante l'aggiornamento. La Max Surge proprietà di Deployment consente di impostare il numero massimo di Pod che possono essere creati rispetto al numero desiderato di Pod.

Valuta la possibilità di apportare modifiche max unavailable per garantire che l'implementazione non arrechi interruzioni ai tuoi clienti. Ad esempio, Kubernetes imposta il 25% per impostazione max unavailable predefinita, il che significa che se hai 100 pod, potresti avere solo 75 pod attivi durante un rollout. Se la tua applicazione richiede un minimo di 80 pod, questa implementazione può causare interruzioni. Puoi invece impostare un valore del 20% max unavailable per assicurarti che ci siano almeno 80 pod funzionanti durante il rollout.

Usa le distribuzioni blue/green

Le modifiche sono intrinsecamente rischiose, ma le modifiche che non possono essere annullate possono essere potenzialmente catastrofiche. Le procedure di modifica che consentono di tornare indietro nel tempo in modo efficace tramite un rollback rendono più sicuri i miglioramenti e la sperimentazione. Blue/green le implementazioni offrono un metodo per annullare rapidamente le modifiche in caso di problemi. In questa strategia di distribuzione, crei un ambiente per la nuova versione. Questo ambiente è identico alla versione corrente dell'applicazione da aggiornare. Una volta effettuato il provisioning del nuovo ambiente, il traffico viene indirizzato al nuovo ambiente. Se la nuova versione produce i risultati desiderati senza generare errori, il vecchio ambiente viene terminato. Altrimenti, il traffico viene ripristinato alla vecchia versione.

È possibile eseguire blue/green distribuzioni in Kubernetes creando una nuova distribuzione identica alla distribuzione della versione esistente. Dopo aver verificato che i Pod nella nuova distribuzione funzionino senza errori, puoi iniziare a inviare traffico alla nuova distribuzione modificando le selector specifiche del servizio che indirizza il traffico ai Pod della tua applicazione.

Molti strumenti di integrazione continua come Flux, Jenkins e Spinnaker consentono di automatizzare le implementazioni. blue/green Il blog di AWS Containers include una guida dettagliata all'uso di AWS Load Balancer Controller: utilizzo di AWS Load Balancer Controller per la distribuzione, la distribuzione canaria e i test blue/green A/B

Usa le distribuzioni Canary

Le implementazioni Canary sono una variante delle blue/green implementazioni in grado di eliminare in modo significativo i rischi derivanti dalle modifiche. In questa strategia di distribuzione, crei una nuova distribuzione con meno pod insieme alla vecchia distribuzione e diriga una piccola percentuale di traffico verso la nuova distribuzione. Se le metriche indicano che la nuova versione funziona allo stesso modo o è migliore rispetto alla versione esistente, aumenti progressivamente il traffico verso la nuova distribuzione, scalandola fino a deviare tutto il traffico verso la nuova distribuzione. In caso di problemi, puoi indirizzare tutto il traffico verso la vecchia distribuzione e interrompere l'invio di traffico verso la nuova distribuzione.

Sebbene Kubernetes non offra un modo nativo per eseguire implementazioni canarie, puoi utilizzare strumenti come Flagger con Istio. https://github.com/weaveworks/flagger https://docs.flagger.app/tutorials/istio-progressive-delivery

Controlli sanitari e autoriparazione

Nessun software è privo di bug, ma Kubernetes può aiutarti a ridurre al minimo l'impatto degli errori del software. In passato, se un'applicazione si bloccava, qualcuno doveva porre rimedio alla situazione riavviando l'applicazione manualmente. Kubernetes ti dà la possibilità di rilevare i guasti del software nei tuoi Pod e di sostituirli automaticamente con nuove repliche. Con Kubernetes puoi monitorare lo stato delle tue applicazioni e sostituire automaticamente le istanze non integre.

Kubernetes supporta tre tipi di controlli sullo stato di salute: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

  1. Sonda Liveness

  2. Sonda di avvio (supportata nella versione Kubernetes 1.16+)

  3. Sonda di prontezza

Kubelet, l'agente di Kubernetes, è responsabile dell'esecuzione di tutti i controlli sopra menzionati. Kubelet può controllare lo stato di salute di un Pod in tre modi: kubelet può eseguire un comando shell all'interno del contenitore di un Pod, inviare una richiesta HTTP GET al suo contenitore o aprire un socket TCP su una porta specificata.

Se scegli una sonda exec basata, che esegue uno script di shell all'interno di un contenitore, assicurati che il comando shell termini prima della scadenza del valore. timeoutSeconds Altrimenti, il nodo avrà <defunct> dei processi, con conseguente errore del nodo.

Raccomandazioni

Usa Liveness Probe per rimuovere i pod malsani

La sonda Liveness è in grado di rilevare condizioni di deadlock in cui il processo continua a funzionare, ma l'applicazione non risponde. Ad esempio, se utilizzi un servizio web che ascolta sulla porta 80, puoi configurare una sonda Liveness per inviare una richiesta HTTP GET sulla porta 80 del Pod. Kubelet invierà periodicamente una richiesta GET al Pod e si aspetterà una risposta; se il Pod risponde tra 200-399, il kubelet ritiene che il Pod sia integro; in caso contrario, il Pod verrà contrassegnato come non integro. Se un Pod non supera continuamente i controlli di stato, il kubelet lo interromperà.

Puoi usarlo per ritardare la prima initialDelaySeconds sonda.

Quando usate Liveness Probe, assicuratevi che la vostra applicazione non si imbatta in una situazione in cui tutti i Pod falliscano simultaneamente, perché Kubernetes cercherà di sostituire tutti i Pod, il che renderà l'applicazione offline. Inoltre, Kubernetes continuerà a creare nuovi Pod che falliranno anche con Liveness Probes, mettendo a dura prova il piano di controllo. Evita di configurare Liveness Probe in modo che dipenda da un fattore esterno al tuo Pod, ad esempio un database esterno. In altre parole, un database esterno al tuo POD che non risponde non dovrebbe far sì che i tuoi Pod falliscano con i loro Liveness Probe.

Il post di Sandor Szücs LIVENESS PROBES ARE DANGEROUS descrive i problemi che possono essere causati da sonde non configurate correttamente.

Usa Startup Probe per le applicazioni che richiedono più tempo per essere avviate

Quando l'app richiede più tempo per l'avvio, puoi utilizzare Startup Probe per ritardare la Liveness and Readiness Probe. Ad esempio, un'app Java che deve idratare la cache da un database può richiedere fino a due minuti prima di essere completamente funzionante. Qualsiasi Liveness o Readiness Probe fino a quando non sarà completamente funzionante potrebbe fallire. La configurazione di uno Startup Probe consentirà all'app Java di ripristinare lo stato di integrità prima dell'esecuzione di Liveness o Readiness Probe.

Finché Startup Probe non ha esito positivo, tutte le altre Probe vengono disattivate. Puoi definire il tempo massimo che Kubernetes deve attendere per l'avvio dell'applicazione. Se, dopo il tempo massimo configurato, il Pod continua a non funzionare con Startup Probes, verrà terminato e verrà creato un nuovo Pod.

Lo Startup Probe è simile al Liveness Probe: se fallisce, il Pod viene ricreato. Come spiega Ricardo A. nel suo post Fantastic Probes And How To Configure Them, Startup Probes dovrebbe essere usato quando il tempo di avvio di un'applicazione è imprevedibile. Se sai che la tua applicazione impiega dieci secondi per avviarsi, dovresti invece usare Probe with. Liveness/Readiness initialDelaySeconds

Usa Readiness Probe per rilevare l'indisponibilità parziale

Mentre la sonda Liveness rileva i guasti in un'app che vengono risolti chiudendo il Pod (quindi riavviando l'app), Readiness Probe rileva le condizioni in cui l'app potrebbe essere temporaneamente non disponibile. In queste situazioni, l'app potrebbe temporaneamente non rispondere; tuttavia, si prevede che torni a funzionare una volta completata l'operazione.

Ad esempio, durante intense I/O operazioni su disco, le applicazioni potrebbero essere temporaneamente non disponibili per gestire le richieste. In questo caso, chiudere il Pod dell'applicazione non è una soluzione; allo stesso tempo, le richieste aggiuntive inviate al Pod possono fallire.

Puoi utilizzare Readiness Probe per rilevare l'indisponibilità temporanea dell'app e interrompere l'invio di richieste al relativo Pod finché non torna a funzionare. A differenza di Liveness Probe, in cui un errore comporterebbe una ricreazione di Pod, un Readiness Probe guasto significherebbe che Pod non riceverà alcun traffico dal servizio Kubernetes. Quando Readiness Probe ha esito positivo, Pod riprenderà a ricevere traffico dal Servizio.

Proprio come Liveness Probe, evita di configurare Readiness Probe che dipendono da una risorsa esterna al Pod (come un database). Ecco uno scenario in cui un Readiness configurato male può rendere l'applicazione non funzionale: se il Readiness Probe di un Pod si guasta quando il database dell'app è irraggiungibile, anche altre repliche Pod falliranno contemporaneamente poiché condividono gli stessi criteri di controllo dello stato. Impostando la sonda in questo modo, ogni volta che il database non è disponibile, i Readiness Probe del Pod falliranno e Kubernetes interromperà l'invio di traffico a tutti i Pod.

Un effetto collaterale dell'utilizzo di Readiness Probes è che possono aumentare il tempo necessario per aggiornare le implementazioni. Le nuove repliche non riceveranno traffico a meno che Readiness Probes non abbia esito positivo; fino ad allora, le vecchie repliche continueranno a ricevere traffico.

Gestire le interruzioni

I Pod hanno una durata limitata: anche se ne possiedi di lunga durata, è prudente assicurarsi che i Pod si terminino correttamente quando arriva il momento. A seconda della strategia di aggiornamento, gli aggiornamenti dei cluster Kubernetes potrebbero richiedere la creazione di nuovi nodi di lavoro, il che richiede la ricreazione di tutti i Pod sui nodi più recenti. Una corretta gestione delle terminazioni e i Pod Disruption Budget possono aiutarti a evitare interruzioni del servizio poiché i Pod vengono rimossi dai nodi più vecchi e ricreati sui nodi più recenti.

Il modo migliore per aggiornare i nodi di lavoro è creare nuovi nodi di lavoro e terminare quelli vecchi. Prima di terminare i nodi di lavoro, dovresti drain farlo. Quando un nodo di lavoro viene svuotato, tutti i suoi pod vengono rimossi in modo sicuro. La sicurezza è una parola chiave in questo caso; quando i pod di un lavoratore vengono sfrattati, non gli viene semplicemente inviato un segnale. SIGKILL Viene invece inviato un SIGTERM segnale al processo principale (PID 1) di ciascun contenitore contenuto nei Pod da sgomberare. Dopo l'invio SIGTERM del segnale, Kubernetes concederà al processo un po' di tempo (periodo di tolleranza) prima che venga inviato un segnale. SIGKILL Questo periodo di tolleranza è di 30 secondi per impostazione predefinita; puoi sovrascrivere il valore predefinito utilizzando grace-period flag in kubectl o declare nel tuo Podspec. terminationGracePeriodSeconds

kubectl delete pod <pod name> —grace-period=<seconds>

È comune avere contenitori in cui il processo principale non ha il PID 1. Considera questo contenitore Python-based di esempio:

$ kubectl exec python-app -it ps PID USER TIME COMMAND 1 root 0:00 {script.sh} /bin/sh ./script.sh 5 root 0:00 python app.py

In questo esempio, lo script di shell riceveSIGTERM, il processo principale, che in questo esempio è un'applicazione Python, non riceve alcun SIGTERM segnale. Quando il Pod viene terminato, l'applicazione Python verrà interrotta bruscamente. Questo problema può essere risolto modificando la dimensione del contenitore per ENTRYPOINT avviare l'applicazione Python. In alternativa, puoi usare uno strumento come dumb-init per assicurarti che la tua applicazione sia in grado di gestire i segnali.

Puoi anche utilizzare gli hook di Container per eseguire uno script o una richiesta HTTP all'avvio o all'arresto del contenitore. L'azione PreStop hook viene eseguita prima che il contenitore riceva un SIGTERM segnale e deve essere completata prima che questo segnale venga inviato. Il terminationGracePeriodSeconds valore si applica da quando l'azione PreStop hook inizia l'esecuzione, non quando il SIGTERM segnale viene inviato.

Raccomandazioni

Proteggi i carichi di lavoro critici con Pod Disruption Budgets

Pod Disruption Budget o PDB possono interrompere temporaneamente il processo di sfratto se il numero di repliche di una domanda scende al di sotto della soglia dichiarata. Il processo di sfratto continuerà una volta che il numero di repliche disponibili avrà superato la soglia. È possibile utilizzare PDB per dichiarare il numero e il minAvailable numero di repliche. maxUnavailable Ad esempio, se desideri che siano disponibili almeno tre copie della tua app, puoi creare un PDB.

apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: my-svc-pdb spec: minAvailable: 3 selector: matchLabels: app: my-svc

La politica PDB sopra riportata indica a Kubernetes di interrompere il processo di sfratto fino a quando non saranno disponibili tre o più repliche. Il PodDisruptionBudgets drenaggio dei nodi rispetta. Durante un aggiornamento di un gruppo di nodi gestito da EKS, i nodi vengono svuotati con un timeout di quindici minuti. Dopo quindici minuti, se l'aggiornamento non è forzato (l'opzione si chiama Rolling update nella console EKS), l'aggiornamento non riesce. Se l'aggiornamento è forzato, i pod vengono eliminati.

Per i nodi autogestiti, puoi anche utilizzare strumenti come AWS Node Termination Handler, che assicurano che il piano di controllo di Kubernetes risponda in modo appropriato agli eventi che possono rendere l'istanza EC2 non disponibile, come eventi di manutenzione EC2 e interruzioni EC2 Spot. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html Utilizza l'API Kubernetes per isolare il nodo in modo da garantire che non siano programmati nuovi pod, quindi lo scarica, interrompendo tutti i pod in esecuzione.

Puoi utilizzare Pod anti-affinity per pianificare i pod di una distribuzione su nodi diversi ed evitare ritardi legati al PDB durante gli aggiornamenti dei nodi.

Pratica l'ingegneria del caos

L'ingegneria del caos è la disciplina della sperimentazione su un sistema distribuito al fine di aumentare la fiducia nella capacità del sistema di resistere a condizioni turbolente durante la produzione.

Nel suo blog, Dominik Tornow spiega che Kubernetes è un sistema dichiarativo in cui "l'utente fornisce una rappresentazione dello stato desiderato del sistema al sistema. Il sistema considera quindi lo stato corrente e lo stato desiderato per determinare la sequenza di comandi per passare dallo stato corrente allo stato desiderato. » Ciò significa che Kubernetes memorizza sempre lo stato desiderato e se il sistema si discosta, Kubernetes interverrà per ripristinare lo stato. Ad esempio, se un nodo di lavoro diventa non disponibile, Kubernetes riprogrammerà i Pod su un altro nodo di lavoro. Allo stesso modo, in caso di replica arresto anomalo, il Deployment Controller ne creerà uno nuovo. https://kubernetes.io/docs/concepts/architecture/controller/#design replica In questo modo, i controller Kubernetes correggono automaticamente i guasti.

Gli strumenti di Chaos Engineering come Gremlin ti aiutano a testare la resilienza del tuo cluster Kubernetes e a identificare i singoli punti di errore. Gli strumenti che introducono il caos artificiale nel tuo cluster (e non solo) possono scoprire debolezze sistemiche, offrire l'opportunità di identificare colli di bottiglia e configurazioni errate e correggere i problemi in un ambiente controllato. La filosofia di Chaos Engineering raccomanda di rompere le cose apposta e di sottoporre a stress test l'infrastruttura per ridurre al minimo i tempi di inattività imprevisti.

Usa una Service Mesh

È possibile utilizzare una service mesh per migliorare la resilienza dell'applicazione. Le service mesh consentono la comunicazione da servizio a servizio e aumentano l'osservabilità della rete di microservizi. La maggior parte dei prodotti service mesh funziona facendo eseguire un piccolo proxy di rete insieme a ciascun servizio che intercetta e ispeziona il traffico di rete dell'applicazione. È possibile inserire l'applicazione in una mesh senza modificarla. Utilizzando le funzionalità integrate del service proxy, è possibile fare in modo che generi statistiche di rete, crei registri di accesso e aggiunga intestazioni HTTP alle richieste in uscita per il tracciamento distribuito.

Una service mesh può aiutarti a rendere i tuoi microservizi più resilienti con funzionalità come tentativi automatici delle richieste, timeout, interruzione del circuito e limitazione della velocità.

Se gestisci più cluster, puoi utilizzare una service mesh per abilitare la comunicazione da servizio a servizio tra cluster.

Reti di servizio

Osservabilità

L'osservabilità è un termine generico che include monitoraggio, registrazione e tracciamento. Le applicazioni basate su microservizi sono distribuite per natura. A differenza delle applicazioni monolitiche in cui è sufficiente il monitoraggio di un singolo sistema, in un'architettura applicativa distribuita è necessario monitorare le prestazioni di ogni componente. È possibile utilizzare sistemi di monitoraggio, registrazione e tracciamento distribuito a livello di cluster per identificare i problemi nel cluster prima che causino interruzioni ai clienti.

Gli strumenti integrati di Kubernetes per la risoluzione dei problemi e il monitoraggio sono limitati. Il metrics-server raccoglie le metriche delle risorse e le archivia in memoria ma non le conserva. Puoi visualizzare i log di un Pod usando kubectl, ma Kubernetes non conserva automaticamente i log. E l'implementazione del tracciamento distribuito viene eseguita a livello di codice dell'applicazione o utilizzando mesh di servizi.

L'estensibilità di Kubernetes brilla qui. Kubernetes ti consente di portare la tua soluzione centralizzata preferita di monitoraggio, registrazione e tracciamento.

Raccomandazioni

Monitora le tue applicazioni

Il numero di metriche da monitorare nelle applicazioni moderne è in continua crescita. È utile disporre di un metodo automatizzato per tracciare le applicazioni in modo da potersi concentrare sulla risoluzione delle sfide dei clienti. Cluster-wide strumenti di monitoraggio come Prometheus o CloudWatch Container Insights possono monitorare il cluster e il carico di lavoro e fornirti segnali quando, o preferibilmente, prima che le cose vadano male.

Gli strumenti di monitoraggio consentono di creare avvisi a cui il team operativo può abbonarsi. Prendi in considerazione le regole per attivare gli allarmi per eventi che, se aggravati, possono causare un'interruzione o influire sulle prestazioni delle applicazioni.

Se non ti è chiaro quali metriche monitorare, puoi trarre ispirazione da questi metodi:

  • Metodo RED. È l'acronimo di richieste, errori e durata.

  • Metodo USE. È l'acronimo di utilizzo, saturazione ed errori.

Il post di Sysdig Le migliori pratiche per gli avvisi su Kubernetes include un elenco completo di componenti che possono influire sulla disponibilità delle applicazioni.

Usa la libreria client Prometheus per esporre le metriche delle applicazioni

Oltre a monitorare lo stato dell'applicazione e ad aggregare le metriche standard, puoi anche utilizzare la libreria client Prometheus per esporre metriche personalizzate specifiche dell'applicazione per migliorarne l'osservabilità.

Utilizza strumenti di registrazione centralizzati per raccogliere e conservare i log

La registrazione in EKS rientra in due categorie: registri del piano di controllo e registri delle applicazioni. La registrazione del piano di controllo EKS fornisce registri di controllo e diagnostica direttamente dal piano di controllo ai CloudWatch registri dell'account. I log delle applicazioni sono log prodotti dai Pods in esecuzione all'interno del cluster. I log delle applicazioni includono i log prodotti da Pods che eseguono le applicazioni di business logic e i componenti del sistema Kubernetes come CoreDNS, Cluster Autoscaler, Prometheus, ecc.

EKS fornisce cinque tipi di log del piano di controllo:

  1. Log dei componenti del server API Kubernetes

  2. Audit

  3. Autenticatore

  4. Controller manager

  5. Scheduler

I registri del controller manager e dello scheduler possono aiutare a diagnosticare i problemi del piano di controllo, come strozzature ed errori. Per impostazione predefinita, i log del piano di controllo EKS non vengono inviati a Logs. CloudWatch Puoi abilitare la registrazione del piano di controllo e selezionare i tipi di log del piano di controllo EKS da acquisire per ogni cluster del tuo account

La raccolta dei log delle applicazioni richiede l'installazione di uno strumento di aggregazione dei log come Fluent Bit, Fluentd o CloudWatch Container Insights nel cluster.

Gli strumenti di aggregazione dei log di Kubernetes vengono eseguiti come ed estraggono i log dei container dai nodi. DaemonSets I log delle applicazioni vengono quindi inviati a una destinazione centralizzata per l'archiviazione. Ad esempio, CloudWatch Container Insights può utilizzare Fluent Bit o Fluentd per raccogliere i log e inviarli a Logs per l'CloudWatch archiviazione. Fluent Bit e Fluentd supportano molti popolari sistemi di analisi dei log come Elasticsearch e InfluxDB, offrendoti la possibilità di cambiare il backend di archiviazione per i tuoi log modificando Fluent bit o la configurazione dei log di Fluentd.

Utilizzate un sistema di tracciamento distribuito per identificare i colli di bottiglia

Una tipica applicazione moderna ha componenti distribuiti in rete e la sua affidabilità dipende dal corretto funzionamento di ciascuno dei componenti che compongono l'applicazione. È possibile utilizzare una soluzione di tracciamento distribuito per capire come fluiscono le richieste e come comunicano i sistemi. Le tracce possono mostrare dove esistono strozzature nella rete applicativa e prevenire problemi che possono causare guasti a catena.

Sono disponibili due opzioni per implementare il tracciamento nelle applicazioni: è possibile implementare il tracciamento distribuito a livello di codice utilizzando librerie condivise o utilizzare una service mesh.

L'implementazione del tracciamento a livello di codice può essere svantaggiosa. In questo metodo, è necessario apportare modifiche al codice. Ciò è ulteriormente complicato se hai applicazioni poliglotte. Sei anche responsabile della gestione di un'altra libreria, tra i tuoi servizi.

Le Service Mesh come LinkerD e Istio possono essere utilizzate per implementare il tracciamento distribuito nell'applicazione con modifiche minime al codice dell'applicazione. È possibile utilizzare Service Mesh per standardizzare la generazione, la registrazione e il tracciamento delle metriche.

Strumenti di tracciamento come AWS e Jaeger supportano sia X-Ray le librerie condivise che le implementazioni di service mesh.

Prendi in considerazione l'utilizzo di uno strumento di tracciamento come AWS X-Ray o Jaeger che supporti entrambe le implementazioni (libreria condivisa e service mesh) in modo da non dover cambiare strumento se successivamente adotterai service mesh.