Considérations réseaux pour Azure Kubernetes Services (partie 2)

Cet article est la seconde partie d’une série sur le réseau dans AKS. Vous retrouverez la première partie ici.
Dans la première partie, nous avons concentré nos observations sur le control plane d’AKS et les configurations PaaS associées, corollaires de ces considérations réseaux.
Dans ce nouvel article, nous allons nous concentrer sur le worker plane, et regarder également quelques concepts relatifs à l’usage de subnet Azure par AKS.
Considérations réseaux pour le worker plane
Lorsque l’on parle de réseau dans Kubernetes, nous devons réfléchir à comment les pods peuvent communiquer entre eux, ainsi qu’avec le monde extérieur (à Kubernetes).
C’est ici que commencent les discussions sur le Container Network Interface (CNI).
CNI est un standard qui permet aux différents providers de développer leurs solutions et de les brancher par la suite sur Kubernetes.
Il existe de nombreuses solutions de CNI, et nous n’allons pas développer ce sujet aujourd’hui. En revanche, d’un point de vue AKS, il est intéressant de noter que pendant longtemps, nos seules options étaient les suivantes :
- Kubenet
- Azure CNI
Kubenet
Kubenet est la configuration par défaut pour le worker plane. De fait, en utilisant Kubenet, il est possible de passer outre les réflexions d’architecture réseau inhérentes à un autre choix de CNI, et c’est probablement pour cela qu’il s’agit encore aujourd’hui de l’option par défaut.
D’un point de vue technique, AKS avec Kubenet s’appuie sur un concept de NAT (Network Address Translation). Les pods ont leur propre range IP, indépendante du range réseau du Virtual Network.
Avantages de Kubenet
En note positive, ce NAT permet d’avoir un overlay réseau, et donc de considérer uniquement les nodes dans la planification de la taille du Vnet. Par exemple, si l’on prend un subnet avec un CIDR /26, il est possible d’avoir jusqu’à 59 nodes (64 – 5) pour notre cluster AKS, ce qui fait un cluster de taille assez conséquente.

Dans Kubernetes, nous avons 2 ranges réseaux à prévoir :
- le range pour l’adressage des pods
- le range pour les services Kubernetes
Ces deux ranges sont cependant configurés avec des valeurs par défaut :
|
Pod CIDR default value |
Service CIDR default value |
|
10.244.0.0/16 |
10.0.0.0/16 |
Un cluster avec Kubenet sera affiché avec la valeur kubenet pour le network plugin, et l’on pourra également voir affichées les valeurs du pod CIDR et du Service CIDR.

On notera que ces ranges sont privés d’un point de vue Azure, ce qui signifie que l’on peut les utiliser sur d’autres cluster.
Limites de Kubenet
Parlons maintenant des limites de Kubenet.
Toutes les fonctionnalités d’AKS ne sont pas disponibles avec ce plugin réseau, même si l’on a pu observer des ajouts au fur et à mesure de l’évolution du service AKS.
Pour commencer, il y a une limite d’un cluster par subnet. Ensuite, et c’est l’un des points les plus importants, il y a une latence réseau induite par le hop du NAT de Kubenet. Bien qu’il soit difficile d’évaluer cette dite latence, elle est suffisante pour que Microsoft ne recommande pas Kubenet pour des environnements de production.
Si l’on regarde les flux réseaux, pour un trafic entrant vers un workload Kubernetes, ceux-ci vont d’abord aller vers l’un des nodes du cluster, et ensuite vers les pods. Pour parvenir à trouver la route réseau depuis l’extérieur du cluster, une UDR (User Defined Route) sur le subnet AKS est requise. Cette UDR est gérée par le control plane AKS, et mise à jour automatiquement. Elle permet de définir quel node est le next hop pour des sous-ensembles du range réseau des pods, généralement par tranche de /24 pour 1 node.

À des nodes additionnels correspondraient des routes additionnelles.
Enfin, on notera également la non-compatibilité de Kubenet avec des nodes Windows.
En conclusion, pour de meilleures performances ou des containers Windows, il nous faut considérer Azure CNI.
Azure CNI
Pour commencer, un cluster avec Azure CNI n’affichera pas de range pour les pods.

Ceci en raison de la nature même du CNI, qui permet une “meilleure intégration” avec le réseau Azure. On comprendra par « meilleure intégration » que les pods consomment des IPs dans le range du Vnet.

À la place d’un NAT, Azure CNI crée un pont pour les pods, les rendant directement visibles dans le Vnet. Il n’y a donc pas, de fait, de hop entre les pods et le Vnet, ce qui permet de meilleures performances réseaux, similaires à des communications VM to VM.
Comme discuté dans la partie précédente, il est également possible de déployer des nodes Windows, et donc d’héberger des workloads utilisant des containers Windows.
Une autre option disponible est la technologie du Virtual Node qui utilise des Azure Container Instances.
D’un point de vue moins positif à présent, il est nécessaire de planifier la taille du Vnet correctement, puisque les pods consomment des IPs dans ce range. Parmi les points à considérer, on notera :
- Les IPs pour les nodes, en incluant les upgrades
- Le nombre de pods maximal par node
Pour ce second point, la valeur par défaut pour Azure CNI est 30 (pour une valeur maximum est 110).
Microsoft nous fournit une formule pour calculer la taille du réseau Azure :
number of nodes + 1) + ((number of nodes + 1) * maximum pods per node that you configure)
Cependant, cette formule ne prend pas en compte le paramètre maxSurge qui définit combien de nodes sont créés lors des upgrades (ce qui nous ramène à l’autre point à considérer pour la planification du réseau Azure).
Si l’on configure le maxSurge avec une valeur de 33%, on aura donc pour un cluster de 9 nodes, 3 nodes créés en même temps pour un upgrade. La formule devient dans ce cas :
number of nodes + Additional nodes configured for upgrade) + ((number of nodes + Additional nodes configured for upgrade) * maximum pods per node that you configure)
En continuant avec notre exemple, nous avons donc 9 nodes et 30 pods par node, ce qui nous donne : (9+3) + (9+3) * 30
Soit 279 IPs. Ce qui fait finalement beaucoup pour un cluster pas si gros. On peut voir également que le cluster réserve les IPs dans le Vnet lorsque l’on regarde les connected devices.

Pour optimiser cette consommation d’IP, une option appelée « Azure CNI with dynamic IP allocation » a été mise à disposition. On peut en trouver la description dans la documentation Azure. Dans ce cas, les pods utilisent un subnet différent de celui des nodes. Le subnet en question doit être créé avant le cluster, et apparait par la suite comme un delegated subnet.
Malgré cette option, un overlay serait tout de même mieux.
Azure CNI avec overlay
La bonne nouvelle est donc que les équipes produit AKS ont écouté leurs clients et développé un modèle Azure CNI avec overlay.
Avec cette possibilité, il est possible de bénéficier d’Azure CNI, de ses performances et fonctionnalités, tout en évitant l’épuisement des IPs du Vnet ou plus généralement des ranges IP RFC 1918. Une bonne nouvelle, donc.
Azure CNI overlay se comporte comme un Kubenet dopé. La documentation Microsoft indique que chaque node se voit assigné un CIDR /24, similairement à Kubenet. En revanche, là où Kubenet est plafonné à 400 nodes à cause du nombre maximal de routes dans une UDR, la limite de nodes passe à 1000 avec Azure CNI overlay.
De même, Microsoft annonce des performances au niveau d’Azure CNI, ainsi que la compatibilité avec les nodes Linux et Windows.
À noter toutefois, puisque le trafic n’est pas encapsulé, le filtrage NSG est toujours en œuvre et il est nécessaire d’ajouter aux prérequis de trafic sortant les flux suivants :
- Trafic de node à node sur tous les ports et protocoles
- Trafic du CIDR nodes aux CIDR pods sur tous les ports et protocoles
- Trafic de pods à pods sur tous les ports et protocoles

Un cluster avec Azure CNI overlay affichera Azure CNI comme Network plugin ainsi qu’un Pod CIDR.

On notera tout de même quelques limitations comme la non-compatibilité de AGIC (en passe d’être remplacé par un déploiement de Gateway API managé), ou l’absence de support pour le dual stack IPv4 IPv6, qui sont bien disponibles sur Azure CNI ou Kubenet.
Azure CNI powered by Cilium
Dans la famille Kubenet dopé, nous avons également Azure CNI powered by Cilium. Cette option permet de combiner Azure CNI overlay avec un Data plane s’appuyant sur Cilium.
L’option est intéressante pour introduire Cilium comme CNI dans un cluster, sans toutefois devoir gérer complètement ce dernier. D’un point de vue cluster, il n’y a pas beaucoup de différences avec Azure CNI overlay dans l’état actuel des choses. On peut en revanche voir un déploiement Cilium dans le namespace kube-system.
Il y aurait beaucoup à dire sur Cilium et nous garderons donc cela pour un prochainarticle. Pour le moment nous allons laisser ce sujet en suspens, et passer à notre dernière option.
Bring your own CNI
Comme le laisse supposer le titre de ce paragraphe, il est possible de déployer un cluster sans CNI. On spécifie dans ce cas « None » comme valeur pour le network plugin.
En regardant les nodes après le déploiement, on observe qu’ils sont dans un statut NotReady, en attente d’un CNI.
À ce stade, nous pouvons déployer à peu près n’importe quel CNI. Comme pour la partie précédente, nous nous arrêterons ici pour cet article, et reviendrons sur le sujet une autre fois.
Intéressons-nous à présent à l’usage des subnets par un cluster AKS et aux options disponibles à ce sujet.
Utilisation des subnets
Pour le moment, nous avons vu que les nodes vivent dans leur propre subnet. En fonction de l’option de CNI, nous avons besoin ou pas d’un grand CIDR pour ce subnet.
Dans certains cas, il est nécessaire de disposer de subnet additionnel, comme par exemple pour l’intégration de l’API server, comme discuté dans la première partie de cet article, ou pour Azure CNI with Dynamic Allocation vu précédemment.
Il y a encore deux autres cas d’usage pouvant induire un besoin de subnet additionnel.
Pour commencer, dans le cas de node pool supplémentaire :

Comme on le voit sur l’illustration, il est possible d’ajouter un nouveau subnet pour séparer les node pools supplémentaires du node pool system.
À noter : le réseau ne peut pas être géré par AKS. Il est impératif de préparer le réseau avant le déploiement du cluster. D’autre part, puisqu’AKS gère les flux à travers un NSG associé aux node pools, ce nouveau subnet n’engendre pas de microsegmentation par défaut. Il faut en ce sens ajouter des NSGs au niveau de chaque subnet pour avoir une option de filtrage indépendante par subnet. Mais dans ce cas, la gestion des flux est décorrélée du plan de contrôle Kubernetes, et implique des actions dans le plan de contrôle Azure.
Si l’on s’intéresse à la section connected device sur le Vnet, on peut voir les node pools sur chaque subnet.

Notre dernier cas d’usage consiste à dédier un subnet pour les Internal Load Balancers déployés par le Cloud Controller Manager d’AKS. Bien que l’action se situe dans le scope du control plane Kubernetes, elle se reflète dans le worker plane, et dans notre cas dans le réseau virtuel Azure.

Illustrons notre propos avec un déploiement :
Comme nous l’avons dit, nous voulons utiliser un load balancer interne dans un subnet dédié :
Nous créons ensuite un service kubernetes avec 2 annotations :
- beta.kubernetes.io/azure-load-balancer-internal qui nous permet de spécifier l’usage d’un load balancer ;
- beta.kubernetes.io/azure-load-balancer-internal-subnet pour spécifier le subnet spécifique.
Lorsque le service est créé, on peut observer que celui-ci est bien de type LoadBalancer avec une IP privée.
Avec le load balancer interne correspondant :

Voilà qui conclut notre article. Résumons un peu tout ce que nous avons vu.
Considération réseaux pour Azure Kubernetes Services : l’essentiel à retenir
Dans cet article en deux parties, nous avons discuté des sujets suivants :
| Domaine | Actions |
| Control plane | Protéger l’API server avec
– Une accept list – Un cluster privé – API server Vnet integration |
| Worker plane | Configurer le réseau des nodes et pods
– Avec Kubenet, qui isole les nodes et les pods dans un overlay accessible par NAT – Avec Azure CNI qui utilise le même range pour les pods et les nodes. – Ou Azure CNI Overlay / Powered by Cilium qui permet d’avoir le meilleur des deux précédentes options. |
| Utilisations de subnet | Utiliser des subnets supplémentaires dans le plan Azure pour
– Des nodes pools additionnels – Des Load Balancer interne – Des pods avec Azure CNI Dynamic allocation – L’API server dans le cadre de l’intégration Vnet
|
Vous souhaitez en savoir plus ? Echanger avec nos experts ? Contactez-nous !
