ユーザーデータが投入された 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 (Amazon 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 変数に追加する必要があります。たとえば、Amazon S3 の .s3.us-east-1.amazonaws.com ドメインを us-east-1 AWS リージョンで追加します。

3.    (kube-proxy および aws-node ポッドで使用されている) configmap/proxy-environment-variables にある 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 を起動する前に、yumdocker、および kubelet の設定ファイルを更新または作成する必要があります。

AWS マネジメントコンソールから起動された AWS CloudFormation テンプレートを使用してワーカーノードに投入されたユーザーデータの例については、「Launching self-managed Amazon Linux 2 nodes」を参照してください。

6.    aws-node および kube-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 サーバーに接続できなくなった場合、プロキシは単一障害点になり、クラスターの動作が予測不能になる可能性があります。プロキシが単一障害点にならないようにするには、サービス検出名前空間またはロードバランサーの背後でプロキシを実行します。

7.    プロキシ変数が kube-proxy および aws-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 エンドポイントへのアクセスを検証します。


この記事はお役に立ちましたか?


請求に関するサポートまたは技術的なサポートが必要ですか?