跳至內容

如何使用 Docker 自動化 Amazon EKS 工作節點的 HTTP Proxy 組態?

4 分的閱讀內容
0

我想透過使用者資料自動化 Amazon Elastic Kubernetes Service (Amazon EKS) 工作節點的 HTTP Proxy 組態。

解決方法

**注意:**以下解決方法僅適用於基礎執行時期為 Docker 的節點,不適用於使用 containerd 執行時期的節點。對於使用 containerd 執行時期的節點,請參閱如何為 Amazon EKS containerd 節點自動化設定 HTTP Proxy?

若要在工作節點上設定 Proxy,您必須設定 Amazon EKS 叢集的必要元件,使其可透過 Proxy 通訊。元件包括 kubelet systemd 服務、kube-proxy、aws-node Pod,以及 yum 更新。

若要為使用 Docker 執行時期的工作節點自動化 Proxy 組態,請完成以下步驟:

  1. 找出您叢集的 IP 位址 CIDR 區塊:

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

    **注意:**上述命令會回傳 10.100.0.1172.20.0.1,因此叢集 IP 位址 CIDR 區塊為 10.100.0.0/16172.20.0.0/16

  2. 根據命令的輸出,建立名為 proxy-env-vars-config.yaml 的 ConfigMap 檔案。
    若輸出中的 IP 位址範圍為 172.20.x.x,請使用以下 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

    **注意:**將 VPC_CIDR_RANGE 替換為您叢集虛擬私有雲端 (VPC) 的 IPv4 位址 CIDR 區塊。
    若輸出中的 IP 位址範圍為 10.100.x.x,請使用以下 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

    **注意:**將 VPC_CIDR_RANGE 替換為您叢集 VPC 的 IPv4 位址 CIDR 區塊。
    使用私有 API 伺服器端點存取、私有子網路且無網際網路存取的 Amazon EKS 叢集需要額外的端點。若您使用上述組態建立叢集,則必須為以下服務建立並新增端點:
    Amazon Elastic Container Registry (Amazon ECR)
    Amazon Simple Storage Service (Amazon S3)
    Amazon Elastic Compute Cloud (Amazon EC2)
    Amazon Virtual Private Cloud (Amazon VPC)
    **重要:**您必須將公共端點子網域新增至 NO_PROXY 變數。例如,在 us-east-1 AWS 區域中,為 Amazon S3 新增 .s3.us-east-1.amazonaws.com 網域。若您為 Amazon EKS 叢集啟用端點私有存取,則必須將 Amazon EKS 端點新增至 NO_PROXY 變數。例如,在 us-east-1 AWS 區域中,為您的 Amazon EKS 叢集新增 .us-east-1.eks.amazonaws.com 網域。

  3. 確認 configmap/proxy-environment-variables 中的 NO_PROXY 變數 (由 kube-proxyaws-node Pod 使用) 包含 Kubernetes 叢集 IP 位址空間。例如,在上述 ConfigMap 檔案的程式碼範例中,當 IP 位址範圍為 10.100.x.x 時,會使用 10.100.0.0/16

  4. 套用 ConfigMap:

    $ kubectl apply -f /path/to/yaml/proxy-env-vars-config.yaml
  5. 若要設定 Docker 常駐程式與 kubelet,請在工作節點中包含使用者資料:

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

    **重要:**在啟動 Docker 常駐程式與 kubelet 之前,您必須更新或建立 yum、Docker 與 kubelet 組態檔。
    如需如何使用 AWS CloudFormation 範本在工作節點中包含使用者資料的詳細資訊,請參閱建立自行管理的 Amazon Linux 節點

  6. 若要更新 aws-nodekube-proxy Pod,請執行以下命令:

    $ 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

    若您變更 ConfigMap,請套用更新,然後再次在 Pod 中設定 ConfigMap:

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

    **重要:**當您更新 kube-proxyaws-node 時,也必須更新所有 YAML 修改。若要將 ConfigMap 更新為預設值,請執行 eksctl utils update-kube-proxyeksctl utils update-aws-node 命令。
    若 Proxy 與 API 伺服器之間的連線中斷,則 Proxy 會成為單點故障,並可能導致叢集行為無法預測。為避免此問題,請將 Proxy 部署在服務探索命名空間或負載平衡器之後。

  7. 確認 kube-proxyaws-node Pod 使用 Proxy 變數:

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

    範例輸出:

    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

    如果您未使用 AWS PrivateLink,請確認可透過 Proxy 伺服器存取 Amazon EC2、Amazon ECR 和 Amazon S3 的 API 端點。

AWS 官方已更新 2 年前