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

5분 분량
0

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

간략한 설명

워커 노드에 프록시를 설정하려면 Amazon EKS 클러스터의 필수 구성 요소가 프록시와 통신하도록 구성해야 합니다. 구성 요소에는 kubelet systemd 서비스, 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입니다.

2. 1단계의 명령 출력을 기반으로 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(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.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 변수에 추가해야 합니다. 예를 들어, us-east-1 AWS 리전의 Amazon EKS 클러스터용 .us-east-1.eks.amazonaws.com 도메인을 추가하세요.

3. configmap/proxy-environment-variables(kube-proxyaws-node 포드에서 사용) 의 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. 도커 대몬(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, Dockerkubelet 구성 파일을 업데이트하거나 생성해야 합니다.

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

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

팁: 프록시가 API 서버와 연결이 끊어지면 프록시는 단일 장애 지점이 되고 클러스터의 동작을 예측할 수 없게 됩니다. 프록시가 단일 장애 지점이 되는 것을 방지하려면 서비스 검색 네임스페이스 또는 로드 밸런서 뒤에서 프록시를 실행하세요.

  1. 프록시 변수가 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
 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 공식업데이트됨 일 년 전