Comment utiliser plusieurs plages d'adresses CIDR avec Amazon EKS ?

Date de la dernière mise à jour : 28/07/2021

Je souhaite utiliser plusieurs plages d'adresses CIDR avec Amazon Elastic Kubernetes Service (Amazon EKS) pour résoudre les problèmes liés à mes pods. Par exemple, comment puis-je exécuter des pods avec les différentes plages d'adresses CIDR ajoutées à mon Amazon Virtual Private Cloud (Amazon VPC) ? De plus, comment puis-je ajouter d'autres adresses IP à mon sous-réseau lorsqu'il est à court d'adresses IP ? Enfin, comment puis-je être sûr que les pods s'exécutant sur les nœuds de travail ont des plages d'adresses IP différentes ?

Brève description

Avant de suivre les étapes de la section Résolution vérifiez que vous disposez des éléments suivants :

  • Un cluster Amazon EKSen cours d'exécution
  • Accès à une version (non antérieure à 1.16 284) de l'interface de ligne de commande AWS (AWS CLI)
  • Autorisations AWS Identity and Access Management (IAM) pour gérer un Amazon VPC
  • Un kubectl avec des autorisations pour créer des ressources personnalisées et modifier le DaemonsSet
  • Une version installée de jq (à partir du site jq) sur votre système
  • Un système Unix avec un shell Bash

Gardez à l'esprit les points suivants :

  • Si vous exécutez vos pods sur différentes plages d'adresses CIDR, vous disposez d'un plus grand nombre d'adresses IP pour les pods gérés par Amazon EKS. Vous bénéficiez également d'une plus grande flexibilité pour vos architectures réseau. Les pods ne consomment pas d'adresses IP RFC 1918 dans votre VPC dans deux cas. Le premier est lorsque vous ajoutez des blocs d'adresses CIDR secondaires à un VPC à partir des plages 100.64.0.0/10 et 198.19.0.0/16. Le deuxième est lorsque vous utilisez un réseau personnalisé CNI.
  • Dans les scénarios avec conversion d'adresses réseau (NAT) de niveau opérateur, 100.64.0.0/10 est une plage de réseau privé. Cette plage de réseau privé est utilisée dans l'espace d'adresses partagées pour les communications entre un fournisseur de services et ses abonnés. Vous devez avoir une passerelle NAT configurée dans la table de routage pour que les pods puissent communiquer avec Internet. Les daemonsets ne sont pas pris en charge sur les clusters AWS Fargate. Pour ajouter des plages d'adresses CIDR secondaires à des profils Fargate, utilisez des sous-réseaux à partir de blocs d'adresses CIDR secondaires de votre VPC. Ensuite, balisez vos nouveaux sous-réseaux avant de les ajouter à votre profil Fargate.

Important : Dans certaines cas, Amazon EKS ne peut pas communiquer avec les nœuds lancés dans les sous-réseaux à partir de blocs d'adresses CIDR supplémentaires ajoutés à un VPC après la création d'un cluster. Pour plus d'informations, reportez-vous à la note « Important » dans Considérations relatives au VPC de cluster.

Résolution

Remarque : si vous recevez des erreurs lors de l'exécution des commandes AWS CLI, assurez-vous d'utiliser la version la plus récente d'AWS CLI.

Dans la résolution suivante, vous devez d'abord configurer votre VPC. Configurez ensuite le plugin CNI pour utiliser une nouvelle plage d'adresses CIDR

Ajouter des plages d'adresses CIDR supplémentaires pour étendre votre réseau VPC

1.    Trouvez vos VPC.

Si vos VPC ont une balise, exécutez la commande suivante pour les trouver :

VPC_ID=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=yourVPCName | jq -r '.Vpcs[].VpcId')

Si vos VPC n'ont pas de balise, exécutez la commande suivante pour répertorier tous les VPC de votre région AWS :

aws ec2 describe-vpcs --filters  | jq -r '.Vpcs[].VpcId'

2.    Pour attacher votre VPC à une variable VPC_ID exécutez la commande suivante :

export VPC_ID=vpc-xxxxxxxxxxxx

3.    Pour associer un bloc d'adresse CIDR supplémentaire de la plage 100.64.0.0/16 au VPC, exécutez la commande suivante :

aws ec2 associate-vpc-cidr-block --vpc-id $VPC_ID --cidr-block 100.64.0.0/16

Créer des sous-réseaux avec une nouvelle plage d'adresses CIDR

1.    Pour répertorier toutes les zones de disponibilité de votre région AWS, exécutez la commande suivante :

aws ec2 describe-availability-zones --region us-east-1 --query 'AvailabilityZones[*].ZoneName'

Remarque : remplacez us-east-1 par votre propre région AWS.

2.    Choisissez la zone de disponibilité dans laquelle vous souhaitez ajouter les sous-réseaux, puis attribuez ces zones de disponibilité aux variables. Par exemple :

export AZ1=us-east-1a
export AZ2=us-east-1b
export AZ3=us-east-1c

Remarque : vous pouvez ajouter d'autres zones de disponibilité en créant d'autres variables.

3.    Pour créer de nouveaux sous-réseaux sous le VPC avec la nouvelle plage d'adresses CIDR, exécutez les commandes suivantes :

CUST_SNET1=$(aws ec2 create-subnet --cidr-block 100.64.0.0/19 --vpc-id $VPC_ID --availability-zone $AZ1 | jq -r .Subnet.SubnetId)
CUST_SNET2=$(aws ec2 create-subnet --cidr-block 100.64.32.0/19 --vpc-id $VPC_ID --availability-zone $AZ2 | jq -r .Subnet.SubnetId)
CUST_SNET3=$(aws ec2 create-subnet --cidr-block 100.64.64.0/19 --vpc-id $VPC_ID --availability-zone $AZ3 | jq -r .Subnet.SubnetId)

Baliser les nouveaux sous-réseaux

Pour les clusters exécutés sur Kubernetes 1.18 et les versions antérieures, vous devez baliser tous les sous-réseaux afin qu'Amazon EKS puisse découvrir les sous-réseaux.

Remarque : Amazon EKS prend en charge la découverte automatique de sous-réseaux sans balises kubernetes.io à partir de la version 1.19 de Kubernetes. Pour plus d'informations, consultez le journal des modifications sur le site GitHub de Kubernetes.

1.    (Facultatif) Ajoutez une balise de nom pour vos sous-réseaux en définissant une paire clé-valeur. Par exemple :

aws ec2 create-tags --resources $CUST_SNET1 --tags Key=Name,Value=SubnetA
aws ec2 create-tags --resources $CUST_SNET2 --tags Key=Name,Value=SubnetB
aws ec2 create-tags --resources $CUST_SNET3 --tags Key=Name,Value=SubnetC

2.    Pour les clusters exécutés sur Kubernetes 1.18 et les versions antérieures, balisez le sous-réseau à des fins de découverte par Amazon EKS. Par exemple :

aws ec2 create-tags --resources $CUST_SNET1 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared
aws ec2 create-tags --resources $CUST_SNET2 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared
aws ec2 create-tags --resources $CUST_SNET3 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared

Remarque : remplacez yourClusterName par le nom de votre cluster Amazon EKS.

Conseil : si vous envisagez d'utiliser Elastic Load Balancing, pensez à ajouter des balises supplémentaires.

Associer votre nouveau sous-réseau à une table de routage

1.    Pour répertorier la totalité de la table de routage sous le VPC, exécutez la commande suivante :

aws ec2 describe-route-tables --filters Name=vpc-id,Values=$VPC_ID |jq -r '.RouteTables[].RouteTableId'

2.    Pour la table de routage que vous souhaitez associer à votre sous-réseau, exécutez la commande suivante pour exporter vers la variable. Remplacez ensuite rtb-xxxxxxxxx par les valeurs de l'étape 1 :

export RTASSOC_ID=rtb-xxxxxxxxx

3.    Associez la table de routage à tous les nouveaux sous-réseaux. Par exemple :

aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET1
aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET2
aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET3

Pour plus d’informations, consultez Routage.

Configurer le plug-in CNI pour utiliser la nouvelle plage d'adresses CIDR

1.    Pour vérifier que vous disposez de la dernière version du plug-in CNI, exécutez la commande suivante.

kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2

Si votre version du plug-in CNI est antérieure à la version 1.5.3, exécutez la commande suivante pour effectuer une mise à jour vers la dernière version :

kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/v1.5/aws-k8s-cni.yaml

2.    Pour activer la configuration réseau personnalisée pour le plug-in CNI, exécutez la commande suivante :

kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true

3.    Pour ajouter l'étiquette ENIConfig afin d'identifier vos nœuds de travail, exécutez la commande suivante :

kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=failure-domain.beta.kubernetes.io/zone

4.    Pour installer la définition de ressource personnalisée EniConfig (depuis le site Web Kubernetes), exécutez la commande suivante :

cat << EOF | kubectl apply -f -
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: eniconfigs.crd.k8s.amazonaws.com
spec:
  scope: Cluster
  group: crd.k8s.amazonaws.com
  version: v1alpha1
  names:
    plural: eniconfigs
    singular: eniconfig
    kind: ENIConfig
EOF

5.    Pour créer une ressource personnalisée ENIConfig pour l'ensemble des sous-réseaux et des zones de disponibilité, exécutez les commandes suivantes :

cat <<EOF  | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ1
spec:
  subnet: $CUST_SNET1
EOF

cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ2
spec:
  subnet: $CUST_SNET2
EOF

cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ3
spec:
  subnet: $CUST_SNET3
EOF

Remarque : ENIConfig doit correspondre à la zone de disponibilité de vos nœuds de travail.

6.    Lancez les nouveaux nœuds de travail et résiliez les anciens.

Remarque : l'exécution de l'étape 6 permet au plugin CNI (ipamd) d'allouer des adresses IP de la nouvelle plage d'adresses CIDR sur les nouveaux nœuds de travail.

Si vous utilisez un réseau personnalisé, l'interface réseau principale n'est pas utilisée pour le placement de pod. Dans ce cas de figure, vous devez d'abord mettre à jour max-pods à l'aide de la formule suivante :

maxPods = (number of interfaces - 1) * (max IPv4 addresses per interface - 1) + 2

Ensuite, vous devez mettre à jour les données utilisateur de vos nœuds auto-gérés pour ajouter les données utilisateur pour transmettre la nouvelle valeur max-pods. Pour le champ BootStrapArguments, entrez ce qui suit :

--use-max-pods false --kubelet-extra-args '--max-pods=<20>'

Remarque : Des groupes de nœuds gérés sont nécessaires pour créer des AMI (Amazon Machine Images) personnalisées.

Si vous avez créé un groupe de nœuds autogérés, vous devez mettre à jour ENIConfig. Mettez à jour ENIConfig avec le groupe de sécurité créé par votre pile CloudFormation pour les nouveaux sous-réseaux. Par exemple :

cat <<EOF  | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ1
spec:
  securityGroups: 
    - sg-xxxxxxxxxxxx
  subnet: $CUST_SNET1
EOF

cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ2
spec:
  securityGroups: 
    - sg-xxxxxxxxxxxx
  subnet: $CUST_SNET2
EOF

cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
 name: $AZ3
spec:
  securityGroups: 
    - sg-xxxxxxxxxxxx
  subnet: $CUST_SNET3
EOF

Remarque : Si vous utilisez des groupes de nœuds gérés, mettez alors à jour les groupes de sécurité du cluster. Remplacez sg-XXXXXXXXXXXX par votre groupe de sécurité de cluster.

7.    Pour tester la configuration en lançant des pods, exécutez les commandes suivantes :

kubectl run nginx --image nginx --replicas 10
kubectl get pods -o wide

À présent, vous pouvez voir que dix nouveaux pods ont été ajoutés et que la nouvelle plage d'adresses CIDR est planifiée sur les nouveaux nœuds de travail.


Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?