Chris McGrath, de DoiT, décrypte le Kubernetes AWS LB Controller et son fonctionnement en coulisses.

BLUF
Une convention existe au sein de la communauté Kubernetes : les éléments intégrés nativement à Kubernetes font référence à kubernetes.io dans leur nommage, contrairement aux add-ons. Ces derniers suivent généralement une convention auto-documentée du type ebs.csi.aws.com, qui permet d'identifier intuitivement un add-on. L'add-on aws-load-balancer-controller, lui, déroge à cette convention.
Public visé
Cet article s'adresse à trois publics, chacun avec un objectif distinct :
1. Les administrateurs Kubernetes qui exploitent EKS ou des distributions Kubernetes génériques sur AWS : vous n'avez pas besoin de lire cet article, mais je vous recommande de l'enregistrer dans vos favoris et de garder en tête qu'il peut servir de référence si vous devez un jour déboguer le provisionnement d'AWS Load Balancers via des Services Kubernetes utilisant des annotations du type service.beta.kubernetes.io/aws-load-balancer-*.
2. Les passionnés de Kubernetes qui apprécient les articles de fond pour mieux maîtriser la plateforme.
3. Les mainteneurs d'EKS, d'aws-cloud-controller-manager, d'aws-load-balancer-controller et de la documentation AWS : mon objectif est de mettre en lumière une incohérence déroutante propre au provisionnement de Load Balancers Kubernetes sur AWS. J'espère que cela encouragera un alignement avec les pratiques du reste de la communauté Kubernetes. (Le problème touche plusieurs dépôts git et sites de documentation, il ne se règle donc pas avec quelques merge requests.)
Introduction
J'ai récemment lancé une preuve de concept impliquant le provisionnement d'AWS Load Balancers pour un cluster EKS (Elastic Kubernetes Service), à l'aide de services Kubernetes de type LoadBalancer dotés d'annotations de la forme service.beta.kubernetes.io/aws-load-balancer-*, listées sur cette page.
Au départ, certaines annotations ne fonctionnaient pas comme prévu. J'ai pu les diagnostiquer, mais pour cela il fallait d'abord comprendre l'origine du problème. La documentation de la page liée explique correctement le fonctionnement, mais ses explications restent peu accessibles aux débutants.
Cet article propose donc une analyse approfondie de plusieurs sujets :
- Pourquoi aws-load-balancer-controller prête à confusion
- Le contexte qui aidera les débutants à se mettre à niveau
- Les détails expliquant pourquoi les choses fonctionnent ainsi
- Quelques conseils de dépannage simples mais utiles
- Des pistes pour que les différents groupes de mainteneurs rendent tout cela moins déroutant à l'avenir
Le défi : un cas d'identité confondue
Comme indiqué, je trouve la page liée ci-dessus peu adaptée aux débutants. Pour être clair : le projet m'a paru suffisamment déroutant pour qu'il me faille une journée entière pour le cerner. C'est mauvais signe, sachant que je suis expert Kubernetes depuis juillet 2018. Une fois la lumière faite, ma première pensée a été : " Ah, voilà ce qui se passe. TIL (Today I learned) — il existe deux contrôleurs Kubernetes spécifiques à AWS qui peuvent finir par exploiter des annotations attachées à des Services Kubernetes de type Load Balancer pour provisionner et gérer des LBs AWS. " Ma deuxième pensée a été : " Eh bien… comment les autres sont-ils censés s'en sortir sans expert sous la main ? Je devrais écrire un article là-dessus. "
Voici la liste des éléments qui rendent le projet AWS Load Balancer Controller déroutant :
1.) Cela ressemble à une fonctionnalité officielle native, mais ce n'en est pas une !
Lors d'une recherche Google sur " aws service of type lb "
Le premier résultat : docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html
Le deuxième résultat : kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/service/annotations/
Et la section pertinente de la documentation officielle Kubernetes, qui apparaît en premier résultat lorsque vous recherchez " kubernetes service of type loadbalancer "
https://kubernetes.io/docs/concepts/services-networking/service/
Ces trois pages ressemblent toutes à de la documentation officielle, et toutes semblent traiter du même sujet, puisque les mêmes annotations y figurent.
Si vous y faites un Ctrl+F sur :
service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags
La même ressource apparaît sur les trois pages. Au premier coup d'œil, on a donc l'impression que les trois sites parlent de la même chose.
En réalité, aws-load-balancer-controller est un add-on Kubernetes qui étend les fonctionnalités natives. Deux des liens ci-dessus traitent donc des fonctionnalités natives, et le troisième concerne un add-on destiné à offrir des fonctionnalités étendues.
2.) La convention de nommage employée par le site et les annotations du projet est très peu intuitive. Elle laisse croire que les annotations renvoient à une fonctionnalité native :
2A.) Le nom de domaine qui héberge la documentation du projet est kubernetes-sigs.github.io
ce qui donne l'impression d'une fonctionnalité Kubernetes native.
2B.) Les annotations de l'add-on font référence à service.beta.kubernetes.io, un espace habituellement réservé aux fonctionnalités natives.
3.) La page d'accueil du site de documentation du projet ne précise pas immédiatement qu'il s'agit d'un add-on Kubernetes destiné à étendre les fonctionnalités natives.
Ce n'est qu'en arrivant en bas de la deuxième page de la documentation
et en apercevant helm install aws-load-balancer-controller que le déclic se fait : " Ahhh ! C'est un add-on, ok, ça a du sens. "
4.) Le pattern utilisé par l'API n'est pas cohérent avec celui adopté par l'ensemble de la communauté Kubernetes :
Prenons Cert Manager et le pilote EBS Volume CSI (Container Storage Interface) comme exemples de patterns standards :
- Dans la documentation de cert-manager, 95 % des annotations utilisent
cert-manager.io. On comprend donc intuitivement, d'un coup d'œil, que les annotations renvoient à un add-on tiers. - La première phrase de la page d'accueil de la documentation est : " cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters… ". Cela précise d'emblée que le projet est une extension qui ajoute des fonctionnalités.
- Pour le pilote EBS Volume CSI, la convention de nommage permet de distinguer clairement et intuitivement, d'un coup d'œil, qu'il diffère de la fonctionnalité native.
La classe de stockage AWS native utilise provisioner: kubernetes.io/aws-ebs
La classe de stockage de l'add-on EBS utilise provisioner: ebs.csi.aws.com
- Il est très courant que les pages d'accueil des différents sites de documentation EBS CSI répètent d'emblée qu'il s'agit d'un add-on non installé par défaut. La documentation de ce projet va jusqu'à inclure délibérément le mot-clé " driver " pour rendre cela plus intuitif : " The Amazon EBS CSI driver isn't installed when you first create a cluster. To use the driver, you must add it as an Amazon EKS add-on or as a self-managed add-on. " Et au cas où certains arriveraient sur la page GitHub plutôt que sur la documentation, même la page d'accueil GitHub du projet contient un lien vers " Driver Installation "
5.) L'interface et la documentation d'AWS sont elles aussi incohérentes au sujet d'aws-load-balancer-controller :
AWS Load Balancer Controller dispose d'un guide utilisateur sur docs.aws.amazon.com intitulé " Installing the AWS Load Balancer Controller add-on "
Mais dans l'interface graphique, il n'apparaît pas comme un add-on officiel, même lorsque vous cliquez sur Get more add-ons et que vous voyez Amazon EBS CSI Driver et AWS Distro for OpenTelemetry

6.) Le projet manque de contexte
La page consacrée aux annotations de service mentionne brièvement deux notions à la fois utiles à comprendre (puisque la compréhension facilite le dépannage) et quasi impossibles à appréhender pour un nouveau venu sans explication supplémentaire. Si vous tentez une recherche Google sur ces sujets, les informations trouvées seront très vagues, fragmentées et apparemment contradictoires, à moins de savoir capter de nombreuses nuances.
Les deux notions auxquelles je fais référence, brièvement mentionnées sans explication dans la documentation, sont :
1. " in-tree " : " the k8s in-tree kube-controller-manager "
2. " Legacy AWS Cloud Provider " : " The AWS Load Balancer Controller manages Kubernetes Services in a compatible way with the legacy aws cloud provider. "
Dans un monde idéal, on trouverait une définition synthétique et un lien vers une lecture complémentaire pour les curieux. Voici comment je les résumerais : techniquement, ce sont deux choses différentes, mais autant les considérer comme une seule. Le Legacy AWS Cloud Provider fournit la fonctionnalité native par défaut de provisionnement des services de type Load Balancer pour les clusters Kubernetes exécutés sur AWS.
Contexte de fond
Quand je dépanne quelque chose, la première étape est toujours de chercher à comprendre. Le sujet du provisionnement des LBs AWS exige beaucoup de contexte pour être pleinement saisi. Malheureusement, jusqu'à aujourd'hui, ces informations étaient dispersées, jamais explorées en profondeur, et truffées de nuances qui en compliquent la compréhension. Voici ma tentative de consolider quelques éléments clés et de les rendre accessibles.
Contexte des sujets clés :
1.) kube-controller-manager vs cloud-controller-manager vs aws-cloud-controller-manager
Les notions " in-tree " et " Legacy AWS Cloud Provider " comportent des nuances difficiles à saisir sans connaître le contexte autour de ces sujets connexes. Commençons donc par là.
Auparavant, Kubernetes comptait quatre composants de control plane : controller-manager, scheduler, api-server et etcd. On exécutait soit kube-controller-manager, soit cloud-controller-manager, mais pas les deux.
Le cloud-controller-manager était l'option utilisée 95 % du temps. Il offrait les mêmes fonctionnalités que kube-controller-manager, plus une prise en charge native pour s'interfacer avec plusieurs API CSP (Cloud Service Provider). Comme il savait dialoguer avec les API CSP, il pouvait par exemple provisionner des volumes AWS EBS et des AWS Load Balancers.
Le kube-controller-manager, lui, est une implémentation cloud-agnostic ; il lui manque donc la capacité native d'auto-provisionner du stockage CSP ou des Load Balancers CSP.
Aujourd'hui, Kubernetes compte normalement cinq composants de control plane :
etcd, kube-api-server, kube-scheduler, kube-controller-manager et un controller manager spécifique au CSP comme aws-cloud-controller-manager. Les diagrammes de la documentation officielle Kubernetes ont été mis à jour pour refléter cette nouvelle architecture. Vous pouvez aussi le vérifier avec des méthodes de déploiement comme kops ou kubeadm, qui exposent le control plane. Le principal changement, c'est que vous disposez désormais de cloud controller managers dédiés à un seul fournisseur cloud, conçus pour s'exécuter aux côtés de kube-controller-manager. Le cloud-controller-manager d'origine, lui, relevait davantage d'une solution universelle tout-en-un.
2.) " In-tree " fait référence à l'époque où les bibliothèques Go Lang capables de s'interfacer avec plusieurs API CSP se trouvaient dans le dépôt Kubernetes pour construire une image de conteneur Universal Kubernetes Cloud Controller Manager :
In-tree : code qui réside dans le dépôt principal Kubernetes k8s.io/kubernetes.
Out-of-tree : code qui réside dans un dépôt externe en dehors du dépôt git k8s.io/kubernetes.
La base de code de Kubernetes 1.14 intégrait nativement des API pour 8 CSP différents. D'autres souhaitaient être ajoutés, et leur regroupement impliquait qu'ils devaient tous atteindre la stabilité simultanément pour une release. Un pattern intenable du point de vue de la maintenabilité. Pour résoudre le problème, une KEP (Kubernetes Enhancement Proposal) a été approuvée. Elle proposait que la fonctionnalité CSP soit découplée de Kubernetes et refactorisée en add-ons.
Ce découplage simplifierait le processus de release de Kubernetes et permettrait aux fournisseurs cloud de publier fonctionnalités et correctifs indépendamment du cycle de release et des processus de Kubernetes. Une décision visant à rembourser la dette technique afin d'assurer la santé du projet sur le long terme.
3.) Si vous tentez de creuser ce sujet par vous-même, il est facile de tomber sur des informations qui semblent à première vue contradictoires, jusqu'à ce que vous saisissiez plusieurs nuances. En voici quelques-unes, dans le désordre :
- La migration de in-tree vers out-of-tree semble s'étaler sur des années. Beaucoup d'informations laissent aussi entendre qu'elle a démarré il y a longtemps et qu'elle s'est terminée il y a longtemps. Qu'elle a démarré et s'est terminée à différents moments. Et qu'elle est encore en cours.
- J'ai mentionné plus haut que la base de code de Kubernetes 1.14 intégrait des API pour huit CSP différents.
Si vous regardez la base de code de Kubernetes 1.26, vous verrez encore quatre CSP différents in-tree. AWS apparaît toujours dans la liste des CSP in-tree. Mais il existe un dépôt git out-of-tree faisant référence à aws-cloud-provider qui laisse entendre qu'AWS a achevé sa migration dès la 1.20.
Mais la KEP suggère que la migration sera terminée vers la version 1.27 ?
C'est typiquement pour ce genre de raison que j'ai préféré écrire un article plutôt que de contribuer à corriger un problème de documentation. Bien qu'AWS et d'autres CSP existent toujours in-tree (dans une version universelle CSP du cloud controller manager), cette version n'est pas celle utilisée en pratique. AWS et les autres CSP utilisent leur propre implémentation dédiée, comme aws-cloud-controller-manager, plutôt que l'ancien cloud-controller-manager universel tout-en-un in-tree.
Les différents CSP achèvent leur migration de l'in-tree universel vers l'out-of-tree spécifique à des rythmes différents. Autre point un peu déroutant : cet effort complexe a été scindé en deux parties. La fonctionnalité native in-tree d'origine incluait la logique de provisionnement du stockage CSP et des LBs CSP. Non seulement elle a été déplacée out-of-tree, mais elle a été davantage découplée, de sorte que les pilotes CSI pour le stockage CSP sont devenus un composant isolé doté de ses propres calendriers de migration.
- Quand on prend conscience de l'ampleur de la complexité de ce refactor, certaines choses prennent du sens. D'abord, il n'est pas étonnant qu'il ait pris plus de 4 ans. Les implémentations out-of-tree des fournisseurs cloud ont atteint le statut bêta dans la version 1.11, en mai 2019. Ensuite, lorsqu'on réalise que plusieurs feature freezes ont été instaurés pour soutenir le processus de migration, on comprend mieux pourquoi des bugs comme ceux liés à
ExternalTrafficPolicy: Localsur les LBs AWS ont mis des années à être corrigés. Cela explique aussi pourquoi la logique native de provisionnement des LBs AWS n'a pas connu beaucoup d'évolutions fonctionnelles ces dernières années.
4.) " Legacy AWS Cloud Provider " désigne en gros la fonctionnalité par défaut de provisionnement de load balancer accessible dans une installation par défaut d'EKS ou de Kubernetes sur AWS.
Quelques nuances empêchent cette affirmation d'être exacte à 100 %, mais elle reste suffisamment proche de la vérité pour être utile.
Voici ces nuances :
- Legacy AWS Cloud Provider peut désigner la logique spécifique à AWS qui existait in-tree, dans le cloud-controller-manager (CSP universel), capable de provisionner des volumes AWS EBS et des LBs AWS.
- Legacy AWS Cloud Provider peut aussi désigner la logique par défaut de provisionnement de load balancer présente dans aws-cloud-controller-manager.
- aws-cloud-controller-manager est souvent invisible pour les utilisateurs.
– Sous EKS, aws-cloud-controller-manager s'exécute sur des master nodes managés invisibles pour vous.
– Sous kops ou kubeadm, qui utilisent des master nodes auto-hébergés, vous le verrez.
– Sous RKE2, vous ne le verrez pas en raison de certains choix d'implémentation de sécurité en défense en profondeur, qui font tourner certains composants du control plane comme des processus isolés de Kubernetes.
- Legacy AWS Cloud Provider peut désigner deux choses différentes, mais dans le contexte des LBs AWS, elles reviennent au même puisqu'elles prennent en charge les mêmes annotations. Vous pouvez retrouver les 22 annotations d'origine en cherchant la chaîne
const ServiceAnnotationLoadBalancersur cette page. À noter qu'au moment où j'écris ces lignes, une recherche de la chaîneservice.beta.kubernetes.io/aws-load-balancersur la page de documentation ne retourne que 21 annotations. Ce n'est qu'un problème de documentation, pas un changement de code.
Voici la liste des 22 annotations accessibles par défaut :
service.beta.kubernetes.io/aws-load-balancer-typeservice.beta.kubernetes.io/aws-load-balancer-internalservice.beta.kubernetes.io/aws-load-balancer-proxy-protocolservice.beta.kubernetes.io/aws-load-balancer-access-log-emit-intervalservice.beta.kubernetes.io/aws-load-balancer-access-log-enabledservice.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-nameservice.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefixservice.beta.kubernetes.io/aws-load-balancer-connection-draining-enabledservice.beta.kubernetes.io/aws-load-balancer-connection-draining-timeoutservice.beta.kubernetes.io/aws-load-balancer-connection-idle-timeoutservice.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabledservice.beta.kubernetes.io/aws-load-balancer-extra-security-groupsservice.beta.kubernetes.io/aws-load-balancer-security-groupsservice.beta.kubernetes.io/aws-load-balancer-ssl-certservice.beta.kubernetes.io/aws-load-balancer-ssl-portsservice.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policyservice.beta.kubernetes.io/aws-load-balancer-backend-protocolservice.beta.kubernetes.io/aws-load-balancer-additional-resource-tagsservice.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-thresholdservice.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-thresholdservice.beta.kubernetes.io/aws-load-balancer-healthcheck-timeoutservice.beta.kubernetes.io/aws-load-balancer-healthcheck-interval5.) Le projet AWS Load Balancer Controller est conceptuellement proche du projet AWS EBS CSI Driver :
Tous deux résultent du découplage de la logique du contrôleur Kubernetes qui résidait auparavant in-tree dans le cloud-controller-manager universel tout-en-un. Tous deux poursuivaient l'objectif commun d'assurer la rétrocompatibilité. Je me demande si cela a pesé dans la décision de réutiliser certaines annotations.
6.) Les projets EBS CSI Driver Add-on et AWS LB Controller Add-on ont été lancés par des équipes différentes.
Le projet EBS CSI Driver Add-on a été lancé par AWS. Le projet AWS LB Controller Add-on a été lancé à l'origine par Ticketmaster et CoreOS, et était autrefois connu sous le nom d'" AWS ALB Ingress Controller ". Il a été cédé à Kubernetes SIG-AWS en 2018. À l'origine, l'ALB Ingress Controller se décrivait surtout comme un Application Load Balancer Controller. Au fil du temps, le périmètre du projet s'est élargi pour inclure aussi le contrôle des NLBs. En juillet 2021, il a donc été rebaptisé " AWS Load Balancer Controller ".
Pourquoi en est-on arrivé là ?
Si la logique du cloud-controller-manager universel tout-en-un n'avait pas été migrée out-of-tree dans des add-ons externes découplés, la dette technique aurait ralenti durablement tout le développement futur des fonctionnalités et la correction des bugs. Je me souviens d'une époque où les bugs liés à externalTrafficPolicy: local revenaient sans cesse et mettaient des années à être correctement corrigés. Maintenant que la logique est découplée du code, du processus de release et des tests du projet officiel Kubernetes, les bugs sont corrigés en quelques mois plutôt qu'en années, et les demandes de fonctionnalités peuvent à nouveau être étudiées.
Un développement plus rapide a permis de belles avancées, comme le fait de rendre le concept de Software Defined Perimeter via proxy Authn/z plus simple à mettre en œuvre, grâce à la nouvelle intégration d'AWS Cognito avec la logique de provisionnement ALB. Le projet AWS LB Controller offre aussi davantage d'options pour le provisionnement des NLBs via des annotations. Une nouveauté que j'apprécie particulièrement : l'annotation service.beta.kubernetes.io/aws-load-balancer-nlb-target-type:, qui permet de choisir comment router le trafic vers les pods backend. La valeur par défaut "instance" fait passer le trafic de nELB -> NodePort -> service Kube -> Pod. Une nouvelle valeur "ip" permet au trafic d'aller de nELB -> Pod, comme le fait l'aELB.
Référence abrégée :
nELB = network Elastic Load Balancer (LB L4 en tant que service)
aELB/ALB = application Elastic Load Balancer (LB L7 en tant que service)
cELB = classic Elastic Load Balancer (LB L4/L7 en tant que service)
Je soupçonne que si la gestion des nELBs a fini par s'inviter dans le projet anciennement appelé ALB Ingress Controller, c'est parce que ce dernier était sans doute plus ouvert aux changements et aux nouveautés à une époque où aws-cloud-controller-manager était soumis à un feature freeze pour faciliter la migration in-tree.
Quant à savoir pourquoi AWS Load Balancer Controller ne ressemble pas davantage à AWS EBS CSI Driver Add-on, je pense que cela tient au fait qu'AWS a piloté le projet EBS CSI du début à la fin. Le projet LB Controller, lui, a été adopté en cours de route, et les grandes organisations ont tendance à mettre en œuvre les changements lentement, en raison de la loi de Brooks. (La surcharge de communication dans les grandes organisations ralentit considérablement les changements.)
Conseils de dépannage pour AWS LB Controller
Ces conseils ne se veulent ni complets ni exhaustifs. Ils visent simplement à vous débloquer et à vous orienter vers des sujets pertinents pour des recherches complémentaires.
1.) Vérifiez si AWS LB Controller est installé
kubectl get deployments --namespace=kube-system
C'est important, car cela peut entraîner des changements significatifs de comportement. Si vous avez deux clusters avec 99 % des mêmes workloads YAML et de la même configuration déployés, et que la différence de 1 % entre eux tient à la présence ou non d'AWS LB Controller, ces 99 % de YAML similaires peuvent produire des résultats différents.
2.) Envisagez sérieusement de passer à la dernière version
La commande suivante vous permet de voir quelle version vous exécutez
kubectl get deploy aws-load-balancer-controller -n=kube-system -o yaml | grep image:
image: public.ecr.aws/eks/aws-load-balancer-controller:v2.4.6
Voici un cas concret récent où la pratique consistant à rester à jour s'est avérée précieuse :
EKS 1.21 a atteint sa fin de vie le 15 février 2023. Quelques utilisateurs d'AWS LB Controller ont subi des interruptions, jusqu'à ce qu'ils passent de 2.3.x à 2.4.x. Ces interruptions étaient dues à la mise à niveau de Kubernetes 1.21 vers 1.22, qui a supprimé de nombreuses API obsolètes. AWS LB Controller 2.4.x prend en charge la nouvelle API Ingress networking.k8s.io/v1. La 2.3.x ne prend en charge que l'ancienne API networking.k8s.io/v1beta1, supprimée de Kubernetes 1.22. Les tickets d'issues du projet aws-lb-controller ont anticipé ce problème et fait en sorte que les versions 2.4.x fonctionnent avec Kubernetes 1.19++, laissant ainsi aux organisations le temps de migrer. Celles qui suivent la bonne pratique de maintenir leurs add-ons à jour ont évité les interruptions. Les autres, qui se contentent du minimum de maintenance, ont sans doute rencontré ce problème après avoir fini par mettre Kubernetes à jour pour rester sur une release supportée.
3.) Lisez attentivement toute la documentation d'installation de bout en bout : il est facile de passer à côté de certaines exigences :
En plus d'installer aws-load-balancer-controller dans le namespace kube-system et de configurer correctement les rôles IAM, vous devez aussi taguer correctement les sous-réseaux du VPC.
# Extrait de configuration Terraform VPC en tant que codemodule vpc { ... public_subnet_tags = { "kubernetes.io/role/elb" = "1" } private_subnet_tags = { "kubernetes.io/role/internal-elb" = "1" }}
/*Information contextuelle complémentaire :Si vous consultez la documentation EKShttps://aws.amazon.com/premiumsupport/knowledge-center/eks-load-balancer-controller-subnets/Vous y verrez une référence à"kubernetes.io/cluster/${local.cluster_name}" = "shared"Ce tag était requis par les anciennes versions d'aws-load-balancer-controller*/4.) Pour déboguer un objet ingress, vérifiez quelles Ingressclasses sont installées
kubectl get ingressclass
Si vous en voyez plus d'une, exécutez kubectl describe ingressclass pour voir si l'une d'elles porte une annotation la marquant comme celle par défaut.
Si l'ingress class alb n'est pas marquée comme celle par défaut, indiquez explicitement l'ingress class souhaitée sur l'objet ingress que vous tentez de déboguer.
5. Pour déboguer des annotations de provisionnement de LB spécifiques aux objets service, les choses se compliquent un peu… Voici en quoi :
Vous auriez en pratique deux contrôleurs différents s'exécutant simultanément dans le même cluster.
Sous EKS, comme il s'agit d'un service managé avec des Master Nodes Kubernetes managés, vous ne pouvez voir visuellement qu'un seul des deux contrôleurs. (Vous ne verrez pas aws-cloud-controller-manager, puisqu'il s'exécute sur les master nodes managés.)
Les deux contrôleurs présentent de larges chevauchements en termes de fonctionnalités et d'objets dont ils sont responsables :
– aws-cloud-controller-manager : provisionne des cELBs et des nELBs
– aws-load-balancer-controller : provisionne des aELBs et des nELBs
5A.) Identifiez quel contrôleur gère activement votre objet service Kubernetes.
Selon cette documentation, si vous annotez un service Kubernetes avec l'une de ces options :
service.beta.kubernetes.io/aws-load-balancer-type: nlb-ip
service.beta.kubernetes.io/aws-load-balancer-type: external
Alors le contrôleur aws-cloud-controller-manager ignorera l'objet pour qu'aws-load-balancer-controller puisse le gérer.
5B.) Si aws-load-balancer-controller gère un service, kubectl describe service devient utile !
Beaucoup de ceux qui ont essayé des options avancées de LB ont sans doute déjà rencontré un cas où le LB reste bloqué en statut pending et refuse de se provisionner. Imaginons que vous exécutiez kubectl describe service $NAME pour le déboguer. Si Legacy AWS Controller Manager gère le service, vous obtiendrez sans doute un message d'erreur sans utilité. Si c'est aws-load-balancer-controller qui le gère, vous obtiendrez bel et bien des messages d'erreur utiles au débogage. (Ils signalent très bien si vous avez raté une étape d'installation, comme des droits IAM manquants ou la partie sur le tagging des sous-réseaux.)
5C.) Parcourez les notes de version pour repérer les changements à prendre en compte :
- aws-cloud-controller-manager provisionne par défaut des LBs avec des IPs publiques. Vous devez ajouter de la configuration pour provisionner des IPs privées. C'est l'inverse pour aws-load-balancer-controller. (depuis la v2.2.0)
- aws-cloud-controller-manager provisionne par défaut des cELBs. aws-load-balancer-controller provisionne par défaut des nELBs (pour tout service annoté avec
service.beta.kubernetes.io/aws-load-balancer-type: external, puisque c'est ce qui détermine quel contrôleur est aux commandes). - Les images de conteneurs d'aws-cloud-controller-manager étaient auparavant disponibles sur Docker Hub, mais à partir de la v2.4.6, elles ne seront plus hébergées que sur le registre de conteneurs public.ecr.aws.
5D.) La plupart des objets Kubernetes prennent en charge des boucles de réconciliation qui font passer l'état actuel à l'état souhaité. Les contrôleurs de Load Balancer présentent quelques cas particuliers où il faut supprimer puis recréer pour que les changements itératifs prennent effet.
Ce n'est généralement pas nécessaire, mais ça vaut parfois la peine d'essayer. L'annotation du point 5A en est un exemple où la documentation recommande la recréation plutôt que la modification. À noter aussi que les valeurs nlb-ip et external sont propres à AWS LB Controller, le contrôleur Legacy utilisant les valeurs nlb et (vide pour provisionner un cELB). Ce piège peut s'avérer important pour quiconque utilise un contrôleur GitOps comme ArgoCD ou Flux pour des changements itératifs, puisque ceux-ci tendent à mettre à jour les manifestes plutôt qu'à supprimer et recréer les ressources. Si un utilisateur d'ArgoCD ou de Flux teste donc des changements itératifs dans un environnement de dev, il devra peut-être intervenir manuellement dans ce cas particulier pour voir ses changements appliqués.
J'avais deux raisons principales d'écrire cet article. La première était de partager des connaissances : c'est fait. La seconde était d'encourager des changements qui pourraient rendre tout cela moins déroutant. Trois changements, à la portée des mainteneurs du projet et de la documentation, contribueraient grandement à dissiper la confusion. Tous reviennent à rapprocher aws-load-balancer-controller du projet EBS-CSI :
- Ajouter le projet à la liste EKS des add-ons officiels installables via la console AWS.
- Mettre à jour la documentation à plusieurs endroits pour qu'il soit immédiatement évident qu'aws-load-balancer-controller est un add-on.
- Modifier les annotations pour qu'elles ne fassent plus référence à
kubernetes.io, mais ressemblent davantage àebs.csi.aws.com. Le statut d'add-on devient ainsi évident à l'inspection, et l'effet SEO (référencement) améliorerait l'expérience utilisateur lors de la recherche de la documentation pertinente.