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 EC2 istanza è probabilmente una delle decisioni più difficili che i clienti devono affrontare perché si trovano in cluster con più carichi di lavoro. Non esiste una soluzione completa. one-size-fits 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 upgrade e la configurazione gestiti. Può essere scalato con Kubernetes Cluster Autoscaler ed è un'opzione comune per i cluster che hanno diverse esigenze di elaborazione.

Karpenter è un autoscaler di nodi open source e nativo del carico di lavoro creato da AWS. Ridimensiona i nodi di 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 gruppi di nodi. I nodi vengono creati direttamente, il EC2 che evita le quote predefinite dei gruppi di nodi (450 nodi per gruppo) e offre una maggiore flessibilità di selezione delle istanze con un minore sovraccarico operativo. Consigliamo ai clienti di utilizzare Karpenter quando possibile.

Usa molti tipi di istanze diversi 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 riduci il numero di nodi oltre la capacità della regione, riceverai un messaggio di errore indicante che non sono disponibili istanze. Per evitare questo problema, non è necessario limitare arbitrariamente il tipo di istanze che possono essere utilizzate nel 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 scalati 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 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 inferiore sul piano di controllo di Kubernetes perché ci saranno meno kubelet e saranno in esecuzione. DaemonSets Tuttavia, i nodi di grandi dimensioni potrebbero non essere utilizzati completamente 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 sarebbe limitato a 110 pod per nodo. Se i tuoi pod utilizzano 4 core ciascuno, ciò potrebbe essere previsto (4 core x 110 = 440 core/nodo). Con un cluster a 3 nodi, la capacità di gestire un incidente di istanza sarebbe ridotta perché un'interruzione di un'istanza potrebbe influire su 1/3 del 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 dovrebbero definire le risorse di cui hanno bisogno e la disponibilità richiesta tramite contaminazioni, tolleranze e. PodTopologySpread Dovrebbero preferire i nodi più grandi che possano essere utilizzati appieno 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 zone di disponibilità e 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 tra le zone di disponibilità, è necessario utilizzare: topologySpreadConstraints

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 del carico di lavoro

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

Per garantire prestazioni costanti ai carichi di lavoro, un carico di lavoro può utilizzare le etichette Karpenter supportate per definire 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 abbinare 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 elaborazione in modo efficiente

Le risorse di calcolo includono EC2 istanze e zone di disponibilità. L'uso efficace delle risorse di elaborazione aumenterà la scalabilità, la disponibilità, le prestazioni e ridurrà i costi totali. L'utilizzo 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 elaborazione di cui hanno bisogno senza prima creare gruppi di nodi o configurare tag di etichette per nodi specifici. Per ulteriori informazioni, consulta le best practice di Karpenter. Valuta la possibilità di abilitare il consolidamento nel tuo provider Karpenter per sostituire i nodi sottoutilizzati.

Automatizza gli aggiornamenti di Amazon Machine Image (AMI)

Mantenendo aggiornati i componenti del Worker Node ti assicurerai 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 del sistema operativo, del kernel e delle patch delle applicazioni installate localmente ridurrà la manutenzione man mano che si aumenta la scalabilità.

Si consiglia di utilizzare l'ultima AMI Bottlerocket ottimizzata per Amazon EKS o Amazon EKS ottimizzata per Amazon EKS per l'immagine del nodo. Karpenter utilizzerà automaticamente l'ultima AMI disponibile per effettuare il provisioning di nuovi nodi nel cluster. I gruppi di nodi gestiti aggiorneranno l'AMI durante un aggiornamento del 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 lancio di Auto Scaling Group (ASG) con nuove AMI IDs quando sono disponibili per il rilascio delle patch. Le versioni minori dell'AMI (ad esempio da 1.23.5 a 1.24.3) saranno disponibili nella console EKS e nell'API 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'AMI più recente disponibile da questa pagina o utilizzare la CLI 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

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 tue applicazioni condividono un singolo volume root EBS con l'host, ciò può esaurire la quota di 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 partizione overlay, montano un volume locale dall'host e anche quando si connettono 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 dello 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 EC2 istanze 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 effettuare il provisioning dei tuoi gruppi di nodi, consulta gli esempi in EKS Blueprints for terraform. Se si utilizza Karpenter per il provisioning dei nodi, è possibile utilizzare i dati utente del nodo per blockDeviceMappingsaggiungere volumi aggiuntivi.

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

---
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 su quali tipi di istanza devono essere eseguiti e limitare il numero di repliche su una singola istanza con caratteristiche Kubernetes.

Disabilita la registrazione non necessaria su disco

Evitate la registrazione locale non necessaria evitando di eseguire 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 disponibili quando la velocità di aggiornamento del sistema operativo è una necessità

Importante

L'applicazione di patch alle istanze esistenti deve essere eseguita solo quando necessario. Amazon consiglia di trattare l'infrastruttura come immutabile e di testare accuratamente gli aggiornamenti promossi negli 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 isolare, svuotare o sostituire l'istanza.

Per sostituire un'istanza devi prima crearne, convalidarla e distribuirne una nuova. AMIs È necessario creare un'istanza sostitutiva e la vecchia istanza deve essere isolata e drenata. Quindi i carichi di lavoro devono essere creati sulla nuova istanza, verificati e ripetuti per tutte le istanze che devono essere corrette. Occorrono ore, giorni o settimane per sostituire le istanze in modo sicuro senza interrompere i carichi di lavoro.

Amazon consiglia di utilizzare un'infrastruttura immutabile costruita, testata e promossa a partire da un sistema dichiarativo automatizzato, ma se hai l'esigenza di applicare rapidamente le patch ai sistemi, dovrai applicare patch ai sistemi esistenti e sostituirli non appena ne saranno AMIs disponibili di nuovi. A causa dell'ampio differenziale 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.

I nodi di patching ti consentiranno 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 che funzionano 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.