Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Plano de datos de Kubernetes
La selección de los tipos de EC2 instancias es posiblemente una de las decisiones más difíciles a las que se enfrentan los clientes cuando se trata de clústeres con múltiples cargas de trabajo. No existe una solución one-size-fits definitiva. Estos son algunos consejos que le ayudarán a evitar los errores más comunes relacionados con el escalado de la computación.
Escalado automático de nodos
Te recomendamos que utilices el escalado automático de nodos, ya que reduce el esfuerzo y se integra perfectamente con Kubernetes. Se recomiendan los grupos de nodos gestionados y Karpenter
Los grupos de nodos gestionados le ofrecerán la flexibilidad de los grupos de Amazon EC2 Auto Scaling, con ventajas adicionales para la configuración y las actualizaciones gestionadas. Se puede escalar con el escalador automático de clústeres de Kubernetes
Karpenter es un escalador automático de nodos nativo de carga de trabajo de código abierto creado por AWS. Escala los nodos de un clúster en función de los requisitos de carga de trabajo en materia de recursos (p. ej., la GPU) y de las limitaciones y tolerancias (p. ej., la dispersión por zonas) sin gestionar los grupos de nodos. Los nodos se crean directamente, EC2 lo que evita las cuotas predeterminadas de los grupos de nodos (450 nodos por grupo) y proporciona una mayor flexibilidad de selección de instancias con una menor sobrecarga operativa. Recomendamos a los clientes que utilicen Karpenter siempre que sea posible.
Usa muchos tipos de instancias diferentes EC2
Cada región de AWS tiene un número limitado de instancias disponibles por tipo de instancia. Si crea un clúster que usa solo un tipo de instancia y escala el número de nodos más allá de la capacidad de la región, recibirá un error que indica que no hay instancias disponibles. Para evitar este problema, no debes limitar arbitrariamente el tipo de instancias que se pueden usar en tu clúster.
Karpenter utilizará un amplio conjunto de tipos de instancias compatibles de forma predeterminada y seleccionará una instancia en el momento del aprovisionamiento en función de los requisitos de carga de trabajo pendientes, la disponibilidad y el coste. Puede ampliar la lista de tipos de instancias utilizados en la clave de. karpenter.k8s.aws/instance-category
NodePools
El escalador automático de clústeres de Kubernetes requiere que los grupos de nodos tengan un tamaño similar para poder escalarlos de forma coherente. Debes crear varios grupos en función del tamaño de la CPU y la memoria y escalarlos de forma independiente. Utilice el ec2-instance-selector
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
Prefiera nodos más grandes para reducir la carga del servidor de API
A la hora de decidir qué tipos de instancias usar, un menor número de nodos grandes supondrá una menor carga en el plano de control de Kubernetes, ya que habrá menos kubelets y en ejecución. DaemonSets Sin embargo, es posible que los nodos grandes no se utilicen plenamente como los nodos más pequeños. Los tamaños de los nodos deben evaluarse en función de la disponibilidad de la carga de trabajo y los requisitos de escala.
Un clúster con tres instancias u-24tb1.metal (24 TB de memoria y 448 núcleos) tiene 3 kubelets y, de forma predeterminada, estaría limitado a 110 pods por nodo. Si sus pods utilizan 4 núcleos cada uno, es de esperar (4 núcleos x 110 = 440 núcleos por nodo). Con un clúster de 3 nodos, tu capacidad para gestionar un incidente en una instancia sería baja, ya que la interrupción de una instancia podría afectar a un tercio del clúster. Debes especificar los requisitos de los nodos y la distribución de los módulos en tus cargas de trabajo para que el programador de Kubernetes pueda colocar las cargas de trabajo correctamente.
Las cargas de trabajo deben definir los recursos que necesitan y la disponibilidad requerida mediante restricciones, tolerancias y. PodTopologySpread
El programador de Kubernetes intentará distribuir automáticamente las cargas de trabajo entre las zonas de disponibilidad y los hosts si hay recursos disponibles. Si no hay capacidad disponible, el escalador automático de clústeres de Kubernetes intentará añadir nodos en cada zona de disponibilidad de manera uniforme. Karpenter intentará añadir nodos de la forma más rápida y económica posible, a menos que la carga de trabajo especifique otros requisitos.
Para forzar que las cargas de trabajo se distribuyan con el programador y se creen nuevos nodos entre las zonas de disponibilidad, debe utilizar: 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
Utilice nodos de tamaños similares para lograr un rendimiento uniforme de las cargas de trabajo
Las cargas de trabajo deben definir el tamaño de los nodos en los que deben ejecutarse para permitir un rendimiento uniforme y un escalado predecible. Una carga de trabajo que requiera 500 millones de CPU tendrá un rendimiento diferente en una instancia de 4 núcleos que en una de 16 núcleos. Evita los tipos de instancias que utilizan ráfagas, CPUs como las instancias de la serie T.
Para garantizar que tus cargas de trabajo tengan un rendimiento uniforme, una carga de trabajo puede utilizar las etiquetas de Karpenter compatibles
kind: deployment ... spec: template: spec: containers: nodeSelector: karpenter.k8s.aws/instance-size: 8xlarge
Las cargas de trabajo que se programen en un clúster con el escalador automático de clústeres de Kubernetes deben hacer coincidir un selector de nodos con los grupos de nodos según la coincidencia de etiquetas.
spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: eks.amazonaws.com/nodegroup operator: In values: - 8-core-node-group # match your node group name
Utilice los recursos informáticos de forma eficiente
Los recursos informáticos incluyen EC2 instancias y zonas de disponibilidad. El uso eficaz de los recursos informáticos aumentará la escalabilidad, la disponibilidad y el rendimiento y reducirá el coste total. El uso eficiente de los recursos es extremadamente difícil de predecir en un entorno de escalado automático con múltiples aplicaciones. Karpenter
Karpenter permite a las cargas de trabajo declarar el tipo de recursos informáticos que necesitan sin tener que crear primero grupos de nodos ni configurar etiquetas para nodos específicos. Consulte las prácticas recomendadas de Karpenter para obtener más información. Considere habilitar la consolidación en su aprovisionador de Karpenter para reemplazar los nodos que están infrautilizados.
Automatice las actualizaciones de Amazon Machine Image (AMI)
Si mantiene actualizados los componentes de los nodos de trabajo, garantizará que disponga de los últimos parches de seguridad y funciones compatibles con la API de Kubernetes. La actualización del kubelet es el componente más importante de la funcionalidad de Kubernetes, pero la automatización de los parches del sistema operativo, del kernel y de las aplicaciones instaladas localmente reducirá el mantenimiento a medida que se vaya escalando.
Se recomienda utilizar la última AMI de Amazon Linux 2 optimizada para Amazon EKS o Bottlerocket optimizada para Amazon EKS para la imagen de nodo. Karpenter utilizará automáticamente la última AMI disponible
Para los grupos de nodos gestionados, debe actualizar la plantilla de lanzamiento del Grupo Auto Scaling (ASG) con la nueva AMI IDs cuando estén disponibles para las versiones de parches. Las versiones secundarias de AMI (por ejemplo, de la 1.23.5 a la 1.24.3) estarán disponibles en la consola y la API de EKS como actualizaciones para el grupo de nodos. Las versiones de parches (p. ej., de la 1.23.5 a la 1.23.6) no se presentarán como actualizaciones para los grupos de nodos. Si desea mantener su grupo de nodos actualizado con las versiones de parches de la AMI, debe crear una nueva versión de la plantilla de lanzamiento y dejar que el grupo de nodos sustituya las instancias por la nueva versión de la AMI.
Puede encontrar la AMI más reciente disponible en esta página o utilizar la AWS CLI.
aws ssm get-parameter \ --name /aws/service/eks/optimized-ami/1.24/amazon-linux-2/recommended/image_id \ --query "Parameter.Value" \ --output text
Utilice varios volúmenes de EBS como contenedores
Los volúmenes de EBS tienen una cuota input/output (de E/S) basada en el tipo de volumen (por ejemplo, gp3) y el tamaño del disco. Si sus aplicaciones comparten un único volumen raíz de EBS con el host, esto puede agotar la cuota de disco de todo el host y provocar que otras aplicaciones esperen hasta alcanzar la capacidad disponible. Las aplicaciones escriben en el disco si escriben archivos en su partición superpuesta, montan un volumen local desde el host y también cuando se desconectan de forma estándar (STDOUT), según el agente de registro utilizado.
Para evitar el I/O agotamiento del disco, debe montar un segundo volumen en la carpeta de estado del contenedor (por ejemplo, /run/containerd), usar volúmenes EBS independientes para el almacenamiento de la carga de trabajo y deshabilitar el registro local innecesario.
Para montar un segundo volumen en sus EC2 instancias mediante eksctl
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"
Si utilizas terraform para aprovisionar tus grupos de nodos, consulta algunos ejemplos en EKS BlueprintsblockDeviceMappings
Para montar un volumen de EBS directamente en su pod, debe utilizar el controlador CSI de AWS EBS
--- 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
Evite las instancias con límites de conexión de EBS bajos si las cargas de trabajo utilizan volúmenes de EBS
EBS es una de las formas más fáciles de que las cargas de trabajo tengan almacenamiento persistente, pero también tiene limitaciones de escalabilidad. Cada tipo de instancia tiene un número máximo de volúmenes de EBS que se pueden adjuntar. Las cargas de trabajo deben declarar los tipos de instancias en los que deben ejecutarse y limitar el número de réplicas en una sola instancia contaminada por Kubernetes.
Deshabilita los registros innecesarios en el disco
Evite el registro local innecesario al no ejecutar las aplicaciones mediante la depuración del registro en producción y la desactivación del registro que lee y escribe en el disco con frecuencia. Journald es el servicio de registro local que mantiene un búfer de registro en la memoria y lo vacía en el disco periódicamente. Se prefiere Journald a syslog, que registra todas las líneas inmediatamente en el disco. Al deshabilitar syslog, también se reduce la cantidad total de almacenamiento que se necesita y se evitan complicadas reglas de rotación de registros. Para deshabilitar syslog, puedes añadir el siguiente fragmento a tu configuración de cloud-init:
runcmd: - [ systemctl, disable, --now, syslog.service ]
Las instancias de parcheo se implementan cuando la velocidad de actualización del sistema operativo es necesaria
importante
Solo se deben aplicar parches a las instancias instaladas cuando sea necesario. Amazon recomienda tratar la infraestructura como inmutable y probar minuciosamente las actualizaciones que se promocionan en entornos inferiores de la misma manera que lo hacen las aplicaciones. Esta sección se aplica cuando eso no es posible.
Se tarda unos segundos en instalar un paquete en un host Linux existente sin interrumpir las cargas de trabajo en contenedores. El paquete se puede instalar y validar sin acordonar, agotar ni reemplazar la instancia.
Para reemplazar una instancia, primero debe crear, validar y distribuir una nueva. AMIs Se debe crear un sustituto para la instancia, y se debe acordonar y vaciar la instancia anterior. Luego, las cargas de trabajo deben crearse en la nueva instancia, verificarse y repetirse para todas las instancias que necesiten ser parcheadas. Reemplazar las instancias de forma segura sin interrumpir las cargas de trabajo lleva horas, días o semanas.
Amazon recomienda utilizar una infraestructura inmutable que se cree, pruebe y promueva a partir de un sistema declarativo automatizado, pero si tiene la necesidad de parchar los sistemas rápidamente, tendrá que parchear los sistemas y sustituirlos a medida que haya nuevos AMIs disponibles. Debido a la gran diferencia de tiempo entre la aplicación de parches y la sustitución de los sistemas, recomendamos utilizar AWS Systems Manager Patch Manager para automatizar la aplicación de parches a los nodos cuando sea necesario.
Los nodos de parches le permitirán implementar rápidamente las actualizaciones de seguridad y reemplazar las instancias de forma regular una vez que se haya actualizado la AMI. Si utiliza un sistema operativo con un sistema de archivos raíz de solo lectura, como Flatcar Container Linux