내용으로 건너뛰기

Docker를 사용하여 Amazon EKS 워커 노드의 HTTP 프록시 구성을 자동화하려면 어떻게 해야 합니까?

5분 분량
0

사용자 데이터를 사용하여 Amazon Elastic Kubernetes Service(Amazon EKS) 워커 노드에 대한 HTTP 프록시 구성을 자동화하려고 합니다.

해결 방법

참고: 다음 해결 방법은 기본 런타임이 Docker인 노드에만 적용되며 런타임이 포함된 노드에는 적용되지 않습니다. containerd 런타임이 있는 노드의 경우 Amazon EKS containerd 노드의 HTTP 프록시 구성을 자동화하려면 어떻게 해야 합니까?를 참조하세요.

워커 노드에 프록시를 설정하려면 Amazon EKS 클러스터의 필수 구성 요소가 프록시와 통신하도록 구성해야 합니다. 구성 요소에는 kubelet systemd 서비스, kube-proxy, aws-node 포드 및 yum 업데이트가 포함됩니다.

Docker 런타임으로 워커 노드의 프록시 구성을 자동화하려면 다음 단계를 완료하세요.

  1. 클러스터의 IP 주소 CIDR 블록 찾기:

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

    참고: 이전 명령은 10.100.0.1 또는 172.20.0.1을 반환하므로 클러스터 IP 주소 CIDR 블록은 10.100.0.0/16 또는 172.20.0.0/16입니다.

  2. 명령 출력을 기반으로 proxy-env-vars-config.yaml이라는 ConfigMap 파일을 생성합니다.
    출력에 172.20.x.x 범위의 IP 주소가 있는 경우 다음 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 블록으로 대체합니다.
    출력에 10.100.x.x 범위의 IP 주소가 있는 경우 다음 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. kube-proxyaws-node 포드에서 사용하는 configmap/proxy-environment-variablesNO_PROXY 변수에 Kubernetes 클러스터 IP 주소 스페이스가 포함되어 있는지 확인합니다. 예를 들어, IP 주소 범위가 10.100.x.x인 ConfigMap 파일에 대한 위 코드 예시에서는 10.100.0.0/16이 사용되었습니다.

  4. ConfigMap 적용:

    $ kubectl apply -f /path/to/yaml/proxy-env-vars-config.yaml
  5. 도커 대몬(daemon)과 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==--

    중요: 도커 대몬(daemon)과 kubelet을 시작하기 전에 yum, Docker 및 kubelet 구성 파일을 업데이트하거나 생성해야 합니다.
    AWS CloudFormation 템플릿을 사용하여 작업자 노드에 사용자 데이터를 포함하는 방법에 대한 자세한 내용은 자체 관리형 Amazon Linux 노드 생성을 참조하십시오.

  6. aws-nodekube-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

    ConfigMap을 변경한 다음 업데이트를 적용하고 포드에 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-proxy 또는 aws-node를 업데이트할 때 모든 YAML 수정 사항도 업데이트해야 합니다. ConfigMap을 기본 값으로 업데이트하려면 eksctl utils update-kube-proxy 또는 eksctl utils update-aws-node 명령을 실행합니다.
    프록시가 API 서버와 연결이 끊어지면 프록시는 단일 장애 지점이 되고 클러스터의 동작을 예측할 수 없게 됩니다. 이 문제를 방지하려면 서비스 검색 네임스페이스 또는 로드 밸런서 뒤에서 프록시를 실행하세요.

  7. 프록시 변수가 kube-proxyaws-node 포드에서 사용되는지 확인합니다.

    $ 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를 사용하지 않는 경우에는 Amazon EC2, Amazon ECR 및 Amazon S3용 프록시 서버를 통해 API 엔드포인트에 대한 액세스를 확인합니다.

AWS 공식업데이트됨 2년 전