Carichi di lavoro - 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à.

Carichi di lavoro

I carichi di lavoro hanno un impatto sulla scalabilità del cluster. I carichi di lavoro che utilizzano APIs molto Kubernetes limiteranno la quantità totale di carichi di lavoro che è possibile avere in un singolo cluster, ma ci sono alcune impostazioni predefinite che puoi modificare per ridurre il carico.

I carichi di lavoro in un cluster Kubernetes hanno accesso a funzionalità che si integrano con l'API Kubernetes (ad esempio Secrets and ServiceAccounts), ma queste funzionalità non sono sempre obbligatorie e devono essere disabilitate se non vengono utilizzate. La limitazione dell'accesso ai carichi di lavoro e della dipendenza dal piano di controllo di Kubernetes aumenterà il numero di carichi di lavoro eseguibili nel cluster e migliorerà la sicurezza dei cluster rimuovendo l'accesso non necessario ai carichi di lavoro e implementando pratiche con privilegi minimi. Leggi le best practice di sicurezza per ulteriori informazioni.

Utilizzare IPv6 per il collegamento in rete tramite pod

Non è possibile effettuare la transizione di un VPC da uno all'altro, IPv4 IPv6 abilitarlo IPv6 prima di effettuare il provisioning di un cluster è importante. Se IPv6 abiliti un VPC, ciò non significa che devi utilizzarlo e se i tuoi pod e servizi lo utilizzano, IPv6 puoi comunque indirizzare il traffico da e verso gli indirizzi. IPv4 Per ulteriori informazioni, consulta le best practice di rete EKS.

L'utilizzo IPv6 nel cluster evita alcuni dei limiti più comuni di scalabilità dei cluster e dei carichi di lavoro. IPv6 evita l'esaurimento degli indirizzi IP laddove non sia possibile creare pod e nodi perché non è disponibile alcun indirizzo IP. Inoltre, presenta miglioramenti delle prestazioni per nodo, poiché i pod ricevono gli indirizzi IP più velocemente riducendo il numero di allegati ENI per nodo. Puoi ottenere prestazioni del nodo simili utilizzando la modalità IPv4 prefisso nel VPC CNI, ma devi comunque assicurarti di avere abbastanza indirizzi IP disponibili nel VPC.

Limita il numero di servizi per namespace

Il numero massimo di servizi in un namespace è 5.000 e il numero massimo di servizi in un cluster è 10.000. Per organizzare carichi di lavoro e servizi, aumentare le prestazioni ed evitare l'impatto a cascata sulle risorse con ambito namespace, consigliamo di limitare il numero di servizi per namespace a 500.

Il numero di regole delle tabelle IP create per nodo con kube-proxy aumenta con il numero totale di servizi nel cluster. La generazione di migliaia di regole di tabelle IP e il routing dei pacchetti tramite tali regole hanno un impatto sulle prestazioni dei nodi e aggiungono latenza di rete.

Crea namespace Kubernetes che comprendano un singolo ambiente applicativo purché il numero di servizi per namespace sia inferiore a 500. Ciò consentirà di mantenere l'individuazione dei servizi sufficientemente ridotta da evitare i limiti di individuazione dei servizi e può anche aiutarti a evitare le collisioni di denominazione dei servizi. Gli ambienti applicativi (ad esempio dev, test, prod) devono utilizzare cluster EKS separati anziché namespace.

Comprendi le quote di Elastic Load Balancer

Quando crei i tuoi servizi, considera il tipo di bilanciamento del carico che utilizzerai (ad esempio Network Load Balancer (NLB) o Application Load Balancer (ALB)). Ogni tipo di load balancer offre funzionalità diverse e ha quote diverse. Alcune delle quote predefinite possono essere modificate, ma ci sono alcuni valori massimi di quota che non possono essere modificati. Per visualizzare le quote e l'utilizzo del tuo account, consulta la dashboard di Service Quotas nella console AWS.

Ad esempio, gli obiettivi ALB predefiniti sono 1000. Se disponi di un servizio con più di 1000 endpoint, dovrai aumentare la quota o suddividere il servizio tra più endpoint ALBs o utilizzare Kubernetes Ingress. Le destinazioni NLB predefinite sono 3000, ma sono limitate a 500 destinazioni per AZ. Se il tuo cluster utilizza più di 500 pod per un servizio NLB, dovrai utilizzarne più di uno AZs o richiedere un aumento del limite di quota.

Un'alternativa all'utilizzo di un sistema di bilanciamento del carico abbinato a un servizio consiste nell'utilizzare un controller di ingresso. Il controller AWS Load Balancer può creare ALBs risorse in ingresso, ma potresti prendere in considerazione l'utilizzo di un controller dedicato nel tuo cluster. Un controller di ingresso interno al cluster consente di esporre più servizi Kubernetes da un unico sistema di bilanciamento del carico eseguendo un proxy inverso all'interno del cluster. I controller dispongono di funzionalità diverse, come il supporto per l'API Gateway, che può comportare vantaggi a seconda del numero e delle dimensioni dei carichi di lavoro.

Usa Route 53, Global Accelerator o CloudFront

Per rendere disponibile un servizio che utilizza più sistemi di bilanciamento del carico come singolo endpoint, devi utilizzare Amazon CloudFront, AWS Global Accelerator o Amazon Route 53 per esporre tutti i sistemi di bilanciamento del carico come un unico endpoint rivolto al cliente. Ciascuna opzione presenta vantaggi diversi e può essere utilizzata separatamente o insieme a seconda delle esigenze.

Route 53 può esporre più sistemi di bilanciamento del carico con un nome comune e inviare traffico a ciascuno di essi in base al peso assegnato. Per ulteriori informazioni sui pesi DNS, consulta la documentazione e scopri come implementarli con il controller DNS esterno Kubernetes nella documentazione di AWS Load Balancer Controller.

Global Accelerator può indirizzare i carichi di lavoro verso la regione più vicina in base all'indirizzo IP richiesto. Ciò può essere utile per i carichi di lavoro distribuiti in più regioni, ma non migliora il routing verso un singolo cluster in una singola regione. L'uso di Route 53 in combinazione con Global Accelerator offre vantaggi aggiuntivi come il controllo dello stato e il failover automatico se non è disponibile una AZ. Puoi vedere un esempio di utilizzo di Global Accelerator con Route 53 in questo post del blog.

CloudFront può essere utilizzato con Route 53 e Global Accelerator o da solo per indirizzare il traffico verso più destinazioni. CloudFront memorizza nella cache le risorse fornite dalle fonti di origine, il che può ridurre i requisiti di larghezza di banda a seconda del tipo di servizio che si sta servendo.

Utilizza EndpointSlices al posto degli endpoint

Quando scopri i pod che corrispondono a un'etichetta di servizio, dovresti usarli EndpointSlicesal posto degli endpoint. Gli endpoint erano un modo semplice per esporre servizi su piccola scala, ma i servizi di grandi dimensioni con scalabilità automatica o aggiornamenti generano molto traffico sul piano di controllo di Kubernetes. EndpointSlices dispongono di un raggruppamento automatico che abilita cose come i suggerimenti che tengono conto della topologia.

Non tutti i controller lo utilizzano come impostazione predefinita. EndpointSlices È necessario verificare le impostazioni del controller e abilitarlo se necessario. Per il controller AWS Load Balancer è necessario abilitare il flag --enable-endpoint-slices opzionale da utilizzare. EndpointSlices

Se possibile, usa segreti immutabili ed esterni

Il kubelet conserva una cache delle chiavi e dei valori correnti per i Secrets utilizzati nei volumi per i pod su quel nodo. Il kubelet controlla i Secrets per rilevare le modifiche. Man mano che il cluster cresce, il numero crescente di orologi può influire negativamente sulle prestazioni del server API.

Esistono due strategie per ridurre il numero di orologi su Secrets:

  • Per le applicazioni che non richiedono l'accesso alle risorse Kubernetes, puoi disabilitare i segreti degli account di servizio con montaggio automatico impostando Token: false automountServiceAccount

  • Se i segreti dell'applicazione sono statici e non verranno modificati in futuro, contrassegna il segreto come immutabile. Il kubelet non mantiene un controllo API per i segreti immutabili.

Per disabilitare il montaggio automatico di un account di servizio sui pod, puoi utilizzare la seguente impostazione nel tuo carico di lavoro. Puoi sovrascrivere queste impostazioni se carichi di lavoro specifici richiedono un account di servizio.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app
automountServiceAccountToken: true

Monitora il numero di segreti nel cluster prima che superi il limite di 10.000. È possibile visualizzare il numero totale di segreti in un cluster con il seguente comando. È necessario monitorare questo limite tramite gli strumenti di monitoraggio del cluster.

kubectl get secrets -A | wc -l

È necessario impostare il monitoraggio per avvisare un amministratore del cluster prima che venga raggiunto questo limite. Prendi in considerazione l'utilizzo di opzioni di gestione dei segreti esterne come AWS Key Management Service (AWS KMS) o Hashicorp Vault con il driver CSI Secrets Store.

Limita la cronologia delle distribuzioni

I pod possono essere lenti durante la creazione, l'aggiornamento o l'eliminazione perché i vecchi oggetti vengono ancora tracciati nel cluster. Puoi ridurre il numero revisionHistoryLimit di implementazioni per ripulire quelle più vecchie, il ReplicaSets che ridurrà al numero totale di oggetti tracciati da Kubernetes Controller Manager. Il limite cronologico predefinito per le distribuzioni è 10.

Se il cluster crea molti oggetti di lavoro tramite CronJobs o altri meccanismi, è necessario utilizzare l'ttlSecondsAfterFinishedimpostazione per pulire automaticamente i vecchi pod nel cluster. Ciò rimuoverà i lavori eseguiti con successo dalla cronologia dei processi dopo un determinato periodo di tempo.

Quando un Pod viene eseguito su un nodo, il kubelet aggiunge un set di variabili di ambiente per ogni servizio attivo. I processi Linux hanno una dimensione massima per il loro ambiente, che può essere raggiunta se hai troppi servizi nel tuo spazio dei nomi. Il numero di servizi per namespace non deve superare 5.000. Dopodiché, il numero di variabili dell'ambiente di servizio supera i limiti della shell, causando il blocco dei Pods all'avvio.

Esistono altri motivi per cui i pod non dovrebbero utilizzare le variabili di ambiente di servizio per l'individuazione dei servizi. Alcuni esempi sono i conflitti tra i nomi delle variabili di ambiente, la perdita di nomi di servizio e la dimensione totale dell'ambiente. È necessario utilizzare CoredNS per scoprire gli endpoint del servizio.

Limita i webhook ad ammissione dinamica per risorsa

I webhook di ammissione dinamici includono webhook di ammissione e webhook mutanti. Sono endpoint API che non fanno parte del piano di controllo di Kubernetes e vengono chiamati in sequenza quando una risorsa viene inviata all'API Kubernetes. Ogni webhook ha un timeout predefinito di 10 secondi e può aumentare la quantità di tempo necessaria per una richiesta API se hai più webhook o se hai un timeout di uno di essi.

Assicurati che i tuoi webhook siano altamente disponibili, specialmente durante un incidente AZ, e che la FailurePolicy sia impostata correttamente per rifiutare la risorsa o ignorare l'errore. Non chiamate i webhook quando non sono necessari, permettendo ai comandi --dry-run kubectl di bypassare il webhook.

apiVersion: admission.k8s.io/v1
kind: AdmissionReview
request:
  dryRun: False

I webhook mutanti possono modificare le risorse in successione frequente. Se disponi di 5 webhook mutanti e distribuisci 50 risorse, etcd memorizzerà tutte le versioni di ciascuna risorsa fino alla compattazione, ogni 5 minuti, per rimuovere le vecchie versioni delle risorse modificate. In questo scenario, quando etcd rimuove le risorse sostituite, verranno rimosse 200 versioni di risorse da etcd e, a seconda delle dimensioni delle risorse, potrebbe occupare molto spazio sull'host etcd fino a quando la deframmentazione non viene eseguita ogni 15 minuti.

Questa deframmentazione può causare pause in etcd che potrebbero avere altri effetti sull'API e sui controller di Kubernetes. È consigliabile evitare la modifica frequente di risorse di grandi dimensioni o la modifica di centinaia di risorse in rapida successione.

Confronta i carichi di lavoro tra più cluster

Se hai due cluster che dovrebbero avere prestazioni simili ma non lo fanno, prova a confrontare le metriche per identificarne il motivo.

Ad esempio, il confronto della latenza dei cluster è un problema comune. Questo è in genere causato dalla differenza nel volume delle richieste API. È possibile eseguire la seguente CloudWatch LogInsight query per comprendere la differenza.

filter @logStream like "kube-apiserver-audit"
| stats count(*) as cnt by objectRef.apiGroup, objectRef.apiVersion, objectRef.resource, userAgent, verb, responseStatus.code
| sort cnt desc
| limit 1000

Puoi aggiungere filtri aggiuntivi per restringere il campo, ad esempio concentrandoti su tutte le richieste di elenchi dafoo.

filter @logStream like "kube-apiserver-audit"
| filter verb = "list"
| filter user.username like "foo"
| stats count(*) as cnt by objectRef.apiGroup, objectRef.apiVersion, objectRef.resource, responseStatus.code
| sort cnt desc
| limit 1000