

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à.

# Migliori pratiche per l'affidabilità
<a name="reliability"></a>

Questa sezione fornisce indicazioni su come rendere i carichi di lavoro in esecuzione su EKS resilienti e altamente disponibili

## Come utilizzare questa guida
<a name="how-to-use-this-guide"></a>

Questa guida è destinata a sviluppatori e architetti che desiderano sviluppare e gestire servizi ad alta disponibilità e con tolleranza ai guasti in EKS. La guida è organizzata in diverse aree tematiche per facilitarne la fruizione. Ogni argomento inizia con una breve panoramica, seguita da un elenco di consigli e best practice per l'affidabilità dei cluster EKS.

## Introduzione
<a name="introduction"></a>

Le migliori pratiche di affidabilità per EKS sono state raggruppate nei seguenti argomenti:
+ Applicazioni
+ Piano di controllo
+ Piano dei dati

Cosa rende affidabile un sistema? Se un sistema può funzionare in modo coerente e soddisfare le esigenze nonostante i cambiamenti dell'ambiente nel corso di un periodo di tempo, può essere definito affidabile. A tal fine, il sistema deve rilevare i guasti, correggersi automaticamente e avere la capacità di scalare in base alla domanda.

I clienti possono utilizzare Kubernetes come base per gestire applicazioni e servizi mission-critical in modo affidabile. Ma oltre a incorporare principi di progettazione delle applicazioni basate su container, l'esecuzione affidabile dei carichi di lavoro richiede anche un'infrastruttura affidabile. In Kubernetes, l'infrastruttura comprende il piano di controllo e il piano dati.

EKS fornisce un piano di controllo Kubernetes di livello di produzione progettato per essere altamente disponibile e tollerante ai guasti.

In EKS, AWS è responsabile dell'affidabilità del piano di controllo Kubernetes. EKS esegue il piano di controllo Kubernetes su tre zone di disponibilità in una regione AWS. Gestisce automaticamente la disponibilità e la scalabilità dei server API Kubernetes e del cluster etcd.

La responsabilità dell'affidabilità del piano dati è condivisa tra te, il cliente e AWS. EKS offre quattro opzioni di nodi di lavoro per l'implementazione del piano dati Kubernetes.

 [EKS Auto Mode](https://docs.aws.amazon.com/eks/latest/userguide/automode.html), che è l'opzione più gestita, gestisce il provisioning, il ridimensionamento e gli aggiornamenti del piano dati oltre a fornire funzionalità gestite di elaborazione, rete e archiviazione. La modalità AMIs automatica viene rilasciata frequentemente e i cluster vengono aggiornati automaticamente all'AMI più recente per implementare correzioni CVE e patch di sicurezza. È possibile controllare quando ciò si verifica configurando i controlli delle [interruzioni](https://docs.aws.amazon.com/eks/latest/userguide/create-node-pool.html#_disruption) nella modalità Auto. NodePools

Fargate gestisce il provisioning e la scalabilità del piano dati eseguendo un Pod per nodo. La terza opzione, i gruppi di nodi gestiti, gestisce il provisioning e gli aggiornamenti del piano dati. Infine, i nodi autogestiti sono l'opzione meno gestita per il piano dati. Maggiore è il piano dati gestito da AWS, minore è la responsabilità.

 [I gruppi di nodi gestiti](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) automatizzano il provisioning e la gestione del ciclo di vita dei nodi EC2. Puoi utilizzare l'API EKS (utilizzando la console EKS, l'API AWS, l'AWS CLICloudFormation, Terraform o`eksctl`) per creare, scalare e aggiornare nodi gestiti. I nodi gestiti eseguono istanze Amazon Linux 2 EC2 ottimizzate per EKS nel tuo account e puoi installare pacchetti software personalizzati abilitando l'accesso SSH. Quando effettui il provisioning dei nodi gestiti, questi vengono eseguiti come parte di un gruppo di Auto Scaling gestito da EKS che può estendersi su più zone di disponibilità; il controllo avviene tramite le sottoreti fornite durante la creazione di nodi gestiti. EKS inoltre contrassegna automaticamente i nodi gestiti in modo che possano essere utilizzati con Cluster Autoscaler.

Amazon EKS segue il modello di responsabilità condivisa CVEs e le patch di sicurezza sui gruppi di nodi gestiti. Poiché i nodi gestiti eseguono sistemi ottimizzati per Amazon EKS, AMIs Amazon EKS è responsabile della creazione di versioni patchate di questi AMIs durante la correzione dei bug. L'utente è invece responsabile della distribuzione di queste versioni AMI con patch ai gruppi di nodi gestiti.

EKS [gestisce anche l'aggiornamento dei nodi](https://docs.aws.amazon.com/eks/latest/userguide/update-managed-node-group.html), sebbene sia necessario avviare il processo di aggiornamento. Il processo di [aggiornamento del nodo gestito](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-update-behavior.html) è spiegato nella documentazione EKS.

Se esegui nodi autogestiti, puoi utilizzare l'[AMI Linux ottimizzata per Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html) per creare nodi di lavoro. L'utente è responsabile dell'applicazione di patch e dell'aggiornamento dell'AMI e dei nodi. [È consigliabile utilizzare l'`eksctl`infrastruttura come strumenti di codice per il provisioning di nodi autogestiti CloudFormation, poiché in questo modo sarà più semplice aggiornare i nodi autogestiti.](https://docs.aws.amazon.com/eks/latest/userguide/update-workers.html) Prendi in considerazione [la migrazione a nuovi nodi](https://docs.aws.amazon.com/eks/latest/userguide/migrate-stack.html) quando aggiorni i nodi di lavoro, poiché il processo di migrazione altera **il** vecchio gruppo di nodi `NoSchedule` e **prosciuga** i nodi dopo che un nuovo stack è pronto ad accettare il carico di lavoro del pod esistente. Tuttavia, puoi anche eseguire un aggiornamento sul posto dei nodi [autogestiti.](https://docs.aws.amazon.com/eks/latest/userguide/update-stack.html)

 **Modello di responsabilità condivisa - Fargate** 

![\[Modello di responsabilità condivisa - Fargate\]](http://docs.aws.amazon.com/it_it/eks/latest/best-practices/images/reliability/SRM-Fargate.jpeg)


 **Modello di responsabilità condivisa - MNG** 

![\[Modello di responsabilità condivisa - MNG\]](http://docs.aws.amazon.com/it_it/eks/latest/best-practices/images/reliability/SRM-MNG.jpeg)


Questa guida include una serie di consigli che puoi utilizzare per migliorare l'affidabilità del tuo piano dati EKS, dei componenti principali di Kubernetes e delle tue applicazioni.

## Feedback
<a name="feedback"></a>

Questa guida è stata pubblicata GitHub per raccogliere feedback e suggerimenti diretti dalla community più ampia. EKS/Kubernetes Se hai una best practice che ritieni debba essere inclusa nella guida, segnala un problema o invia un PR nell' GitHub archivio. Intendiamo aggiornare periodicamente la guida man mano che vengono aggiunte nuove funzionalità al servizio o quando si evolve una nuova best practice.

# Esecuzione di applicazioni ad alta disponibilità
<a name="application"></a>

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 mantiene le applicazioni e i servizi operativi senza interruzioni, il che rende felici gli utenti. Un'infrastruttura scalabile cresce e si restringe in base alle esigenze dell'azienda. L'eliminazione dei singoli punti di errore è un passaggio fondamentale per migliorare la disponibilità di un'applicazione e renderla resiliente.

Con Kubernetes, puoi utilizzare le tue applicazioni ed eseguirle in modo altamente disponibile e resiliente. [La sua gestione dichiarativa assicura 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
<a name="_recommendations"></a>

### Configura Pod Disruption Budgets
<a name="_configure_pod_disruption_budgets"></a>

 I [Pod Disruption Budgets](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) 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 conoscono e rispettano i budget Pod Disruption configurati in fase di ridimensionamento. EKS Auto Mode, Karpenter e Managed Node Groups rispettano anche i Pod Disruption Budgets durante l'aggiornamento dei nodi

### Evita di utilizzare Singleton Pods
<a name="_avoid_running_singleton_pods"></a>

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

### Esegui più repliche
<a name="_run_multiple_replicas"></a>

L'esecuzione di più Repliche Pods di un'app utilizzando un Deployment ne aiuta l'esecuzione in modo ad alta disponibilità. 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 ridimensionare automaticamente le repliche](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) in base alla richiesta del carico di lavoro.

### Pianifica le repliche tra i nodi
<a name="_schedule_replicas_across_nodes"></a>

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

È possibile migliorare ulteriormente l'affidabilità di un'applicazione tipica eseguendola su più applicazioni. AZs

#### Utilizzo delle regole anti-affinità Pod
<a name="_using_pod_anti_affinity_rules"></a>

Il manifesto seguente indica allo scheduler di Kubernetes di *preferire* posizionare i pod su nodi separati e. AZs Non richiede nodi distinti o AZ perché, in tal caso, Kubernetes non sarà in grado di pianificare alcun pod una volta che c'è un pod in esecuzione in ciascuna AZ. Se l'applicazione richiede solo tre repliche, puoi utilizzare `requiredDuringSchedulingIgnoredDuringExecution` for `topologyKey: topology.kubernetes.io/zone` e Kubernetes scheduler non pianificherà due pod nella stessa 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
<a name="_using_pod_topology_spread_constraints"></a>

Analogamente alle regole di 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. AZs Questo approccio funziona molto bene quando si cerca di garantire la tolleranza agli errori e la disponibilità utilizzando 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 di topologia, perché i pod con un'antiaffinità l'uno verso l'altro hanno un effetto repellente. In questi casi, una singola replica su un nodo dedicato non è ideale per la tolleranza agli errori né rappresenta un buon uso delle risorse. Con i vincoli di diffusione della topologia, si ha un maggiore controllo sulla diffusione o sulla distribuzione che lo scheduler dovrebbe cercare di applicare tra i domini della topologia. Ecco alcune proprietà importanti da utilizzare in questo approccio:

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

1. `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"
   ```

1. La `whenUnsatisfiable` proprietà viene utilizzata per determinare come si desidera che lo scheduler risponda se i vincoli desiderati non possono essere soddisfatti.

1. `labelSelector`Viene utilizzato per trovare i pod corrispondenti in modo che lo scheduler possa esserne a conoscenza quando decide dove posizionare i pod in base ai vincoli specificati.

[Oltre a quelli precedenti, ci sono altri campi che puoi approfondire nella documentazione di Kubernetes.](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/)

**La topologia dei pod distribuisce i vincoli su 3 AZs**  
 ![\[Pod topology spread constraints across 3 AZs\]](http://docs.aws.amazon.com/it_it/eks/latest/best-practices/images/reliability/pod-topology-spread-constraints.jpg) 

```
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
<a name="_run_kubernetes_metrics_server"></a>

Installa il server di [metrica](https://github.com/kubernetes-sigs/metrics-server) Kubernetes per aiutarti a scalare le tue applicazioni. [I componenti aggiuntivi di Kubernetes autoscaler come [HPA e VPA](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) devono tenere traccia delle metriche delle applicazioni per scalarle.](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler) Il metrics-server raccoglie i parametri delle risorse che possono essere utilizzati per prendere decisioni di scalabilità. [Le metriche vengono raccolte da kubelets e fornite nel formato Metrics API.](https://github.com/kubernetes/metrics)

Il server di metrica 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 dell'applicazione nel tempo, hai bisogno di uno strumento di monitoraggio come Prometheus o Amazon. CloudWatch

Segui la [documentazione EKS](https://docs.aws.amazon.com/eks/latest/userguide/metrics-server.html) per installare metrics-server nel tuo cluster EKS.

## Horizontal Pod Autoscaler (HPA)
<a name="_horizontal_pod_autoscaler_hpa"></a>

HPA può scalare automaticamente la vostra applicazione in risposta alla domanda e aiutarvi a evitare di avere ripercussioni sui clienti durante i picchi di traffico. È implementato come un anello di controllo in Kubernetes che interroga periodicamente le metriche che forniscono le metriche delle risorse. APIs 

HPA può recuperare le metriche da quanto segue: 1. APIs `metrics.k8s.io`nota anche come API Resource Metrics: fornisce l'utilizzo di CPU e 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 (ad esempio, SQS Queue Depth, latenza ELB).

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

### Scalabilità delle applicazioni in base a metriche personalizzate o esterne
<a name="_scaling_applications_based_on_custom_or_external_metrics"></a>

È possibile utilizzare metriche personalizzate o esterne per ridimensionare l'applicazione in base a metriche diverse dall'utilizzo della CPU o della memoria. I server [Custom Metrics](https://github.com/kubernetes-sigs/custom-metrics-apiserver) API forniscono l'`custom-metrics.k8s.io`API che HPA può utilizzare per la scalabilità automatica delle applicazioni.

Puoi utilizzare [Prometheus Adapter for Kubernetes APIs Metrics per raccogliere metriche da Prometheus](https://github.com/directxman12/k8s-prometheus-adapter) e utilizzarle con l'HPA. [In questo caso, l'adattatore Prometheus esporrà le metriche 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 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 ridimensionare il numero di repliche in base al numero di lavori in esecuzione 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](https://aws.amazon.com/blogs/mt/autoscaling-kubernetes-workloads-with-keda-using-amazon-managed-service-for-prometheus-metrics/) descrive come utilizzare Amazon Managed Service for Prometheus per l'auto-scaling dei carichi di lavoro Kubernetes.

## Vertical Pod Autoscaler (VPA)
<a name="_vertical_pod_autoscaler_vpa"></a>

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, operazione che avviene aumentando l'allocazione delle risorse, è possibile utilizzare [VPA](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler) per ridimensionare automaticamente le repliche dei Pod o fornire consigli di ridimensionamento.

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

 La [documentazione EKS](https://docs.aws.amazon.com/eks/latest/userguide/vertical-pod-autoscaler.html) include una procedura dettagliata per la configurazione di VPA.

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

## Aggiornamento delle applicazioni
<a name="_updating_applications"></a>

Le applicazioni moderne richiedono un'innovazione rapida 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
<a name="_have_a_mechanism_to_perform_rollbacks"></a>

Avere un pulsante Annulla può evitare i disastri. È consigliabile testare le implementazioni in un ambiente inferiore separato (ambiente di test o sviluppo) prima di aggiornare il cluster di produzione. L'utilizzo di una pipeline CI/CD può aiutarti ad automatizzare e testare le implementazioni. Con una pipeline di distribuzione continua, è possibile tornare rapidamente alla 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 in questo modo:

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

L'`--record`argomento registra le modifiche al Deployment e ti aiuta se devi eseguire un rollback. `kubectl rollout history deployment`mostra le modifiche registrate alle distribuzioni nel cluster. È possibile ripristinare una modifica utilizzando. `kubectl rollout undo deployment <DEPLOYMENT_NAME>`

[Per impostazione predefinita, quando aggiorni una distribuzione che richiede la creazione di pod, Deployment eseguirà un aggiornamento progressivo.](https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/) In altre parole, Kubernetes aggiornerà solo una parte dei pod in esecuzione in un Deployment e non tutti i Pod contemporaneamente. Puoi controllare il modo in cui Kubernetes esegue gli aggiornamenti continui tramite la proprietà. `RollingUpdateStrategy`

Quando si esegue un *aggiornamento continuo* di una distribuzione, è possibile utilizzare la [https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-unavailable](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-unavailable)proprietà per specificare il numero massimo di Pod che non possono essere disponibili durante l'aggiornamento. La `Max Surge` proprietà Deployment consente di impostare il numero massimo di Pod che possono essere creati sul numero desiderato di Pod.

Valuta la possibilità di `max unavailable` apportare modifiche per garantire che l'implementazione non arrechi problemi ai 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'implementazione. Se la tua applicazione richiede un minimo di 80 Pod, questa implementazione può causare interruzioni. Puoi invece impostarlo `max unavailable` al 20% per assicurarti che ci siano almeno 80 Pod funzionanti durante l'implementazione.

### Usa le distribuzioni blue/green
<a name="_use_bluegreen_deployments"></a>

Le modifiche sono intrinsecamente rischiose, ma le modifiche che non possono essere annullate possono avere effetti potenzialmente catastrofici. Le procedure di modifica che consentono di tornare efficacemente indietro nel tempo attraverso 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, si crea un ambiente per la nuova versione. Questo ambiente è identico alla versione corrente dell'applicazione in fase di aggiornamento. 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 chiuso. In caso contrario, il traffico viene ripristinato alla versione precedente.

Puoi eseguire blue/green distribuzioni in Kubernetes creando una nuova distribuzione identica a quella 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 indirizzano il traffico verso i Pod dell'applicazione.

Molti strumenti di integrazione continua come [Flux](https://fluxcd.io), [Jenkins e [Spinnaker](https://spinnaker.io) consentono di automatizzare](https://www.jenkins.io) le implementazioni. blue/green Il blog di AWS Containers include una procedura dettagliata sull'uso di AWS Load Balancer Controller: [utilizzo di AWS Load Balancer Controller blue/green per](https://aws.amazon.com/blogs/containers/using-aws-load-balancer-controller-for-blue-green-deployment-canary-deployment-and-a-b-testing/) la distribuzione, implementazione canary e test A/B 

### Usa le distribuzioni Canary
<a name="_use_canary_deployments"></a>

Le implementazioni Canary sono una variante delle implementazioni che possono eliminare in modo significativo i blue/green rischi derivanti dalle modifiche. In questa strategia di distribuzione, oltre a quella precedente, crei una nuova distribuzione con meno pod e dirottando una piccola percentuale di traffico verso la nuova distribuzione. Se le metriche indicano che la nuova versione offre prestazioni uguali o migliori rispetto alla versione esistente, si aumenta progressivamente il traffico verso la nuova distribuzione e lo si aumenta 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 del traffico verso la nuova distribuzione.

[https://github.com/weaveworks/flagger](https://github.com/weaveworks/flagger)

## Controlli sanitari e autoguarigione
<a name="_health_checks_and_self_healing"></a>

Nessun software è privo di bug, ma Kubernetes può aiutarti a ridurre al minimo l'impatto dei guasti 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 sanitari:](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)

1. Sonda Liveness

1. Sonda di avvio (supportata nella versione 1.16\$1 di Kubernetes)

1. Sonda di prontezza

 [Kubelet](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/), l'agente Kubernetes, è responsabile dell'esecuzione di tutti i controlli sopra menzionati. Kubelet può controllare lo stato 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 relativo 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 esca prima della scadenza del valore.* `timeoutSeconds` Altrimenti, il nodo avrà `<defunct>` dei processi che porteranno al fallimento del nodo.

## Raccomandazioni
<a name="_recommendations_2"></a>

### Usa Liveness Probe per rimuovere i pod malsani
<a name="_use_liveness_probe_to_remove_unhealthy_pods"></a>

La sonda Liveness è in grado di rilevare condizioni di *stallo* 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 di Pod. Kubelet invierà periodicamente una richiesta GET al Pod e si aspetta una risposta; se il Pod risponde tra 200 e 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 sanitari, il kubelet lo interromperà.

È possibile utilizzarlo per ritardare la prima `initialDelaySeconds` sonda.

Quando usi Liveness Probe, assicurati che la tua applicazione non si verifichi una situazione in cui tutti i Pod falliscono contemporaneamente il Liveness Probe perché Kubernetes proverà a sostituire tutti i tuoi Pod, il che renderà l'applicazione offline. Inoltre, Kubernetes continuerà a creare nuovi Pod che non funzioneranno nemmeno con le sonde Liveness, il che metterà 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 external-to-your-Pod database che non risponde non dovrebbe far fallire i Liveness Probe ai tuoi Pod.

Nel post [LIVENESS PROBES ARE DANGEROUS di Sandor Szücs vengono descritti i problemi che possono essere causati da sonde](https://srcco.de/posts/kubernetes-liveness-probes-are-dangerous.html) mal configurate.

### Utilizzate Startup Probe per le applicazioni che richiedono più tempo per avviarsi
<a name="_use_startup_probe_for_applications_that_take_longer_to_start"></a>

Quando l'app necessita di più tempo per l'avvio, puoi utilizzare Startup Probe per ritardare l'avvio di Liveness and Readiness Probe. Ad esempio, un'app Java che deve idratare la cache di un database può richiedere fino a due minuti prima di essere completamente funzionante. Qualsiasi sonda Liveness o Readiness finché non diventa completamente funzionante potrebbe fallire. La configurazione di una Startup Probe consentirà all'app Java di funzionare correttamente prima dell'esecuzione di Liveness o *Readiness* Probe.

Finché lo Startup Probe non ha esito positivo, tutte le altre Probe sono disabilitate. Puoi definire il tempo massimo di attesa 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à interrotto e verrà creato un nuovo Pod.

Lo Startup Probe è simile al Liveness Probe: se falliscono, il Pod viene ricreato. Come spiega Ricardo A. nel suo post [Fantastic Probes And How To Configure Them, le](https://medium.com/swlh/fantastic-probes-and-how-to-configure-them-fef7e030bd2f) Startup Probes devono essere utilizzate quando il tempo di avvio di un'applicazione è imprevedibile. Se sapete che l'applicazione impiega dieci secondi per avviarsi, dovreste usare invece Liveness/Readiness Probe con. `initialDelaySeconds`

### Utilizzate Readiness Probe per rilevare l'indisponibilità parziale
<a name="_use_readiness_probe_to_detect_partial_unavailability"></a>

*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 correttamente una volta completata l'operazione.

Ad esempio, durante I/O operazioni intensive su disco, le applicazioni potrebbero essere temporaneamente non disponibili per gestire le richieste. In questo caso, la chiusura del Pod dell'applicazione non è un rimedio; allo stesso tempo, le richieste aggiuntive inviate al Pod possono avere esito negativo.

Puoi utilizzare Readiness Probe per rilevare un'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 guasto comporterebbe la ricreazione del Pod, un Readiness Probe fallito 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 con Liveness Probe, evita di configurare le Readiness Probe che dipendono da una risorsa esterna al Pod (come un database). Ecco uno scenario in cui un Readiness mal configurato può rendere l'applicazione non funzionante: se il Readiness Probe di un Pod si guasta quando il database dell'app non è raggiungibile, anche le 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 si guasteranno e Kubernetes smetterà di inviare traffico a tutti i Pod.*

Un effetto collaterale dell'utilizzo di Readiness Probes è che possono aumentare il tempo necessario per aggiornare le distribuzioni. 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.



## Gestione delle interruzioni
<a name="_dealing_with_disruptions"></a>

I Pod hanno una durata limitata: anche se hai Pod a lunga durata, è prudente assicurarsi che i Pod si spengano 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 che tutti i Pod vengano ricreati su nodi più recenti. Una corretta gestione delle terminazioni e i Pod Disruption Budgets possono aiutarti a evitare interruzioni del servizio, poiché i Pod vengono rimossi dai nodi più vecchi e ricreati sui nodi più recenti.

Il modo preferito 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 relativi pod vengono rimossi in modo sicuro.* Sicurezza è una parola chiave in questo contesto; quando i pod di un lavoratore vengono sfrattati, a quest'ultimo non viene semplicemente inviato un segnale. `SIGKILL` Viene invece inviato un `SIGTERM` segnale al processo principale (PID 1) di ogni container dei Pod che viene sfrattato. Dopo l'invio `SIGTERM` del segnale, Kubernetes concederà al processo del tempo (periodo di grazia) prima dell'invio del segnale. `SIGKILL` Questo periodo di grazia è di 30 secondi per impostazione predefinita; puoi sovrascrivere il valore predefinito usando `grace-period` flag in kubectl o dichiararlo nel tuo Podspec. `terminationGracePeriodSeconds`

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

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

```
$ 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 riceve`SIGTERM`, il processo principale, che in questo esempio è un'applicazione Python, non riceve un `SIGTERM` segnale. Quando il Pod viene terminato, l'applicazione Python verrà interrotta bruscamente. Questo può essere risolto modificando il [https://docs.docker.com/engine/reference/builder/#entrypoint](https://docs.docker.com/engine/reference/builder/#entrypoint)contenitore per avviare l'applicazione Python. In alternativa, puoi usare uno strumento come [dumb-init per assicurarti che la tua applicazione sia in](https://github.com/Yelp/dumb-init) grado di gestire i segnali.

Puoi anche usare [Container hooks](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks) 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 a partire dal momento in cui l'azione `PreStop` hook inizia l'esecuzione, non da quando il `SIGTERM` segnale viene inviato.

## Raccomandazioni
<a name="_recommendations_3"></a>

### Proteggi i carichi di lavoro critici con Pod Disruption Budgets
<a name="_protect_critical_workload_with_pod_disruption_budgets"></a>

Pod Disruption Budget o PDB possono interrompere temporaneamente il processo di sfratto se il numero di repliche di un'applicazione scende al di sotto della soglia dichiarata. Il processo di eliminazione 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 di cui sopra indica a Kubernetes di interrompere il processo di sfratto fino a quando non saranno disponibili tre o più repliche. Il `PodDisruptionBudgets` drenaggio dei nodi rispetti. Durante l'aggiornamento di un gruppo di nodi gestito da EKS, [i nodi vengono svuotati con un](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-update-behavior.html) 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.

[https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html) Utilizza l'API Kubernetes per collegare 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 Deploy's Pod su nodi diversi ed evitare ritardi dovuti al PDB durante gli aggiornamenti dei nodi.

### Pratica l'ingegneria del caos
<a name="_practice_chaos_engineering"></a>

L'ingegneria del caos è la disciplina che consiste nella sperimentazione su un sistema distribuito per aumentare la fiducia nella capacità del sistema di resistere a condizioni di produzione turbolente.

Nel suo blog, Dominik Tornow spiega che [Kubernetes è un sistema dichiarativo in cui "l'utente fornisce al sistema](https://medium.com/@dominik.tornow/the-mechanics-of-kubernetes-ac8112eaa302) *una rappresentazione dello stato desiderato del sistema. Il sistema considera quindi lo stato corrente e lo stato desiderato per determinare la sequenza di comandi per la transizione 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, se un si `replica` blocca, Deployment Contoller ne creerà uno nuovo.](https://kubernetes.io/docs/concepts/architecture/controller/#design) `replica` In questo modo, i controller Kubernetes correggono automaticamente gli errori.

Strumenti di ingegneria del caos come [Gremlin](https://www.gremlin.com) ti aiutano a testare la resilienza del tuo cluster Kubernetes e a identificare singoli punti di errore. Gli strumenti che introducono il caos artificiale nel cluster (e oltre) possono scoprire punti deboli sistemici, offrire l'opportunità di identificare colli di bottiglia e configurazioni errate e correggere i problemi in un ambiente controllato. La filosofia Chaos Engineering sostiene la necessità di rompere le cose di proposito e l'infrastruttura di stress test per ridurre al minimo i tempi di inattività imprevisti.

### Usa una Service Mesh
<a name="_use_a_service_mesh"></a>

È possibile utilizzare una service mesh per migliorare la resilienza dell'applicazione. Le service mesh consentono service-to-service la comunicazione e aumentano l'osservabilità della rete di microservizi. La maggior parte dei prodotti service mesh funziona facendo funzionare 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 modificare l'applicazione. 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 nuovi tentativi di richiesta automatici, timeout, interruzione del circuito e limitazione della velocità.

Se gestisci più cluster, puoi utilizzare una service mesh per abilitare la comunicazione tra cluster. service-to-service

### Service Mesh
<a name="_service_meshes"></a>
+  [Istio](https://istio.io) 
+  [Linker D](http://linkerd.io) 
+  [Console](https://www.consul.io) 



## Osservabilità
<a name="_observability"></a>

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 monitorare 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 del cluster prima che possano causare 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 memorizza. Puoi visualizzare i log di un Pod usando kubectl, ma Kubernetes non conserva automaticamente i log. E l'implementazione della traccia distribuita viene eseguita a livello di codice dell'applicazione o utilizzando mesh di servizi.

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

## Raccomandazioni
<a name="_recommendations_4"></a>

### Monitora le tue applicazioni
<a name="_monitor_your_applications"></a>

Il numero di metriche da monitorare nelle applicazioni moderne è in continua crescita. È utile disporre di un modo automatizzato per tracciare le applicazioni in modo da potersi concentrare sulla risoluzione delle sfide dei clienti. Strumenti di monitoraggio a livello di cluster come [Prometheus](https://prometheus.io) o [CloudWatchContainer Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html) 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 in caso di eventi che, se aggravati, possono portare a un'interruzione o influire sulle prestazioni delle applicazioni.

Se non ti è chiaro quali metriche monitorare, puoi prendere ispirazione da questi metodi:
+  [Metodo RED.](https://www.weave.works/blog/a-practical-guide-from-instrumenting-code-to-specifying-alerts-with-the-red-method) È l'acronimo di richieste, errori e durata.
+  [Metodo USE](http://www.brendangregg.com/usemethod.html). Sta per utilizzo, saturazione ed errori.

Il post di Sysdig [sulle migliori pratiche per gli avvisi su Kubernetes](https://sysdig.com/blog/alerting-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
<a name="_use_prometheus_client_library_to_expose_application_metrics"></a>

Oltre a monitorare lo stato dell'applicazione e aggregare le metriche standard, puoi anche utilizzare la [libreria client Prometheus per esporre metriche personalizzate specifiche dell'](https://prometheus.io/docs/instrumenting/clientlibs/)applicazione per migliorare l'osservabilità dell'applicazione.

### Utilizza strumenti di registrazione centralizzati per raccogliere e conservare i log
<a name="_use_centralized_logging_tools_to_collect_and_persist_logs"></a>

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 i registri di controllo e diagnostica direttamente dal piano di controllo ai CloudWatch registri dell'account. I log delle applicazioni sono registri prodotti dai Pod in esecuzione all'interno del cluster. I log delle applicazioni includono i log prodotti dai Pod 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](https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html) del piano di controllo:

1. Registri dei componenti del server API Kubernetes

1. Audit

1. Autenticatore

1. Responsabile del controller

1. Pianificatore

I registri del controller manager e dello scheduler possono aiutare a diagnosticare 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 che desideri 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](https://www.fluentd.org)](http://fluentbit.io) o Container Insights nel cluster. CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html)

Gli strumenti di aggregazione dei log di Kubernetes funzionano 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'archiviazione. CloudWatch Fluent Bit e Fluentd supportano molti dei più diffusi sistemi di analisi dei log come Elasticsearch e InfluxDB, offrendoti la possibilità di cambiare il backend di archiviazione per i log modificando Fluent bit o la configurazione dei log di Fluentd.

### Utilizzate un sistema di tracciamento distribuito per identificare i colli di bottiglia
<a name="_use_a_distributed_tracing_system_to_identify_bottlenecks"></a>

Una tipica applicazione moderna ha componenti distribuiti sulla 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 comprendere come fluiscono le richieste e come comunicano i sistemi. Traces può mostrarvi i punti critici nella rete delle applicazioni e prevenire problemi che possono causare errori a cascata.

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. Con questo metodo, è necessario apportare modifiche al codice. Ciò è ulteriormente complicato se si utilizzano applicazioni poliglotte. Sei anche responsabile della manutenzione di un'altra libreria, per tutti i tuoi servizi.

Le service mesh come [LinkerD](http://linkerd.io) e [Istio](http://istio.io) 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](https://aws.amazon.com/xray/) X-Ray e Jaeger supportano sia le librerie condivise che le implementazioni di service mesh.](https://www.jaegertracing.io)

Prendi in considerazione l'utilizzo di uno strumento di tracciamento come [AWS](https://aws.amazon.com/xray/) X-Ray [o](https://www.jaegertracing.io) Jaeger che supporti entrambe le implementazioni (libreria condivisa e service mesh) in modo da non dover cambiare strumento se successivamente adotterai la service mesh.

# Piano di controllo EKS
<a name="control-plane"></a>

**Suggerimento**  
 [Esplora le](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el) best practice tramite i workshop Amazon EKS.

Amazon Elastic Kubernetes Service (EKS) è un servizio Kubernetes gestito che semplifica l'esecuzione di Kubernetes su AWS senza dover installare, utilizzare e mantenere il proprio piano di controllo Kubernetes o nodi di lavoro. Funziona a upstream di Kubernetes ed è certificato conforme a Kubernetes. Questa conformità garantisce che EKS supporti le API Kubernetes, proprio come la versione della community open source che puoi installare su EC2 o in locale. Le applicazioni esistenti in esecuzione su Kubernetes upstream sono compatibili con Amazon EKS.

EKS gestisce automaticamente la disponibilità e la scalabilità dei nodi del piano di controllo Kubernetes e sostituisce automaticamente i nodi del piano di controllo non integri.

## Architettura EKS
<a name="reliability_cpeks_architecture"></a>

L'architettura EKS è progettata per eliminare ogni singolo punto di errore che possa compromettere la disponibilità e la durabilità del piano di controllo Kubernetes.

Il piano di controllo Kubernetes gestito da EKS funziona all'interno di un VPC gestito da EKS. Il piano di controllo EKS comprende i nodi del server dell'API Kubernetes, il cluster ecc. Nodi server API Kubernetes che eseguono componenti come il server API, lo scheduler e vengono eseguiti `kube-controller-manager` in un gruppo di auto-scaling. EKS esegue un minimo di due nodi server API in zone di disponibilità distinte (AZs) all'interno della regione AWS. Allo stesso modo, per motivi di durabilità, i nodi del server etcd funzionano anche in un gruppo di auto-scaling che si estende su tre. AZs EKS esegue un gateway NAT in ogni AZ, mentre i server API e i server etcd vengono eseguiti in una sottorete privata. Questa architettura garantisce che un evento in una singola AZ non influisca sulla disponibilità del cluster EKS.

Quando crei un nuovo cluster, Amazon EKS crea un endpoint ad alta disponibilità per il server API Kubernetes gestito che usi per comunicare con il cluster (utilizzando strumenti come). `kubectl` L'endpoint gestito utilizza NLB per bilanciare il carico dei server API Kubernetes. EKS fornisce anche due [ENI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) diversi AZs per facilitare la comunicazione con i nodi di lavoro.

Connettività di rete EKS Data Plane

![\[Connettività\]](http://docs.aws.amazon.com/it_it/eks/latest/best-practices/images/reliability/eks-data-plane-connectivity.jpeg)


Puoi [configurare se il server API del tuo cluster Kubernetes](https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html) è raggiungibile dalla rete Internet pubblica (utilizzando l'endpoint pubblico) o tramite il tuo VPC (utilizzando EKS-Managed) o entrambi. ENIs

Indipendentemente dal fatto che utenti e nodi di lavoro si connettano al server API utilizzando l'endpoint pubblico o l'ENI gestito da EKS, esistono percorsi di connessione ridondanti.

## Raccomandazioni
<a name="cp-recs"></a>

Esamina i seguenti consigli.

## Monitora le metriche del piano di controllo
<a name="reliability_cpmonitor_control_plane_metrics"></a>

Il monitoraggio delle metriche dell'API Kubernetes può fornirti informazioni dettagliate sulle prestazioni del piano di controllo e identificare i problemi. Un piano di controllo non integro può compromettere la disponibilità dei carichi di lavoro in esecuzione all'interno del cluster. Ad esempio, controller scritti in modo errato possono sovraccaricare i server API, influendo sulla disponibilità dell'applicazione.

Kubernetes espone le metriche del piano di controllo sull'endpoint. `/metrics`

Puoi visualizzare le metriche esposte utilizzando: `kubectl`

```
kubectl get --raw /metrics
```

Queste metriche sono rappresentate in un formato di testo [Prometheus.](https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md)

Puoi usare Prometheus per raccogliere e archiviare queste metriche. A maggio 2020, è CloudWatch stato aggiunto il supporto per il monitoraggio delle metriche di Prometheus in Container Insights. CloudWatch Quindi puoi usare Amazon anche CloudWatch per monitorare il piano di controllo EKS. Puoi utilizzare [Tutorial for Adding a New Prometheus Scrape Target: Prometheus KPI](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights-Prometheus-Setup-configure.html#ContainerInsights-Prometheus-Setup-new-exporters) Server Metrics per raccogliere metriche e creare dashboard per monitorare il piano di controllo del cluster. CloudWatch 

[Puoi trovare le metriche del server dell'API Kubernetes qui.](https://github.com/kubernetes/apiserver/blob/master/pkg/endpoints/metrics/metrics.go) Ad esempio, `apiserver_request_duration_seconds` può indicare quanto tempo impiegano le richieste API per l'esecuzione.

Prendi in considerazione il monitoraggio di queste metriche del piano di controllo:

### Server API
<a name="reliability_cpapi_server"></a>


| Metrica | Description | 
| --- | --- | 
|   `apiserver_request_total`   |  Contatore di richieste apiserver suddiviso per ogni verbo, valore di dry run, gruppo, versione, risorsa, ambito, componente e codice di risposta HTTP.  | 
|   `apiserver_request_duration_seconds*`   |  Istogramma della latenza di risposta in secondi per ogni verbo, valore dry run, gruppo, versione, risorsa, sottorisorsa, ambito e componente.  | 
|   `apiserver_admission_controller_admission_duration_seconds*`   |  Istogramma di latenza del controller di ammissione in secondi, identificato per nome e suddiviso per ogni operazione e risorsa e tipo di API (convalida o ammissione).  | 
|   `apiserver_admission_webhook_rejection_count`   |  Numero di accessi respinti dal webhook. Identificato per nome, operazione, rejection\$1code, tipo (validazione o ammissione), error\$1type (calling\$1webhook\$1error, apiserver\$1internal\$1error, no\$1error)  | 
|   `rest_client_request_duration_seconds*`   |  Richiedi l'istogramma di latenza in secondi. Suddiviso per verbo e URL.  | 
|   `rest_client_requests_total`   |  Numero di richieste HTTP, partizionate per codice di stato, metodo e host.  | 
+ Le metriche dell'istogramma includono i suffissi \$1bucket, \$1sum e \$1count.

### ecc.
<a name="reliability_cpetcd"></a>


| Metrica | Description | 
| --- | --- | 
|   `etcd_request_duration_seconds*`   |  Istogramma di latenza della richiesta Etcd in secondi per ogni operazione e tipo di oggetto.  | 
|   `apiserver_storage_db_total_size_in_bytes`o `apiserver_storage_size_bytes` (a partire da EKS v1.28)  |  Dimensione del database Etcd.  | 
+ Le metriche dell'istogramma includono i suffissi \$1bucket, \$1sum e \$1count.

Prendi in considerazione l'utilizzo della [Kubernetes Monitoring Overview Dashboard per visualizzare e monitorare le richieste del server API Kubernetes](https://grafana.com/grafana/dashboards/14623) e le metriche di latenza e latenza ecc.

**Importante**  
Quando viene superato il limite di dimensione del database, etcd emette un allarme di assenza di spazio e smette di accettare ulteriori richieste di scrittura. In altre parole, il cluster diventa di sola lettura e tutte le richieste di modifica degli oggetti, come la creazione di nuovi pod, la scalabilità delle distribuzioni, ecc., verranno rifiutate dal server API del cluster.

## Autenticazione del cluster
<a name="reliability_cpcluster_authentication"></a>

EKS attualmente supporta due tipi di autenticazione: i token dell'[account del portatore/servizio e l'autenticazione IAM che utilizza l'autenticazione tramite token](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens) [webhook](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication). Quando gli utenti chiamano l'API Kubernetes, un webhook trasmette un token di autenticazione incluso nella richiesta a IAM. Il token, un URL con firma di base 64, viene generato dall'interfaccia a riga di comando AWS ([AWS CLI](https://aws.amazon.com/cli/)).

L'utente o il ruolo IAM che crea il cluster EKS ottiene automaticamente l'accesso completo al cluster. Puoi gestire l'accesso al cluster EKS modificando la configmap di [aws-auth](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html).

Se configuri male la `aws-auth` configmap e perdi l'accesso al cluster, puoi comunque utilizzare l'utente o il ruolo del creatore del cluster per accedere al tuo cluster EKS.

Nell'improbabile eventualità che non sia possibile utilizzare il servizio IAM nella regione AWS, è possibile utilizzare anche il token bearer dell'account del servizio Kubernetes per gestire il cluster.

Crea un `super-admin` account autorizzato a eseguire tutte le azioni nel cluster:

```
kubectl -n kube-system create serviceaccount super-admin
```

Crea un'associazione di ruoli che assegna il ruolo super-admin cluster-admin:

```
kubectl create clusterrolebinding super-admin-rb --clusterrole=cluster-admin --serviceaccount=kube-system:super-admin
```

Ottieni il segreto dell'account di servizio:

```
SECRET_NAME=`kubectl -n kube-system get serviceaccount/super-admin -o jsonpath='{.secrets[0].name}'`
```

Ottieni il token associato al segreto:

```
TOKEN=`kubectl -n kube-system get secret $SECRET_NAME -o jsonpath='{.data.token}'| base64 --decode`
```

Aggiungi account e token di servizio a`kubeconfig`:

```
kubectl config set-credentials super-admin --token=$TOKEN
```

Imposta il contesto corrente `kubeconfig` per utilizzare l'account super-admin:

```
kubectl config set-context --current --user=super-admin
```

La finale dovrebbe `kubeconfig` assomigliare a questa:

```
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data:<REDACTED>
    server: https://<CLUSTER>.gr7.us-west-2.eks.amazonaws.com
  name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name>
contexts:
- context:
    cluster: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name>
    user: super-admin
  name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name>
current-context: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name>
kind: Config
preferences: {}
users:
#- name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name>
#  user:
#    exec:
#      apiVersion: client.authentication.k8s.io/v1beta1
#      args:
#      - --region
#      - us-west-2
#      - eks
#      - get-token
#      - --cluster-name
#      - <<cluster name>>
#      command: aws
#      env: null
- name: super-admin
  user:
    token: <<super-admin sa's secret>>
```

## Webhook di ammissione
<a name="reliability_cpadmission_webhooks"></a>

Kubernetes offre due tipi di webhook di ammissione: webhook di ammissione [convalidanti](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers) e webhook di ammissione mutanti. Questi consentono a un utente di estendere l'API Kubernetes e convalidare o modificare gli oggetti prima che vengano accettati dall'API. Una configurazione inadeguata di questi webhook può destabilizzare il piano di controllo EKS bloccando le operazioni critiche del cluster.

Per evitare di influire sulle operazioni critiche del cluster, evita di impostare webhook «catch-all» come i seguenti:

```
- name: "pod-policy.example.com"
  rules:
  - apiGroups:   ["*"]
    apiVersions: ["*"]
    operations:  ["*"]
    resources:   ["*"]
    scope: "*"
```

In alternativa, assicurati che il webhook abbia una policy di fail-open con un timeout inferiore a 30 secondi per assicurarti che, se il webhook non è disponibile, non comprometta i carichi di lavoro critici del cluster.

### Blocca i pod con unsafe `sysctls`
<a name="reliability_cpblock_pods_with_unsafe_sysctls"></a>

 `Sysctl`è un'utilità Linux che consente agli utenti di modificare i parametri del kernel durante l'esecuzione. Questi parametri del kernel controllano vari aspetti del comportamento del sistema operativo, come la rete, il file system, la memoria virtuale e la gestione dei processi.

Kubernetes consente di `sysctl` assegnare profili per i Pod. Kubernetes si classifica come sicuro e non sicuro. `systcls` `sysctls`I namespace sono sicuri nel contenitore o nel Pod e la loro impostazione non influisce sugli altri Pod sul nodo o sul nodo stesso. Al contrario, i sysctls non sicuri sono disabilitati per impostazione predefinita poiché possono potenzialmente interrompere altri Pod o rendere instabile il nodo.

Poiché gli unsafe `sysctls` sono disabilitati per impostazione predefinita, il kubelet non creerà un Pod con un profilo non sicuro. `sysctl` Se crei un Pod di questo tipo, lo scheduler assegnerà ripetutamente tali Pod ai nodi, mentre il nodo non riesce ad avviarlo. Questo ciclo infinito alla fine mette a dura prova il piano di controllo del cluster, rendendolo instabile.

Prendi in considerazione l'utilizzo di [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper-library/blob/377cb915dba2db10702c25ef1ee374b4aa8d347a/src/pod-security-policy/forbidden-sysctls/constraint.tmpl) o [Kyverno](https://kyverno.io/policies/pod-security/baseline/restrict-sysctls/restrict-sysctls/) per rifiutare i Pods con unsafe. `sysctls`

## Gestione degli aggiornamenti del cluster
<a name="reliability_cphandling_cluster_upgrades"></a>

Da aprile 2021, il ciclo di rilascio di Kubernetes è stato modificato da quattro versioni all'anno (una volta al trimestre) a tre versioni all'anno. Una nuova versione secondaria (come 1. **21** o 1. **22**) viene rilasciato all'incirca [ogni quindici settimane.](https://kubernetes.io/blog/2021/07/20/new-kubernetes-release-cadence/#what-s-changing-and-when) A partire da Kubernetes 1.19, ogni versione secondaria è supportata per circa dodici mesi dopo il primo rilascio. Con l'avvento di Kubernetes v1.28, il divario di compatibilità tra il piano di controllo e i nodi di lavoro si è esteso dalle versioni minori n-2 a n-3. [Per saperne di più, consulta Best Practices for Cluster Upgrades.](cluster-upgrades.md)

## Connettività degli endpoint del cluster
<a name="reliability_cpcluster_endpoint_connectivity"></a>

Quando lavori con Amazon EKS (Elastic Kubernetes Service), potresti riscontrare timeout o errori di connessione durante eventi come il ridimensionamento o l'applicazione di patch del piano di controllo di Kubernetes. Questi eventi possono causare la sostituzione delle istanze kube-apiserver, con la potenziale conseguenza della restituzione di indirizzi IP diversi durante la risoluzione del nome di dominio completo. Questo documento descrive le migliori pratiche per gli utenti dell'API Kubernetes per mantenere una connettività affidabile.

**Nota**  
L'implementazione di queste best practice può richiedere aggiornamenti alle configurazioni o agli script dei client per gestire efficacemente le nuove strategie di risoluzione e riprovare il DNS.

*Il problema principale deriva dalla memorizzazione nella cache DNS lato client e dalla potenziale presenza di indirizzi IP obsoleti degli endpoint EKS: NLB pubblico per endpoint pubblici o X-ENI per endpoint privati.* Quando le istanze kube-apiserver vengono sostituite, il Fully Qualified Domain Name (FQDN) può trasformarsi in nuovi indirizzi IP. Tuttavia, a causa delle impostazioni DNS Time to Live (TTL), che sono impostate su 60 secondi nella zona Route 53 gestita da AWS, i client possono continuare a utilizzare indirizzi IP obsoleti per un breve periodo di tempo.

Per mitigare questi problemi, gli utenti delle API Kubernetes (come kubectl, CI/CD pipeline e applicazioni personalizzate) devono implementare le seguenti best practice:
+ Implementare la risoluzione DNS
+ Implementa nuovi tentativi con Backoff e Jitter. Ad esempio, consulta [questo articolo](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) intitolato Failures Happen 
+ Implementa i timeout dei client. Imposta i timeout appropriati per evitare che le richieste di lunga durata blocchino l'applicazione. Tieni presente che alcune librerie client Kubernetes, in particolare quelle generate dai generatori OpenAPI, potrebbero non consentire di impostare facilmente timeout personalizzati.
  + Esempio 1 con kubectl:

  ```
    kubectl get pods --request-timeout 10s # default: no timeout
  ```
  + Esempio 2 con Python: il client [Kubernetes](https://github.com/kubernetes-client/python/blob/release-30.0/kubernetes/client/api_client.py#L120) fornisce un parametro \$1request\$1timeout 

Implementando queste best practice, puoi migliorare in modo significativo l'affidabilità e la resilienza delle tue applicazioni quando interagisci con l'API Kubernetes. Ricorda di testare accuratamente queste implementazioni, specialmente in condizioni di errore simulate, per assicurarti che si comportino come previsto durante gli eventi di scalabilità o applicazione delle patch effettivi.

## Esecuzione di cluster di grandi dimensioni
<a name="reliability_cprunning_large_clusters"></a>

EKS monitora attivamente il carico sulle istanze del piano di controllo e le ridimensiona automaticamente per garantire prestazioni elevate. Tuttavia, è necessario tenere conto dei potenziali problemi e limiti di prestazioni all'interno di Kubernetes e delle quote nei servizi AWS quando si eseguono cluster di grandi dimensioni.
+ [Secondo i test eseguiti dal team, i cluster con più di 1000 servizi potrebbero presentare una latenza di rete utilizzando `iptables` la modalità `kube-proxy` in. ProjectCalico ](https://www.projectcalico.org/comparing-kube-proxy-modes-iptables-or-ipvs/) La soluzione è passare alla modalità di [esecuzione `kube-proxy`](ipvs.md). `ipvs`
+ Potresti anche riscontrare una [limitazione delle richieste dell'API EC2](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/throttling.html) se il CNI deve richiedere gli indirizzi IP per i Pod o se devi creare nuove istanze EC2 frequentemente. Puoi ridurre le chiamate all'API EC2 configurando il CNI per memorizzare nella cache gli indirizzi IP. Puoi utilizzare tipi di istanze EC2 più grandi per ridurre gli eventi di scalabilità EC2.

## Risorse aggiuntive:
<a name="reliability_cpadditional_resources"></a>
+  [Demistificazione delle reti di cluster per i nodi di lavoro Amazon EKS](https://aws.amazon.com/blogs/containers/de-mystifying-cluster-networking-for-amazon-eks-worker-nodes/) 
+  [Controllo dell'accesso agli endpoint del cluster Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html) 
+  [AWS re:Invent 2019: Amazon EKS sotto il cofano (-R1) CON421](https://www.youtube.com/watch?v=7vxDWDD2YnM) 

# Piano dati EKS
<a name="data-plane"></a>

Per utilizzare applicazioni ad alta disponibilità e resilienza, è necessario un piano dati ad alta disponibilità e resilienza. Un piano dati elastico garantisce che Kubernetes possa scalare e correggere automaticamente le tue applicazioni. Un piano dati resiliente è costituito da due o più nodi di lavoro, può crescere e ridursi con il carico di lavoro e ripristinarsi automaticamente in caso di guasti.

[Hai diverse scelte per i nodi di lavoro con EKS: [nodi gestiti in modalità automatica EKS](https://docs.aws.amazon.com/eks/latest/userguide/automode.html), [istanze EC2 e Fargate](https://docs.aws.amazon.com/eks/latest/userguide/worker.html).](https://docs.aws.amazon.com/eks/latest/userguide/fargate.html)

EKS Auto Mode offre il percorso più semplice verso un piano dati resiliente. Auto Mode estende la gestione AWS dei cluster Kubernetes oltre il cluster stesso, per consentire ad AWS di configurare e gestire anche l'infrastruttura che consente il funzionamento regolare dei carichi di lavoro. La modalità automatica ridimensiona automaticamente il piano dati verso l'alto o verso il basso man mano che Kubernetes ridimensiona i pod e lavora per garantire continuamente che i nodi del cluster siano dimensionati in modo appropriato ed economico per i carichi di lavoro attualmente in esecuzione.

[Se scegli le istanze EC2, puoi gestire tu stesso i nodi di lavoro o utilizzare i gruppi di nodi gestiti da EKS.](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) Puoi avere un cluster con una combinazione di modalità automatica, nodi di lavoro gestiti e autogestiti e Fargate.

Fargate esegue ogni Pod in un ambiente di elaborazione isolato. Ogni Pod in esecuzione su Fargate ha il proprio nodo di lavoro. Fargate ridimensiona automaticamente il piano dati come Kubernetes ridimensiona i pod. [È possibile scalare sia il piano dati che il carico di lavoro utilizzando l'autoscaler a pod orizzontale.](https://docs.aws.amazon.com/eks/latest/userguide/horizontal-pod-autoscaler.html)

[Il modo preferito per scalare i nodi di lavoro EC2 (se non si utilizza la modalità automatica EKS, che viene eseguita automaticamente da AWS) è utilizzare i gruppi [Karpenter](https://karpenter.sh/), [Kubernetes Cluster Autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md) o EC2 Auto Scaling.](https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroup.html)

## Raccomandazioni
<a name="_recommendations"></a>

### Distribuisci i nodi di lavoro e i carichi di lavoro su più AZs
<a name="_spread_worker_nodes_and_workloads_across_multiple_azs"></a>

Puoi proteggere i tuoi carichi di lavoro dai guasti in una singola AZ eseguendo nodi di lavoro e Pods in più aree. AZs È possibile controllare l'AZ in cui vengono creati i nodi di lavoro utilizzando le sottoreti in cui vengono creati i nodi.

Il metodo consigliato per distribuire i pod AZs consiste nell'utilizzare [Topology Spread](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#spread-constraints-for-pods) Constraints for Pods. Le funzionalità di scalabilità automatica come EKS Auto Mode e Karpenter sono consapevoli dei vincoli di diffusione della topologia e avvieranno automaticamente i nodi nella posizione corretta per consentire il rispetto dei vincoli imposti. AZs 

La distribuzione riportata di seguito distribuisce i pod, se possibile, lasciando che funzionino comunque in caso contrario AZs :

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-server
  template:
    metadata:
      labels:
        app: web-server
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          whenUnsatisfiable: ScheduleAnyway
          topologyKey: topology.kubernetes.io/zone
          labelSelector:
            matchLabels:
              app: web-server
      containers:
      - name: web-app
        image: nginx
        resources:
          requests:
            cpu: 1
```

**Nota**  
 `kube-scheduler`è a conoscenza dei domini di topologia solo tramite nodi che esistono con tali etichette. Se la distribuzione di cui sopra viene distribuita in un cluster con nodi in una sola zona, tutti i pod verranno programmati su quei nodi poiché `kube-scheduler` non sono a conoscenza delle altre zone. Affinché questa distribuzione della topologia funzioni come previsto con lo scheduler, i nodi devono già esistere in tutte le zone. La `minDomains` proprietà dei vincoli di diffusione della topologia viene utilizzata per comunicare allo scheduler il numero di domini idonei, anche se è in esecuzione un nodo per evitare questo problema.

**avvertimento**  
L'impostazione `whenUnsatisfiable` su `DoNotSchedule` farà sì che i pod non siano programmabili se il vincolo di diffusione della topologia non può essere soddisfatto. Dovrebbe essere impostato solo se è preferibile che i pod non vengano eseguiti invece di violare il vincolo di diffusione della topologia.

Nelle versioni precedenti di Kubernetes, puoi utilizzare le regole di antiaffinità dei pod per pianificare i pod su più pod. AZs *Il manifesto riportato di seguito indica allo scheduler di Kubernetes di preferire la pianificazione dei pod in modo distinto.* AZs

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
  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: failure-domain.beta.kubernetes.io/zone
            weight: 100
      containers:
      - name: web-app
        image: nginx
```

**avvertimento**  
Non è necessario che i pod siano pianificati in AZs modo distinto, altrimenti il numero di pod in una distribuzione non supererà mai il numero di. AZs

### Garantisci la possibilità di avviare nodi in ogni AZ quando usi i volumi EBS
<a name="_ensure_ability_to_launch_nodes_in_each_az_when_using_ebs_volumes"></a>

Se utilizzi Amazon EBS per fornire volumi persistenti, devi assicurarti che i pod e il volume EBS associato si trovino nella stessa zona di disponibilità. Un pod non può accedere ai volumi persistenti supportati da EBS che si trovano in una AZ diversa. Lo [scheduler Kubernetes sa in quale AZ si trova un nodo](https://kubernetes.io/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone) di lavoro dalle etichette che si trovano sul nodo e pianificherà sempre un Pod che richiede un volume EBS nella stessa AZ del volume. Tuttavia, se non ci sono nodi di lavoro disponibili nell'AZ in cui si trova il volume, il Pod non può essere pianificato.

Se utilizzi EKS Auto Mode o Karpenter, dovrai assicurarti di NodeClass selezionare le sottoreti in ogni AZ. Se si utilizzano i gruppi di nodi gestiti, è necessario assicurarsi di disporre di un gruppo di nodi in ogni AZ.

Una funzionalità di storage EBS è integrata in EKS Auto Mode, ma se si utilizza Karpenter o Managed Node Groups, sarà necessario installare anche [EBS CSI](https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html).

### Usa EKS Auto Mode per gestire i nodi di lavoro
<a name="_use_eks_auto_mode_to_manage_worker_nodes"></a>

EKS Auto Mode semplifica la gestione EKS fornendo cluster pronti per la produzione con un sovraccarico operativo minimo. La modalità automatica è responsabile dell'aumento o della riduzione del numero di nodi a seconda dei pod in esecuzione nel cluster. I nodi vengono aggiornati automaticamente con patch e correzioni software, e gli aggiornamenti vengono eseguiti in base alle impostazioni di [NodePool](https://docs.aws.amazon.com/eks/latest/userguide/create-node-pool.html#_disruption)interruzione configurate e ai Pod Disruption Budgets.

### Esegui il Node Monitoring Agent
<a name="_run_the_node_monitoring_agent"></a>

Il [Node Monitoring Agent](https://docs.aws.amazon.com/eks/latest/userguide/node-health.html) monitora e reagisce ai problemi di integrità dei nodi pubblicando gli eventi Kubernetes e aggiornando le condizioni di stato sui nodi. Il Node Monitoring Agent è incluso nei nodi EKS Auto Mode e può essere installato come componente aggiuntivo EKS per i nodi che non sono gestiti da Auto Mode.

EKS Auto Mode, Managed Node Groups e Karpenter hanno tutti la capacità di rilevare le condizioni fatali dei nodi segnalate dall'agente di monitoraggio dei nodi e di ripararli automaticamente quando si verificano tali condizioni.

### Implementazione del QoS
<a name="_implement_qos"></a>

Per le applicazioni critiche, prendi in considerazione la definizione di `requests` = `limits` per il contenitore nel Pod. Ciò garantirà che il contenitore non venga ucciso se un altro Pod richiede risorse.

È consigliabile implementare limiti di CPU e memoria per tutti i contenitori in quanto impedisce che un contenitore consumi inavvertitamente risorse di sistema influendo sulla disponibilità di altri processi co-localizzati.

### Configura e dimensiona le risorse per tutti i carichi di lavoro Requests/Limits
<a name="_configure_and_size_resource_requestslimits_for_all_workloads"></a>

Alcune indicazioni generali possono essere applicate al dimensionamento delle richieste di risorse e ai limiti per i carichi di lavoro:
+ Non specificare limiti di risorse sulla CPU. In assenza di limiti, la richiesta influisce sulla [quantità di tempo relativo alla CPU utilizzata dai container](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#how-pods-with-resource-limits-are-run). Ciò consente ai carichi di lavoro di utilizzare l'intera CPU senza limiti artificiali o carenze.
+ Per le risorse diverse dalla CPU, configuring `requests` = `limits` fornisce il comportamento più prevedibile. Se\$1 `requests` [=`limits`, inoltre, il [QOS](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#qos-classes) del container è stato ridotto da Guaranteed a Burstable, il che rende più probabile lo sfratto in caso di pressione dei nodi.](https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/)
+ Per le risorse diverse dalla CPU, non specificare un limite molto più grande della richiesta. Quanto più grandi `limits` sono le dimensioni configurate rispetto a`requests`, tanto più è probabile che i nodi vengano sovraccaricati, con conseguenti alte probabilità di interruzione del carico di lavoro.
+ [Le richieste di dimensioni corrette sono particolarmente importanti quando si utilizza una soluzione di auto-scaling dei nodi [come](https://aws.github.io/aws-eks-best-practices/karpenter/) Karpenter o Cluster. AutoScaler](https://aws.github.io/aws-eks-best-practices/cluster-autoscaling/) Questi strumenti esaminano le richieste di carico di lavoro per determinare il numero e la dimensione dei nodi da fornire. Se le tue richieste sono troppo piccole e con limiti più elevati, potresti scoprire che i carichi di lavoro vengono eliminati o l'OOM bloccato se sono stati raggruppati in un nodo ristretto.

Determinare le richieste di risorse può essere difficile, ma strumenti come [Vertical Pod Autoscaler](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler) possono aiutarvi a «dimensionare correttamente» le richieste osservando l'utilizzo delle risorse del contenitore in fase di esecuzione. Altri strumenti che possono essere utili per determinare le dimensioni delle richieste includono:
+  [Riccioli d'oro](https://github.com/FairwindsOps/goldilocks) 
+  [Parca](https://www.parca.dev/) 
+  [Profiler](https://prodfiler.com/) 
+  [rg](https://mhausenblas.info/right-size-guide/) 

### Configura le quote di risorse per i namespace
<a name="_configure_resource_quotas_for_namespaces"></a>

I namespace sono concepiti per l'uso negli ambienti con molti utenti distribuiti su più team o progetti. Forniscono un ambito per i nomi e sono un modo per dividere le risorse del cluster tra più team, progetti e carichi di lavoro. È possibile limitare il consumo aggregato di risorse in un namespace. L'[https://kubernetes.io/docs/concepts/policy/resource-quotas/](https://kubernetes.io/docs/concepts/policy/resource-quotas/)oggetto può limitare la quantità di oggetti che possono essere creati in un namespace per tipo, nonché la quantità totale di risorse di elaborazione che possono essere consumate dalle risorse di quel progetto. È possibile limitare la somma totale di risorse di archiviazione and/or (CPU e memoria) che possono essere richieste in un determinato spazio dei nomi.

Se la quota di risorse è abilitata per uno spazio dei nomi per risorse di calcolo come CPU e memoria, gli utenti devono specificare le richieste o i limiti per ogni contenitore in tale spazio dei nomi.

Prendi in considerazione la possibilità di configurare le quote per ogni namespace. Prendi in considerazione l'utilizzo `LimitRanges` per applicare automaticamente limiti preconfigurati ai contenitori all'interno di un namespace.

### Limita l'utilizzo delle risorse del contenitore all'interno di un namespace
<a name="_limit_container_resource_usage_within_a_namespace"></a>

Le quote di risorse aiutano a limitare la quantità di risorse che un namespace può utilizzare. L'[`LimitRange`oggetto](https://kubernetes.io/docs/concepts/policy/limit-range/) può aiutarti a implementare le risorse minime e massime richieste da un contenitore. Utilizzando `LimitRange` you puoi impostare una richiesta e dei limiti predefiniti per i contenitori, il che è utile se l'impostazione dei limiti delle risorse di elaborazione non è una pratica standard nell'organizzazione. Come suggerisce il nome, `LimitRange` può imporre l'utilizzo minimo e massimo delle risorse di calcolo per Pod o Container in un namespace. Inoltre, applica la richiesta di archiviazione minima e massima per in un namespace. PersistentVolumeClaim 

Valuta la possibilità di `ResourceQuota` utilizzarlo insieme `LimitRange` a per imporre limiti a livello di contenitore e namespace. L'impostazione di questi limiti garantirà che un contenitore o un namespace non influiscano sulle risorse utilizzate dagli altri tenant del cluster.

### Usa NodeLocal DNSCache
<a name="_use_nodelocal_dnscache"></a>

È possibile migliorare le prestazioni del Cluster DNS [NodeLocalDNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/)eseguendo. Questa funzionalità esegue un agente di caching DNS sui nodi del cluster come. DaemonSet Tutti i pod utilizzano l'agente di caching DNS in esecuzione sul nodo per la risoluzione dei nomi anziché utilizzare Service. `kube-dns` Questa funzionalità è inclusa automaticamente in EKS Auto Mode.

### Configurare CoredNS con scalabilità automatica
<a name="_configure_auto_scaling_coredns"></a>

Un altro metodo per migliorare le prestazioni del Cluster DNS consiste nell'abilitare l'[auto-scaling](https://docs.aws.amazon.com/eks/latest/userguide/coredns-autoscaling.html) integrato dei CoredNS Pods.

Questa funzionalità monitora continuamente lo stato del cluster, incluso il numero di nodi e core della CPU. Sulla base di tali informazioni, il controller adatterà dinamicamente il numero di repliche dell’implementazione CoreDNS in un cluster EKS.