Comment automatiser la configuration du proxy HTTP pour les nœuds de travail Amazon EKS avec les données utilisateur ?

Dernière mise à jour : 09/04/2020

Je souhaite automatiser la configuration du proxy HTTP pour les nœuds de travail Amazon Elastic Kubernetes Service (Amazon EKS) avec les données utilisateur.

Solution

1.    Recherchez le bloc d'adresse CIDR IP de votre cluster :

$ kubectl get service kubernetes -o jsonpath='{.spec.clusterIP}'; echo

La commande précédente renvoie 10.100.0.1 ou 172.20.0.1, ce qui signifie que le bloc d'adresse CIDR IP de votre cluster est 10.100.0.0/16 ou 172.20.0.0/16.

2.    Créez un fichier ConfigMap nommé proxy-env-vars-config.yaml en fonction de la sortie de la commande utilisée à l'étape 1.

Si cette dernière donne une IP comprise dans la plage 172.20.x.x, voici comment structurer votre fichier ConfigMap :

apiVersion: v1
kind: ConfigMap
metadata:
   name: proxy-environment-variables
   namespace: kube-system
data:
   HTTP_PROXY: http://customer.proxy.host:proxy_port
   HTTPS_PROXY: http://customer.proxy.host:proxy_port
   NO_PROXY: 172.20.0.0/16,localhost,127.0.0.1,VPC_CIDR_RANGE,169.254.169.254,.internal,s3.amazonaws.com,.s3.us-east-1.amazonaws.com,api.ecr.us-east-1.amazonaws.com,dkr.ecr.us-east-1.amazonaws.com,ec2.us-east-1.amazonaws.com

Remarque : remplacez VPC_CIDR_RANGE par le bloc d'adresse CIDR IPv4 du VPC de votre cluster.

Si la sortie de la commande donne une IP comprise dans la plage 10.100.x.x, voici comment structurer votre fichier ConfigMap :

apiVersion: v1
kind: ConfigMap
metadata:
   name: proxy-environment-variables
   namespace: kube-system
data:
   HTTP_PROXY: http://customer.proxy.host:proxy_port
   HTTPS_PROXY: http://customer.proxy.host:proxy_port
   NO_PROXY: 10.100.0.0/16,localhost,127.0.0.1,VPC_CIDR_RANGE,169.254.169.254,.internal,s3.amazonaws.com,.s3.us-east-1.amazonaws.com,api.ecr.us-east-1.amazonaws.com,dkr.ecr.us-east-1.amazonaws.com,ec2.us-east-1.amazonaws.com

Remarque : remplacez VPC_CIDR_RANGE par le bloc d'adresse CIDR IPv4 du VPC de votre cluster.

Si vous créez un cluster Amazon EKS avec un accès au point de terminaison de serveur d'API privé, des sous-réseaux privés et aucun accès Internet, vous devez créer et ajouter des points de terminaison pour les éléments suivants :

Amazon Elastic Container Registry (Amazon ECR)
Amazon Simple Storage Service (Amazon S3)
Amazon Elastic Compute Cloud (Amazon EC2)
Amazon Virtual Private Cloud (Amazon VPC)

Par exemple, vous pouvez utiliser les points de terminaison suivants :

api.ecr.us-east-1.amazonaws.com
dkr.ecr.us-east-1.amazonaws.com
s3.amazonaws.com
s3.us-east-1.amazonaws.com
ec2.us-east-1.amazonaws.com

Important : vous devez ajouter le sous-domaine de point de terminaison public à la variable NO_PROXY. Par exemple, ajoutez le domaine .s3.us-east-1.amazonaws.com pour Amazon S3 dans la région AWS us-east-1.

3.    Vérifiez que la variable NO_PROXY dans configmap/proxy-environment-variables (utilisée par les pods kube-proxy et aws-node) inclut l'espace d'adressage IP du cluster Kubernetes. Par exemple, 10.100.0.0/16 est utilisé dans l'exemple de code précédent pour le fichier ConfigMap, où l'IP est comprise dans la plage 10.100.x.x.

4.    Appliquez le fichier ConfigMap :

$ kubectl apply -f /path/to/yaml/proxy-env-vars-config.yaml

5.    Pour configurer le démon Docker et kubelet, injectez des données utilisateur dans vos nœuds de travail. Voici un exemple :

Content-Type: multipart/mixed; boundary="==BOUNDARY=="
MIME-Version:  1.0
--==BOUNDARY==
Content-Type: text/cloud-boothook; charset="us-ascii"

#Set the proxy hostname and port
PROXY="proxy.local:3128"
MAC=$(curl -s http://169.254.169.254/latest/meta-data/mac/)
VPC_CIDR=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/$MAC/vpc-ipv4-cidr-blocks | xargs | tr ' ' ',')

#Create the docker systemd directory
mkdir -p /etc/systemd/system/docker.service.d

#Configure yum to use the proxy
cloud-init-per instance yum_proxy_config cat << EOF >> /etc/yum.conf
proxy=http://$PROXY
EOF

#Set the proxy for future processes, and use as an include file
cloud-init-per instance proxy_config cat << EOF >> /etc/environment
http_proxy=http://$PROXY
https_proxy=http://$PROXY
HTTP_PROXY=http://$PROXY
HTTPS_PROXY=http://$PROXY
no_proxy=$VPC_CIDR,localhost,127.0.0.1,169.254.169.254,.internal,s3.amazonaws.com,.s3.us-east-1.amazonaws.com,api.ecr.us-east-1.amazonaws.com,dkr.ecr.us-east-1.amazonaws.com,ec2.us-east-1.amazonaws.com
NO_PROXY=$VPC_CIDR,localhost,127.0.0.1,169.254.169.254,.internal,s3.amazonaws.com,.s3.us-east-1.amazonaws.com,api.ecr.us-east-1.amazonaws.com,dkr.ecr.us-east-1.amazonaws.com,ec2.us-east-1.amazonaws.com
EOF

#Configure docker with the proxy
cloud-init-per instance docker_proxy_config tee <<EOF /etc/systemd/system/docker.service.d/proxy.conf >/dev/null
[Service]
EnvironmentFile=/etc/environment
EOF

#Configure the kubelet with the proxy
cloud-init-per instance kubelet_proxy_config tee <<EOF /etc/systemd/system/kubelet.service.d/proxy.conf >/dev/null
[Service]
EnvironmentFile=/etc/environment
EOF

#Reload the daemon and restart docker to reflect proxy configuration at launch of instance
cloud-init-per instance reload_daemon systemctl daemon-reload 
cloud-init-per instance enable_docker systemctl enable --now --no-block docker

--==BOUNDARY==
Content-Type:text/x-shellscript; charset="us-ascii"

#!/bin/bash
set -o xtrace

#Set the proxy variables before running the bootstrap.sh script
set -a
source /etc/environment

/etc/eks/bootstrap.sh ${ClusterName} ${BootstrapArguments}

# Use the cfn-signal only if the node is created through an AWS CloudFormation stack and needs to signal back to an AWS CloudFormation resource (CFN_RESOURCE_LOGICAL_NAME) that waits for a signal from this EC2 instance to progress through either:
# - CreationPolicy https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-creationpolicy.html
# - UpdatePolicy https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html
# cfn-signal will signal back to AWS CloudFormation using https transport, so set the proxy for an HTTPS connection to AWS CloudFormation
/opt/aws/bin/cfn-signal
    --exit-code $? \
    --stack  ${AWS::StackName} \
    --resource CFN_RESOURCE_LOGICAL_NAME  \
    --region ${AWS::Region} \
    --https-proxy $HTTPS_PROXY

--==BOUNDARY==--

Important : Vous devez mettre à jour ou créer des fichiers de configuration yum, docker et kubelet avant de démarrer le démon Docker et kubelet.

Consultez Lancement des nœuds autogérés Amazon Linux 2 pour obtenir un exemple de données utilisateur injectées dans les nœuds de travail à l'aide d'un modèle AWS CloudFormation lancé à partir d'AWS Management Console.

6.    Mettez à jour les pods aws-node et kube proxy :

$ kubectl patch -n kube-system -p '{ "spec": {"template": { "spec": { "containers": [ { "name": "aws-node", "envFrom": [ { "configMapRef": {"name": "proxy-environment-variables"} } ] } ] } } } }' daemonset aws-node
$ kubectl patch -n kube-system -p '{ "spec": {"template":{ "spec": { "containers": [ { "name": "kube-proxy", "envFrom": [ { "configMapRef": {"name": "proxy-environment-variables"} } ] } ] } } } }' daemonset kube-proxy

Si vous modifiez le fichier ConfigMap, appliquez les mises à jour puis définissez à nouveau le fichier ConfigMap dans les pods. Voici un exemple :

$ kubectl set env daemonset/kube-proxy --namespace=kube-system --from=configmap/proxy-environment-variables --containers='*'
$ kubectl set env daemonset/aws-node --namespace=kube-system --from=configmap/proxy-environment-variables --containers='*'

Important : vous devez mettre à jour toutes les modifications YAML des objets kubernetes kube-proxy ou aws-node lorsque ces objets sont mis à niveau. Pour mettre à jour un ConfigMap avec une valeur par défaut, utilisez les commandes eksctl utils update-kube-proxy ou eksctl utils update-aws-node.

Conseil : le proxy peut perdre la connectivité au serveur d'API. Dans ce cas, il devient un point de défaillance unique et le comportement de votre cluster peut être imprévisible. Pour éviter ce problème, exécutez votre proxy derrière un espace de noms de découverte de service ou un équilibreur de charge.

7.    Vérifiez que les variables proxy sont utilisées dans les pods kube proxy et aws-node :

$ kubectl describe pod kube-proxy-xxxx -n kube-system

Le résultat doit être similaire à cet exemple :

Environment:
      HTTPS_PROXY:  <set to the key 'HTTPS_PROXY' of config map 'proxy-environment-variables'>  Optional: false
      HTTP_PROXY:   <set to the key 'HTTP_PROXY' of config map 'proxy-environment-variables'>   Optional: false
      NO_PROXY:     <set to the key 'NO_PROXY' of config map 'proxy-environment-variables'>     Optional: false

Si vous n'utilisez pas AWS PrivateLink, vérifiez l'accès aux points de terminaison d'API via un serveur proxy pour Amazon EC2, Amazon ECR et Amazon S3.


Cette page vous a-t-elle été utile ?


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