Distribuya las cargas de trabajo entre los nodos y las zonas de disponibilidad - AWS Guía prescriptiva

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.

Distribuya las cargas de trabajo entre los nodos y las zonas de disponibilidad

La distribución de una carga de trabajo entre los dominios de error, como las zonas de disponibilidad y los nodos, mejora la disponibilidad de los componentes y reduce las probabilidades de que se produzcan errores en las aplicaciones escalables horizontalmente. En las siguientes secciones, se presentan formas de distribuir las cargas de trabajo entre los nodos y las zonas de disponibilidad.

Utilice las restricciones de dispersión de la topología de los módulos

Las restricciones de dispersión de la topología de los pods de Kubernetes indican al programador de Kubernetes que distribuya los pods gestionados por diferentes dominios de error ReplicaSet o StatefulSet entre ellos (zonas de disponibilidad, nodos y tipos de hardware). Cuando utilizas las restricciones de dispersión de la topología de los pods, puedes hacer lo siguiente:

  • Distribuya o concentre los pods en diferentes dominios de error en función de los requisitos de la aplicación. Por ejemplo, puede distribuir los pods para aumentar la resiliencia y concentrarlos para mejorar el rendimiento de la red.

  • Combine diferentes condiciones, como la distribución entre zonas de disponibilidad y la distribución entre nodos.

  • Especifique la acción preferida si no se pueden cumplir las condiciones:

    • Úselo whenUnsatisfiable: DoNotSchedule con una combinación de maxSkew y minDomains para crear requisitos estrictos para el programador.

    • Úselo whenUnsatisfiable: ScheduleAnyway para reducirmaxSkew.

Si una zona de error deja de estar disponible, los pods de esa zona dejan de estar en buen estado. Kubernetes reprograma los pods y, si es posible, respeta la restricción de dispersión.

Restricciones de dispersión de la topología del pod

El siguiente código muestra un ejemplo del uso de las restricciones de distribución de la topología de los pods en las zonas de disponibilidad o en los nodos:

... spec: selector: matchLabels: app: <your-app-label> replicas: 3 template: metadata: labels: <your-app-label> spec: serviceAccountName: <ServiceAccountName> ... topologySpreadConstraints: - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: topology.kubernetes.io/zone # <---spread those pods evenly over all availability zones whenUnsatisfiable: ScheduleAnyway - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: kubernetes.io/hostname # <---spread those pods evenly over all nodes whenUnsatisfiable: ScheduleAnyway

Restricciones de dispersión de la topología predeterminadas en todo el clúster

Kubernetes proporciona un conjunto predeterminado de restricciones de distribución de la topología para distribuir los pods entre los nodos y las zonas de disponibilidad:

defaultConstraints: - maxSkew: 3 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: ScheduleAnyway - maxSkew: 5 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway
nota

Las aplicaciones que necesitan diferentes tipos de restricciones topológicas pueden anular la política a nivel de clúster.

Las restricciones predeterminadas establecen un valor máximomaxSkew, lo que no resulta útil para las implementaciones que tienen un número reducido de pods. A partir de ahora, no se KubeSchedulerConfiguration puede cambiar en Amazon EKS. Si necesita aplicar otros conjuntos de restricciones de dispersión topológica, considere la posibilidad de utilizar un controlador de admisión mutante, como en la sección siguiente. También puede controlar las restricciones de dispersión de la topología predeterminadas si ejecuta un programador alternativo. Sin embargo, la administración de programadores personalizados añade complejidad y puede tener implicaciones en la resiliencia del clúster y en la alta disponibilidad. Por estas razones, no recomendamos usar un programador alternativo únicamente para las restricciones de dispersión de la topología.

La política de Gatekeeper sobre las restricciones de dispersión de la topología

Otra opción para aplicar las restricciones de dispersión de la topología es utilizar una política del proyecto Gatekeeper. Las políticas de Gatekeeper se definen a nivel de aplicación.

Los siguientes ejemplos de código muestran el uso de una Gatekeeper OPA política para la implementación. Puede modificar la política según sus necesidades. Por ejemplo, aplique la política solo a las implementaciones que tengan la etiqueta HA=true o escriba una política similar utilizando un controlador de políticas diferente.

En este primer ejemplo ConstraintTemplate se muestra el uso conk8stopologyspreadrequired_template.yml:

apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8stopologyspreadrequired spec: crd: spec: names: kind: K8sTopologySpreadRequired validation: openAPIV3Schema: type: object properties: message: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8stopologyspreadrequired get_message(parameters, _default) =3D msg { not parameters.message msg :=_default } get_message(parameters, _default) =3D msg { msg := parameters.message } violation[{"msg": msg}] { input.review.kind.kind ="Deployment" not input.review.object.spec.template.spec.topologySpreadConstraint def_msg :"Pod Topology Spread Constraints are required for Deployments" msg :get_message(input.parameters, def_msg) }

El siguiente código muestra el manifiesto k8stopologyspreadrequired_constraint.yml de constraints YAML:

apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sTopologySpreadRequired metadata: name: require-topologyspread-for-deployments spec: match: kinds: - apiGroups: ["apps"] kinds: ["Deployment"] namespaces: ## Without theses two lines will apply to the whole cluster - "example"

Cuándo usar las restricciones de dispersión topológica

Considere la posibilidad de utilizar restricciones de dispersión topológica en los siguientes escenarios:

  • Cualquier aplicación escalable horizontalmente (por ejemplo, servicios web sin estado)

  • Aplicaciones con réplicas activas-activas o activas-pasivas (por ejemplo, bases de datos o cachés NoSQL)

  • Aplicaciones con réplicas en espera (por ejemplo, controladores)

Entre los componentes del sistema que se pueden utilizar en el escenario de escalabilidad horizontal, por ejemplo, se incluyen los siguientes:

Afinidad y antiafinidad entre los pods

En algunos casos, es conveniente asegurarse de que no se ejecute más de un pod de un tipo específico en un nodo. Por ejemplo, para evitar programar varios pods con un uso intensivo de la red en el mismo nodo, puedes usar la regla de antiafinidad con la etiqueta o. Ingress Network-heavy Cuando la utilicesanti-affinity, también puedes usar una combinación de las siguientes opciones:

  • Contaminaciones en los nodos optimizados para la red

  • Las tolerancias correspondientes en los módulos con un uso intensivo de la red

  • Afinidad de nodos o selector de nodos para garantizar que los pods con un uso intensivo de la red utilicen instancias optimizadas para la red

Como ejemplo, se utilizan pods con un uso intensivo de la red. Es posible que tengas requisitos diferentes, como la GPU, la memoria o el almacenamiento local. Para ver otros ejemplos de uso y opciones de configuración, consulta la documentación de Kubernetes.

Reequilibre los pods

En esta sección, se analizan dos enfoques para reequilibrar los pods en un clúster de Kubernetes. El primero usa el Descheduler para Kubernetes. El Descheduler ayuda a mantener la distribución de los pods al aplicar estrategias para eliminar los pods que infrinjan las restricciones de distribución topológica o las reglas de antiafinidad. El segundo enfoque utiliza la función de consolidación y empaquetado de contenedores de Karpenter. La consolidación evalúa y optimiza continuamente el uso de los recursos al consolidar las cargas de trabajo en un menor número de nodos agrupados de manera más eficiente.

Le recomendamos que utilice Descheduler si no utiliza Karpenter. Si usa Karpenter y Cluster Autoscaler juntos, puede usar Descheduler con Cluster Autoscaler para grupos de nodos.

Descheduler para nodos sin grupo

No hay garantía de que se cumplan las restricciones topológicas cuando se eliminen los pods. Por ejemplo, reducir la escala de una implementación podría provocar un desequilibrio en la distribución de los módulos. Sin embargo, dado que Kubernetes utiliza las restricciones de dispersión de la topología de los pods solo en la fase de programación, los pods quedan desequilibrados en todo el dominio del error.

Para mantener una distribución de pods equilibrada en estos escenarios, puedes usar Descheduler for Kubernetes. Descheduler es una herramienta útil para múltiples propósitos, como hacer cumplir la edad máxima o el tiempo de vida (TTL) de los pods o mejorar el uso de la infraestructura. En el contexto de la resiliencia y la alta disponibilidad (HA), considere las siguientes estrategias de Descheduler:

Función de consolidación y empaquetado de contenedores de Karpenter

En el caso de las cargas de trabajo que utilizan Karpenter, puede utilizar la funcionalidad de consolidación y empaquetado de contenedores para optimizar la utilización de los recursos y reducir los costes en los clústeres de Kubernetes. Karpenter evalúa continuamente la ubicación de los módulos y la utilización de los nodos, e intenta consolidar las cargas de trabajo en un menor número de nodos agrupados de forma más eficiente siempre que sea posible. Este proceso implica analizar los requisitos de recursos, tener en cuenta las limitaciones, como las reglas de afinidad de los módulos, y el posible traslado de los módulos entre nodos para mejorar la eficiencia general del clúster. El código siguiente proporciona un ejemplo:

apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: name: default spec: disruption: consolidationPolicy: WhenUnderutilized expireAfter: 720h

ParaconsolidationPolicy, puede usar WhenUnderutilized oWhenEmpty:

  • Si consolidationPolicy se establece enWhenUnderutilized, Karpenter considera todos los nodos para su consolidación. Cuando Karpenter descubre un nodo vacío o infrautilizado, intenta quitarlo o reemplazarlo para reducir los costes.

  • Cuando consolidationPolicy se establece enWhenEmpty, Karpenter solo considera para la consolidación los nodos que no contienen módulos de carga de trabajo.

Las decisiones de consolidación de Karpenter no se basan únicamente en los porcentajes de utilización de la CPU o la memoria que pueden observarse en las herramientas de supervisión. En su lugar, Karpenter utiliza un algoritmo más complejo basado en las solicitudes de recursos de los módulos y en las posibles optimizaciones de costes. Para obtener más información, consulte la documentación de Karpenter.