Charges de travail - Amazon EKS

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Charges de travail

Les charges de travail ont un impact sur la taille que peut atteindre votre cluster. Les charges de travail qui utilisent APIs fortement Kubernetes limitent le nombre total de charges de travail que vous pouvez avoir dans un seul cluster, mais vous pouvez modifier certaines valeurs par défaut pour réduire la charge.

Les charges de travail d'un cluster Kubernetes ont accès à des fonctionnalités intégrées à l'API Kubernetes (par exemple, Secrets et ServiceAccounts), mais ces fonctionnalités ne sont pas toujours obligatoires et doivent être désactivées si elles ne sont pas utilisées. La limitation de l'accès aux charges de travail et de la dépendance à l'égard du plan de contrôle Kubernetes augmentera le nombre de charges de travail que vous pouvez exécuter dans le cluster et améliorera la sécurité de vos clusters en supprimant les accès inutiles aux charges de travail et en mettant en œuvre les pratiques du moindre privilège. Consultez les meilleures pratiques en matière de sécurité pour plus d'informations.

Utilisation IPv6 pour la mise en réseau des pods

Vous ne pouvez pas passer d'un VPC IPv4 à un VPC. IPv6 Il est donc important de l'activer IPv6 avant de provisionner un cluster. Si vous l'activez IPv6 dans un VPC, cela ne signifie pas que vous devez l'utiliser et si vos pods et services l'utilisent, IPv6 vous pouvez toujours acheminer le trafic vers et depuis IPv4 les adresses. Consultez les meilleures pratiques de mise en réseau EKS pour plus d'informations.

L'utilisation IPv6 dans votre cluster permet d'éviter certaines des limites de dimensionnement des clusters et de la charge de travail les plus courantes. IPv6 évite l'épuisement des adresses IP lorsque les pods et les nœuds ne peuvent pas être créés car aucune adresse IP n'est disponible. Il présente également des améliorations des performances par nœud, car les pods reçoivent les adresses IP plus rapidement en réduisant le nombre de pièces jointes ENI par nœud. Vous pouvez obtenir des performances de nœud similaires en utilisant le mode IPv4 préfixe dans le VPC CNI, mais vous devez tout de même vous assurer que vous disposez de suffisamment d'adresses IP disponibles dans le VPC.

Limiter le nombre de services par espace de noms

Le nombre maximum de services dans un espace de noms est de 5 000 et le nombre maximum de services dans un cluster est de 10 000. Pour aider à organiser les charges de travail et les services, à améliorer les performances et à éviter un impact en cascade sur les ressources limitées aux espaces de noms, nous recommandons de limiter le nombre de services par espace de noms à 500.

Le nombre de règles de tables IP créées par nœud avec kube-proxy augmente avec le nombre total de services dans le cluster. La génération de milliers de règles de tables IP et le routage de paquets via ces règles ont un impact sur les performances des nœuds et augmentent la latence du réseau.

Créez des espaces de noms Kubernetes qui englobent un seul environnement d'application tant que le nombre de services par espace de noms est inférieur à 500. Cela permettra de réduire la taille de la découverte de services pour éviter les limites de découverte de services et peut également vous aider à éviter les collisions de noms de services. Les environnements d'applications (par exemple dev, test, prod) doivent utiliser des clusters EKS distincts au lieu d'espaces de noms.

Comprendre les quotas d'Elastic Load Balancer

Lors de la création de vos services, réfléchissez au type d'équilibrage de charge que vous utiliserez (par exemple, Network Load Balancer (NLB) ou Application Load Balancer (ALB)). Chaque type d'équilibreur de charge fournit des fonctionnalités différentes et possède des quotas différents. Certains quotas par défaut peuvent être ajustés, mais certains quotas maximaux ne peuvent pas être modifiés. Pour consulter les quotas et l'utilisation de votre compte, consultez le tableau de bord des Quotas de Service dans la console AWS.

Par exemple, les cibles ALB par défaut sont 1000. Si votre service compte plus de 1 000 points de terminaison, vous devrez augmenter le quota, diviser le service en plusieurs ALBs ou utiliser Kubernetes Ingress. Les cibles NLB par défaut sont de 3 000, mais elles sont limitées à 500 cibles par AZ. Si votre cluster gère plus de 500 pods pour un service NLB, vous devrez en utiliser plusieurs AZs ou demander une augmentation de la limite de quota.

Une alternative à l'utilisation d'un équilibreur de charge couplé à un service consiste à utiliser un contrôleur d'entrée. Le contrôleur AWS Load Balancer peut créer des ressources ALBs d'entrée, mais vous pouvez envisager d'exécuter un contrôleur dédié dans votre cluster. Un contrôleur d'entrée intégré au cluster vous permet d'exposer plusieurs services Kubernetes à partir d'un seul équilibreur de charge en exécutant un proxy inverse au sein de votre cluster. Les contrôleurs possèdent différentes fonctionnalités, telles que la prise en charge de l'API Gateway, qui peuvent présenter des avantages en fonction du nombre et de l'ampleur de vos charges de travail.

Utilisez Route 53, Global Accelerator ou CloudFront

Pour qu'un service utilisant plusieurs équilibreurs de charge soit disponible en tant que point de terminaison unique, vous devez utiliser Amazon CloudFront, AWS Global Accelerator ou Amazon Route 53 pour exposer tous les équilibreurs de charge en tant que point de terminaison unique destiné au client. Chaque option présente des avantages différents et peut être utilisée séparément ou conjointement en fonction de vos besoins.

La Route 53 peut exposer plusieurs équilibreurs de charge sous un nom commun et peut envoyer du trafic vers chacun d'entre eux en fonction du poids attribué. Pour en savoir plus sur les poids DNS, consultez la documentation et découvrez comment les implémenter avec le contrôleur DNS externe Kubernetes dans la documentation d'AWS Load Balancer Controller.

Global Accelerator peut acheminer les charges de travail vers la région la plus proche en fonction de l'adresse IP de la demande. Cela peut être utile pour les charges de travail déployées dans plusieurs régions, mais cela n'améliore pas le routage vers un seul cluster dans une seule région. L'utilisation de Route 53 en combinaison avec le Global Accelerator présente des avantages supplémentaires tels que la vérification de l'état de santé et le basculement automatique en cas d'absence d'AZ. Vous pouvez voir un exemple d'utilisation de Global Accelerator avec Route 53 dans ce billet de blog.

CloudFront peut être utilisé avec Route 53 et Global Accelerator ou seul pour acheminer le trafic vers plusieurs destinations. CloudFront met en cache les actifs servis depuis les sources d'origine, ce qui peut réduire les besoins en bande passante en fonction de ce que vous servez.

À utiliser à la EndpointSlices place des points de terminaison

Lorsque vous découvrez des pods correspondant à une étiquette de service, vous devez les utiliser à la EndpointSlicesplace des endpoints. Les endpoints étaient un moyen simple d'exposer des services à petite échelle, mais les services volumineux qui évoluent automatiquement ou qui sont mis à jour génèrent un trafic important sur le plan de contrôle Kubernetes. EndpointSlices ont un regroupement automatique qui active des éléments tels que des indications tenant compte de la topologie.

Toutes les manettes ne sont pas utilisées EndpointSlices par défaut. Vous devez vérifier les paramètres de votre manette et l'activer si nécessaire. Pour le contrôleur AWS Load Balancer, vous devez activer l'indicateur --enable-endpoint-slices facultatif à utiliser. EndpointSlices

Utilisez des secrets immuables et externes si possible

Le kubelet conserve un cache des clés et des valeurs actuelles pour les secrets utilisés dans les volumes destinés aux pods de ce nœud. Le kubelet surveille les secrets pour détecter les changements. À mesure que le cluster évolue, le nombre croissant de montres peut avoir un impact négatif sur les performances du serveur d'API.

Il existe deux stratégies pour réduire le nombre de montres sur Secrets :

  • Pour les applications qui n'ont pas besoin d'accéder aux ressources Kubernetes, vous pouvez désactiver le montage automatique des secrets des comptes de service en définissant Token : false automountServiceAccount

  • Si les secrets de votre application sont statiques et ne seront pas modifiés à l'avenir, marquez-les comme immuables. Le kubelet ne surveille pas l'API pour détecter les secrets immuables.

Pour désactiver le montage automatique d'un compte de service sur les pods, vous pouvez utiliser le paramètre suivant dans votre charge de travail. Vous pouvez annuler ces paramètres si des charges de travail spécifiques nécessitent un compte de service.

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

Surveillez le nombre de secrets du cluster avant qu'il ne dépasse la limite de 10 000. Vous pouvez voir le nombre total de secrets dans un cluster à l'aide de la commande suivante. Vous devez surveiller cette limite à l'aide de vos outils de surveillance du cluster.

kubectl get secrets -A | wc -l

Vous devez configurer la surveillance pour alerter un administrateur du cluster avant que cette limite ne soit atteinte. Envisagez d'utiliser des options de gestion des secrets externes telles qu'AWS Key Management Service (AWS KMS) ou Hashicorp Vault avec le pilote CSI Secrets Store.

Historique des déploiements limités

Les pods peuvent être lents lors de la création, de la mise à jour ou de la suppression, car les anciens objets sont toujours suivis dans le cluster. Vous pouvez réduire le nombre revisionHistoryLimit de déploiements pour nettoyer les anciens, ReplicaSets ce qui réduira le nombre total d'objets suivis par le Kubernetes Controller Manager. La limite d'historique par défaut pour les déploiements en 10.

Si votre cluster crée de nombreux objets de travail par le biais de mécanismes CronJobs ou d'autres mécanismes, vous devez utiliser le ttlSecondsAfterFinishedparamètre pour nettoyer automatiquement les anciens modules du cluster. Cela supprimera les tâches exécutées avec succès de l'historique des tâches après un laps de temps spécifié.

Lorsqu'un pod s'exécute sur un nœud, le kubelet ajoute un ensemble de variables d'environnement pour chaque service actif. Les processus Linux ont une taille maximale pour leur environnement, qui peut être atteinte si vous avez trop de services dans votre espace de noms. Le nombre de services par espace de noms ne doit pas dépasser 5 000. Ensuite, le nombre de variables d'environnement de service dépasse les limites du shell, ce qui entraîne le blocage des Pods au démarrage.

Il existe d'autres raisons pour lesquelles les pods ne devraient pas utiliser de variables d'environnement de service pour la découverte de services. Les conflits de noms de variables d'environnement, les noms de service divulgués et la taille totale de l'environnement en sont quelques exemples. Vous devez utiliser CoreDNS pour découvrir les points de terminaison de service.

Limiter les webhooks d'admission dynamique par ressource

Les webhooks d'admission dynamiques incluent les webhooks d'admission et les webhooks mutants. Il s'agit de points de terminaison d'API ne faisant pas partie du plan de contrôle Kubernetes qui sont appelés en séquence lorsqu'une ressource est envoyée à l'API Kubernetes. Chaque webhook a un délai d'expiration par défaut de 10 secondes et peut augmenter la durée d'une demande d'API si vous avez plusieurs webhooks ou si l'un d'entre eux expire.

Assurez-vous que vos webhooks sont hautement disponibles, en particulier lors d'un incident AZ, et que la FailurePolicy est correctement définie pour rejeter la ressource ou ignorer l'échec. N'appelez pas de webhook lorsque vous n'en avez pas besoin en autorisant les commandes kubectl --dry-run à contourner le webhook.

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

Les webhooks mutants peuvent modifier les ressources en succession fréquente. Si vous avez 5 webhooks mutants et que vous déployez 50 ressources, etcd stockera toutes les versions de chaque ressource jusqu'à ce que le compactage s'exécute (toutes les 5 minutes) afin de supprimer les anciennes versions des ressources modifiées. Dans ce scénario, lorsqu'etcd supprime les ressources remplacées, 200 versions de ressources seront supprimées d'etcd et, en fonction de la taille des ressources, cela peut utiliser un espace considérable sur l'hôte etcd jusqu'à ce que la défragmentation s'exécute toutes les 15 minutes.

Cette défragmentation peut provoquer des pauses dans etcd, ce qui pourrait avoir d'autres effets sur l'API et les contrôleurs Kubernetes. Vous devez éviter de modifier fréquemment de grandes ressources ou de modifier des centaines de ressources en succession rapide.

Comparez les charges de travail entre plusieurs clusters

Si vous avez deux clusters qui devraient avoir des performances similaires, mais ce n'est pas le cas, essayez de comparer les indicateurs pour en déterminer la raison.

Par exemple, la comparaison de la latence d'un cluster est un problème courant. Cela est généralement dû à une différence dans le volume des demandes d'API. Vous pouvez exécuter la CloudWatch LogInsight requête suivante pour comprendre la différence.

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

Vous pouvez ajouter des filtres supplémentaires pour l'affiner, par exemple en vous concentrant sur toutes les demandes de liste provenant defoo.

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