사용자 데이터를 사용하여 Amazon EKS 작업자 노드에 대한 HTTP 프록시 구성을 자동화하려면 어떻게 해야 합니까?

최종 업데이트 날짜: 2020년 4월 9일

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

해결 방법

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.    1단계의 명령 출력을 기반으로 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(VPC)

예를 들어 다음 엔드포인트를 사용할 수 있습니다.

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

중요: NO_PROXY 변수에 퍼블릭 엔드포인트 하위 도메인을 추가해야 합니다. 예를 들어 us-east-1 AWS 리전에서 Amazon S3에 대한 .s3.us-east-1.amazonaws.com 도메인을 추가합니다.

3.    configmap/proxy-environment-variables(kube-proxyaws-node pods에 사용됨)의 NO_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.    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, dockerkubelet 구성 파일을 업데이트하거나 생성해야 합니다.

AWS Management Console에서 시작한 AWS CloudFormation 템플릿을 사용하여 작업자 노드에 주입된 사용자 데이터의 예는 자체 관리형 Amazon Linux 2 노드 시작을 참조하십시오.

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

중요: 이러한 객체가 업그레이드될 경우 Kubernetes 객체 kube-proxy 또는 aws-node에 대한 모든 YAML 수정 사항을 업데이트해야 합니다. ConfigMap을 기본값으로 업데이트하려면 eksctl utils update-kube-proxy 또는 eksctl utils update-aws-node 명령을 사용하십시오.

팁: 프록시와 API 서버의 연결이 끊어지면 프록시가 단일 장애 지점이 되어 클러스터의 동작을 예측할 수 없습니다. 프록시가 단일 장애 지점이 되지 않도록 하려면 서비스 검색 네임스페이스 또는 로드 밸런서를 통해 프록시를 실행합니다.

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

$ 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
      NO_PROXY:     <set to the key 'NO_PROXY' of config map 'proxy-environment-variables'>     Optional: false

AWS PrivateLink를 사용하지 않는 경우 Amazon EC2, Amazon ECR 및 Amazon S3용 프록시 서버를 통해 API 엔드포인트에 대한 액세스를 확인하십시오.


이 문서가 도움이 되었습니까?


결제 또는 기술 지원이 필요합니까?