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

5분 분량
0

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

간략한 설명

워커 노드에 프록시를 설정하려면 프록시에서 통신하도록 Amazon EKS 클러스터의 필수 구성 요소를 구성해야 합니다. 구성 요소에는 kubelet 시스템 서비스, kube-proxy, aws-node 포드 및 yum 업데이트가 포함되며 이에 국한되지 않습니다. Docker 런타임으로 워커 노드의 프록시 구성을 자동화하려면 다음을 수행하십시오. 

참고: 다음 해결 방법은 기본 런타임이 Docker인 노드에만 적용되며, 컨테이너화한 런타임이 있는 노드에는 적용되지 않습니다. containerd 런타임이 있는 노드의 경우 EKS containerd 노드의 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입니다.

  1. 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(Amazon VPC)

예를 들어 api.ecr.us-east-1.amazonaws.com, dkr.ecr.us-east-1.amazonaws.com, s3.amazonaws.com, s3.us-east-1.amazonaws.comec2.us-east-1.amazonaws.com 엔드포인트를 사용할 수 있습니다.

중요: NO_PROXY 변수에 퍼블릭 엔드포인트 하위 도메인을 추가해야 합니다. 예를 들어 us-east-1 AWS 리전에서 Amazon S3에 대한 .s3.us-east-1.amazonaws.com 도메인을 추가합니다. Amazon EKS 클러스터에 엔드포인트 프라이빗 액세스를 활성화했다면 Amazon EKS 엔드포인트를 NO_PROXY 변수에 추가해야 합니다. 예를 들어 Amazon EKS 클러스터에 대해 .us-east-1.eks.amazonaws.com 도메인을 us-east-1 AWS 리전에서 추가합니다.

  1. NO_PROXY 변수(configmap/proxy-environment-variables(kube-proxyaws-node pods에 사용됨) 관련)에 Kubernetes 클러스터 IP 주소 공간이 포함되어 있는지 확인하십시오. 예를 들어, 10.100.0.0/16이 IP 범위가 10.100.x.x인 ConfigMap 파일의 이전 코드 샘플에서 사용됩니다.

  2. ConfigMap을 적용합니다.

$ kubectl apply -f /path/to/yaml/proxy-env-vars-config.yaml
  1. Docker 대몬(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==--

중요: yum, Dockerkubelet 구성 파일을 Docker 대몬(daemon) 및 kubelet을 시작하기 전에 업데이트하거나 생성해야 합니다.

AWS CloudFormation 템플릿을 사용하여 워커 노드에 주입된 사용자 데이터의 예는 자체 관리형 Amazon Linux 노드 시작을 참조하세요.

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

  1. 프록시 변수가 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 엔드포인트에 대한 액세스를 확인하십시오.


AWS 공식
AWS 공식업데이트됨 2달 전