View a markdown version of this page

Piano dati Kubernetes - 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à.

Piano dati Kubernetes

La selezione dei tipi di istanze EC2 è probabilmente una delle decisioni più difficili che i clienti devono affrontare perché si tratta di cluster con più carichi di lavoro. Non esiste una soluzione valida per tutti. Ecco alcuni suggerimenti per aiutarti a evitare le insidie più comuni legate alla scalabilità del calcolo.

Scalabilità automatica dei nodi

Ti consigliamo di utilizzare la scalabilità automatica dei nodi che riduce la fatica e si integra profondamente con Kubernetes. I gruppi di nodi gestiti e Karpenter sono consigliati per cluster su larga scala.

I gruppi di nodi gestiti ti offriranno la flessibilità dei gruppi Amazon EC2 Auto Scaling con vantaggi aggiuntivi per gli aggiornamenti e la configurazione gestiti. Può essere scalato con Kubernetes Cluster Autoscaler ed è un'opzione comune per i cluster con diverse esigenze di elaborazione.

Karpenter è un programma di scalabilità automatica di nodi open source e nativo per carichi di lavoro creato da AWS. Scala i nodi in un cluster in base ai requisiti del carico di lavoro per le risorse (ad esempio GPU) e ai limiti e alle tolleranze (ad esempio la diffusione delle zone) senza gestire i gruppi di nodi. I nodi vengono creati direttamente da EC2, il che evita le quote predefinite dei gruppi di nodi (450 nodi per gruppo) e offre una maggiore flessibilità nella selezione delle istanze con minori costi operativi. Consigliamo ai clienti di utilizzare Karpenter quando possibile.

Utilizza diversi tipi di istanze EC2

Ogni regione AWS ha un numero limitato di istanze disponibili per tipo di istanza. Se crei un cluster che utilizza un solo tipo di istanza e scali il numero di nodi oltre la capacità della regione, riceverai un messaggio di errore indicante che non è disponibile alcuna istanza. Per evitare questo problema, non dovresti limitare arbitrariamente il tipo di istanze che possono essere utilizzate nel tuo cluster.

Per impostazione predefinita, Karpenter utilizzerà un'ampia gamma di tipi di istanze compatibili e sceglierà un'istanza al momento del provisioning in base ai requisiti, alla disponibilità e ai costi del carico di lavoro in sospeso. È possibile ampliare l'elenco dei tipi di istanza utilizzati nella chiave di. karpenter.k8s.aws/instance-category NodePools

Kubernetes Cluster Autoscaler richiede che i gruppi di nodi abbiano dimensioni simili in modo che possano essere ridimensionati in modo coerente. È necessario creare più gruppi in base alle dimensioni della CPU e della memoria e scalarli in modo indipendente. Usa il selettore di istanze ec2-instance-selector per identificare le istanze di dimensioni simili per i tuoi gruppi di nodi.

ec2-instance-selector --service eks --vcpus-min 8 --memory-min 16
a1.2xlarge
a1.4xlarge
a1.metal
c4.4xlarge
c4.8xlarge
c5.12xlarge
c5.18xlarge
c5.24xlarge
c5.2xlarge
c5.4xlarge
c5.9xlarge
c5.metal

Preferisci nodi più grandi per ridurre il carico del server API

Al momento di decidere quali tipi di istanze utilizzare, un numero inferiore di nodi di grandi dimensioni comporterà un carico minore sul Kubernetes Control Plane, perché ci saranno meno kubelet e funzionanti. DaemonSets Tuttavia, i nodi di grandi dimensioni potrebbero non essere utilizzati appieno come i nodi più piccoli. Le dimensioni dei nodi devono essere valutate in base alla disponibilità del carico di lavoro e ai requisiti di scalabilità.

Un cluster con tre istanze u-24tb1.metal (24 TB di memoria e 448 core) ha 3 kubelet e per impostazione predefinita è limitato a 110 pod per nodo. Se i tuoi pod utilizzano 4 core ciascuno, questo potrebbe essere previsto (4 core x 110 = 440). cores/node Con un cluster a 3 nodi, la capacità di gestire un incidente di istanza sarebbe bassa perché un'interruzione di 1 istanza potrebbe avere un impatto sul 1/3 cluster. È necessario specificare i requisiti dei nodi e la distribuzione dei pod nei carichi di lavoro in modo che lo scheduler Kubernetes possa posizionare correttamente i carichi di lavoro.

I carichi di lavoro devono definire le risorse di cui hanno bisogno e la disponibilità richiesta tramite limiti, tolleranze e. PodTopologySpread Dovrebbero preferire i nodi più grandi che possono essere pienamente utilizzati e soddisfare gli obiettivi di disponibilità per ridurre il carico sul piano di controllo, ridurre le operazioni e ridurre i costi.

Kubernetes Scheduler cercherà automaticamente di distribuire i carichi di lavoro tra le zone di disponibilità e gli host se le risorse sono disponibili. Se non è disponibile alcuna capacità, Kubernetes Cluster Autoscaler tenterà di aggiungere nodi in ciascuna zona di disponibilità in modo uniforme. Karpenter tenterà di aggiungere nodi nel modo più rapido ed economico possibile, a meno che il carico di lavoro non specifichi altri requisiti.

Per forzare la diffusione dei carichi di lavoro con lo scheduler e la creazione di nuovi nodi nelle zone di disponibilità, è necessario utilizzare la topologia: SpreadConstraints

spec:
  topologySpreadConstraints:
    - maxSkew: 3
      topologyKey: "topology.kubernetes.io/zone"
      whenUnsatisfiable: ScheduleAnyway
      labelSelector:
        matchLabels:
          dev: my-deployment
    - maxSkew: 2
      topologyKey: "kubernetes.io/hostname"
      whenUnsatisfiable: ScheduleAnyway
      labelSelector:
        matchLabels:
          dev: my-deployment

Utilizza nodi di dimensioni simili per prestazioni costanti dei carichi di lavoro

I carichi di lavoro devono definire le dimensioni dei nodi su cui devono essere eseguiti per consentire prestazioni coerenti e una scalabilità prevedibile. Un carico di lavoro che richiede 500 milioni di CPU avrà prestazioni diverse su un'istanza con 4 core rispetto a una con 16 core. Evita i tipi di istanze che utilizzano CPU burstable come le istanze della serie T.

Per assicurarsi che i carichi di lavoro ottengano prestazioni costanti, un carico di lavoro può utilizzare le etichette Karpenter supportate per indirizzare istanze di dimensioni specifiche.

kind: deployment
...
spec:
  template:
    spec:
    containers:
    nodeSelector:
      karpenter.k8s.aws/instance-size: 8xlarge

I carichi di lavoro pianificati in un cluster con Kubernetes Cluster Autoscaler devono far corrispondere un selettore di nodi ai gruppi di nodi in base alla corrispondenza delle etichette.

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: eks.amazonaws.com/nodegroup
            operator: In
            values:
            - 8-core-node-group    # match your node group name

Usa le risorse di calcolo in modo efficiente

Le risorse di elaborazione includono istanze EC2 e zone di disponibilità. L'uso efficace delle risorse di elaborazione aumenterà la scalabilità, la disponibilità e le prestazioni e ridurrà il costo totale. L'uso efficiente delle risorse è estremamente difficile da prevedere in un ambiente di scalabilità automatica con più applicazioni. Karpenter è stato creato per fornire istanze su richiesta in base alle esigenze del carico di lavoro per massimizzare l'utilizzo e la flessibilità.

Karpenter consente ai carichi di lavoro di dichiarare il tipo di risorse di calcolo di cui hanno bisogno senza prima creare gruppi di nodi o configurare etichette contenenti etichette per nodi specifici. Per ulteriori informazioni, consulta le best practice di Karpenter. https://docs.aws.amazon.com/eks/latest/best-practices/karpenter.html Valuta la possibilità di abilitare il consolidamento nel tuo provisioner Karpenter per sostituire i nodi sottoutilizzati.

Automatizza gli aggiornamenti di Amazon Machine Image (AMI)

Mantenere aggiornati i componenti dei nodi di lavoro ti assicurerà di disporre delle patch di sicurezza più recenti e delle funzionalità compatibili con l'API Kubernetes. L'aggiornamento del kubelet è il componente più importante per la funzionalità di Kubernetes, ma l'automazione delle patch del sistema operativo, del kernel e delle applicazioni installate localmente ridurrà la manutenzione man mano che aumenterai la scalabilità.

Si consiglia di utilizzare la versione più recente di Amazon Linux 2 ottimizzata per Amazon EKS o dell'AMI Bottlerocket ottimizzata per Amazon EKS per l'immagine del nodo. Karpenter utilizzerà automaticamente l'ultima AMI disponibile per eseguire il provisioning di nuovi nodi nel cluster. I gruppi di nodi gestiti aggiorneranno l'AMI durante l'aggiornamento di un gruppo di nodi ma non aggiorneranno l'ID AMI al momento del provisioning del nodo.

Per i gruppi di nodi gestiti, è necessario aggiornare il modello di avvio di Auto Scaling Group (ASG) con nuovi ID AMI quando sono disponibili per le versioni delle patch. Le versioni secondarie AMI (ad esempio da 1.23.5 a 1.24.3) saranno disponibili nella console e nell'API EKS come aggiornamenti per il gruppo di nodi. Le versioni di rilascio delle patch (ad esempio da 1.23.5 a 1.23.6) non verranno presentate come aggiornamenti per i gruppi di nodi. Se desideri mantenere aggiornato il tuo gruppo di nodi con le versioni delle patch AMI, devi creare una nuova versione del modello di avvio e lasciare che il gruppo di nodi sostituisca le istanze con la nuova versione AMI.

Puoi trovare l'ultima AMI disponibile in questa pagina o utilizzare l'interfaccia a riga di comando di AWS.

aws ssm get-parameter \
  --name /aws/service/eks/optimized-ami/1.24/amazon-linux-2/recommended/image_id \
  --query "Parameter.Value" \
  --output text

Usa più volumi EBS per i contenitori

Importante

Questa funzionalità è supportata solo su AL2; non è ancora supportata su AL2023.

I volumi EBS hanno una quota input/output (I/O) in base al tipo di volume (ad esempio gp3) e alla dimensione del disco. Se le applicazioni condividono un singolo volume radice EBS con l'host, ciò può esaurire la quota del disco per l'intero host e far sì che le altre applicazioni attendano la capacità disponibile. Le applicazioni scrivono su disco se scrivono file nella loro partizione overlay, montano un volume locale dall'host e anche quando si disconnettono allo standard out (STDOUT) a seconda dell'agente di registrazione utilizzato.

Per evitare l' I/O esaurimento del disco, è necessario montare un secondo volume nella cartella di stato del contenitore (ad esempio/run/containerd), utilizzare volumi EBS separati per l'archiviazione del carico di lavoro e disabilitare la registrazione locale non necessaria.

Per montare un secondo volume sulle tue istanze EC2 usando eksctl puoi usare un gruppo di nodi con questa configurazione:

managedNodeGroups:
  - name: al2-workers
    amiFamily: AmazonLinux2
    desiredCapacity: 2
    volumeSize: 80
    additionalVolumes:
      - volumeName: '/dev/sdz'
        volumeSize: 100
    preBootstrapCommands:
    - |
      "systemctl stop containerd"
      "mkfs -t ext4 /dev/nvme1n1"
      "rm -rf /var/lib/containerd/*"
      "mount /dev/nvme1n1 /var/lib/containerd/"
      "systemctl start containerd"

Se stai usando terraform per eseguire il provisioning dei tuoi gruppi di nodi, consulta gli esempi in EKS Blueprints for terraform. Se stai usando Karpenter per il provisioning dei nodi, puoi utilizzarli blockDeviceMappings con i dati utente del nodo per aggiungere volumi aggiuntivi.

Per montare un volume EBS direttamente sul tuo pod, dovresti usare il driver AWS EBS CSI e consumare un volume con una classe di archiviazione.

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-sc
  resources:
    requests:
      storage: 4Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: public.ecr.aws/docker/library/nginx
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-claim

Evita le istanze con limiti di collegamento EBS bassi se i carichi di lavoro utilizzano volumi EBS

EBS è uno dei modi più semplici per i carichi di lavoro di avere uno storage persistente, ma presenta anche limitazioni di scalabilità. Ogni tipo di istanza ha un numero massimo di volumi EBS che possono essere collegati. I carichi di lavoro devono dichiarare i tipi di istanza su cui devono essere eseguiti e limitare il numero di repliche su una singola istanza con contaminanti Kubernetes.

Disabilita la registrazione non necessaria su disco

Evita le registrazioni locali non necessarie non eseguendo le applicazioni con la registrazione di debug in produzione e disabilitando la registrazione che legge e scrive frequentemente su disco. Journald è il servizio di registrazione locale che mantiene un buffer di log in memoria e lo scarica periodicamente sul disco. Journald è preferito a syslog che registra immediatamente ogni riga su disco. La disabilitazione di syslog riduce anche la quantità totale di spazio di archiviazione necessaria ed evita la necessità di complicate regole di rotazione dei log. Per disabilitare syslog puoi aggiungere il seguente frammento alla tua configurazione cloud-init:

runcmd:
  - [ systemctl, disable, --now, syslog.service ]

Istanze di patch in atto quando la velocità di aggiornamento del sistema operativo è necessaria

Importante

Le istanze di patch installate devono essere eseguite solo quando necessario. Amazon consiglia di considerare l'infrastruttura come immutabile e di testare a fondo gli aggiornamenti che vengono promossi in ambienti inferiori allo stesso modo delle applicazioni. Questa sezione si applica quando ciò non è possibile.

Bastano pochi secondi per installare un pacchetto su un host Linux esistente senza interrompere i carichi di lavoro containerizzati. Il pacchetto può essere installato e convalidato senza bloccare, svuotare o sostituire l'istanza.

Per sostituire un'istanza devi prima creare, convalidare e distribuire nuove AMI. È necessario creare un'istanza sostitutiva e la vecchia istanza deve essere isolata e svuotata. Quindi i carichi di lavoro devono essere creati sulla nuova istanza, verificati e ripetuti per tutte le istanze che devono essere patchate. Sono necessarie ore, giorni o settimane per sostituire le istanze in modo sicuro senza interrompere i carichi di lavoro.

Amazon consiglia di utilizzare un'infrastruttura immutabile creata, testata e promossa da un sistema automatizzato e dichiarativo, ma se hai l'esigenza di applicare rapidamente patch ai sistemi, dovrai applicare patch ai sistemi e sostituirli non appena saranno disponibili nuove AMI. A causa dell'ampio divario di tempo tra l'applicazione delle patch e la sostituzione dei sistemi, consigliamo di utilizzare AWS Systems Manager Patch Manager per automatizzare l'applicazione delle patch ai nodi quando necessario.

L'applicazione delle patch ai nodi ti consentirà di implementare rapidamente gli aggiornamenti di sicurezza e sostituire le istanze a intervalli regolari dopo l'aggiornamento dell'AMI. Se utilizzi un sistema operativo con un file system root di sola lettura come Flatcar Container Linux o Bottlerocket OS, ti consigliamo di utilizzare gli operatori di aggiornamento compatibili con tali sistemi operativi. L'operatore di aggiornamento Flatcar Linux e l'operatore di aggiornamento Bottlerocket riavvieranno le istanze per mantenere i nodi aggiornati automaticamente.