Direkt zum Inhalt

Wie automatisiere ich die HTTP-Proxy-Konfiguration für Amazon-EKS-Worker-Knoten mit Docker?

Lesedauer: 5 Minute
0

Ich möchte die HTTP-Proxy-Konfiguration für Amazon Elastic Kubernetes Service (Amazon EKS)-Worker-Knoten mithilfe von Benutzerdaten automatisieren.

Behebung

Hinweis: Die folgende Lösung gilt nur für Knoten, bei denen die zugrunde liegende Laufzeit Docker ist, und gilt nicht für Knoten mit einer containerd-Laufzeit. Informationen zu Knoten mit containerd-Laufzeit findest du unter Wie kann ich die Konfiguration des HTTP-Proxys für Amazon EKS-containerd-Knoten automatisieren?

Um einen Proxy auf Worker-Knoten einzurichten, musst du die erforderlichen Komponenten deines Amazon EKS-Clusters für die Kommunikation vom Proxy aus konfigurieren. Zu den Komponenten gehören der kubelet systemd-Service, kube-proxy, aws-node-Pods und yum-Update.

Um die Proxy-Konfiguration für Worker-Knoten mit einer Docker-Laufzeit zu automatisieren, führe die folgenden Schritte aus:

  1. Finde den IP-Adress-CIDR-Block deines Clusters:

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

    Hinweis: Der vorherige Befehl gibt entweder 10.100.0.1 oder 172.20.0.1 zurück, daher ist der Cluster-IP-Adress-CIDR-Block entweder 10.100.0.0/16 oder 172.20.0.0/16.

  2. Erstelle basierend auf der Ausgabe des Befehls eine ConfigMap-Datei mit dem Namen proxy-env-vars-config.yaml.
    Wenn die Ausgabe eine IP-Adresse aus dem Bereich 172.20.x.x enthält, verwende die folgende ConfigMap-Struktur:

    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

    Hinweis: Ersetze VPC_CIDR_RANGE durch den IPv4-Adress-CIDR-Block der Virtual Private Cloud (VPC) deines Clusters.
    Wenn die Ausgabe eine IP-Adresse aus dem Bereich 10.100.x.x enthält, verwende die folgende ConfigMap-Struktur:

    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

    Hinweis: Ersetze VPC_CIDR_RANGE durch den IPv4-Adress-CIDR-Block der VPC deines Clusters.
    Amazon EKS-Cluster mit privatem API-Serverendpunktzugriff, privaten Subnetzen und ohne Internetzugang erfordern zusätzliche Endpunkte. Wenn du die vorherige Konfiguration zum Erstellen eines Clusters verwendest, musst du Endpunkte für die folgenden Services erstellen und hinzufügen:
    Amazon Elastic Container Registry (Amazon ECR)
    Amazon Simple Storage Service (Amazon S3)
    Amazon Elastic Compute Cloud (Amazon EC2)
    Amazon Virtual Private Cloud (Amazon VPC)
    Wichtig: Du musst die Subdomain für öffentliche Endpunkte zur Variablen NO\ _PROXY hinzufügen. Füge beispielsweise die Domain .s3.us-east-1.amazonaws.com für Amazon S3 in der AWS-Region us-east-1 hinzu. Wenn du den privaten Endpunktzugriff für deinen Amazon EKS-Cluster aktivierst, musst du den Amazon EKS-Endpunkt zur Variablen NO_PROXY hinzufügen. Füge beispielsweise die Domain .us-east-1.eks.amazonaws.com für deinen Amazon EKS-Cluster in der AWS-Region us-east-1 hinzu.

  3. Überprüfe, dass die Variable NO_PROXY in configmap/proxy-environment-variables, die von kube-proxy- und aws-node-Pods verwendet wird, den Kubernetes-Cluster-IP-Adressbereich enthält. Zum Beispiel wird 10.100.0.0/16 im vorherigen Code-Beispiel für die ConfigMap-Datei verwendet, wobei der IP-Adressbereich von 10.100.x.x reicht.

  4. Wende die ConfigMap an:

    $ kubectl apply -f /path/to/yaml/proxy-env-vars-config.yaml
  5. Um den Docker-Daemon und kubelet zu konfigurieren, füge Benutzerdaten zu deinen Worker-Knoten hinzu:

    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==--

    Wichtig: Bevor du den Docker-Daemon und kubelet startest, musst du yum-, Docker- und kubelet-Konfigurationsdateien aktualisieren oder erstellen.
    Weitere Informationen dazu, wie du eine AWS-CloudFormation-Vorlage verwendest, um User Data in Worker-Knoten einzubinden, findest du unter Selbstverwaltete Amazon Linux-Knoten erstellen.

  6. Um die aws-node- und kube-proxy-Pods zu aktualisieren, führe die folgenden Befehle aus:

    $ 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

    Falls du die ConfigMap änderst, wende die Updates an und stelle die ConfigMap erneut in den Pods ein:

    $ 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='*'

    Wichtig: Wenn du kube-proxy oder aws-node aktualisierst, musst du auch alle YAML-Änderungen aktualisieren. Um eine ConfigMap auf einen Standardwert zu aktualisieren, führe die Befehle eksctl utils update-kube-proxy oder eksctl utils update-aws-node aus.
    Wenn der Proxy die Verbindung zum API-Server verliert, wird der Proxy zu einem Single Point of Failure und kann zu unvorhersehbarem Cluster-Verhalten führen. Um dieses Problem zu vermeiden, führe deinen Proxy hinter einem Serviceerkennungs-Namespace oder Load Balancer aus.

  7. Überprüfe, dass die Proxy-Variablen in den kube-proxy- und aws-node-Pods verwendet werden:

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

    Beispielausgabe:

    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

    Wenn du AWS PrivateLink nicht verwendest, überprüfe den Zugriff auf API-Endpunkte über einen Proxy-Server für Amazon EC2, Amazon ECR und Amazon S3.

AWS OFFICIALAktualisiert vor 2 Jahren