跳至内容

如何为 Amazon EKS containerd 节点自动配置 HTTP 代理?

6 分钟阅读
0

我想为具有 containerd 运行时的 Amazon Elastic Kubernetes Service (Amazon EKS) 节点自动配置 HTTP 代理。

简短描述

您可以使用自定义启动模板自动为 Amazon EKS 节点配置 HTTP 代理,该模板在用户数据中包含代理设置。配置方法因您的 AMI 系列而异: Amazon Linux 2、Amazon Linux 2023 或 Bottlerocket。

**注意:**对于 Amazon EKS 集群 1.24 及更高版本,containerd 是默认的容器运行时。

解决方法

要为您的托管节点组配置 HTTP 代理设置,请使用您的亚马逊机器映像 (AMI) ID 创建自定义启动模板。然后,为您的 HTTP 代理和集群的环境值配置相应的设置。

根据您的 AMI 系列选择配置方法:

为 Amazon Linux 2 节点配置 HTTP 代理

创建启动模板

  1. 打开 Amazon Elastic Compute Cloud (Amazon EC2) 控制台
  2. 在导航窗格中,选择 Launch Templates(启动模板)。
  3. 选择 Create launch template(创建启动模板)。
  4. 对于 Launch template name(启动模板名称),为您的模板输入名称。
  5. 对于 Application and OS Images (Amazon Machine Image)(应用程序和操作系统映像(亚马逊机器映像)),选择您的 Amazon Linux 2 AMI ID。
  6. 配置以下选项:
    对于 Instance type(实例类型),选择所需的实例类型。
    对于 Key pair name(密钥对名称),选择您的 Amazon EC2 SSH 密钥对。
    对于 Security groups(安全组),选择您的安全组。
  7. 展开 Advanced details(高级详细信息)。
  8. 对于 User data(用户数据),输入以下配置:
    MIME-Version: 1.0
    Content-Type: multipart/mixed; boundary="==BOUNDARY=="
    
    --==BOUNDARY==
    Content-Type: text/cloud-boothook; charset="us-ascii"
    
    #Set the proxy hostname and port
    PROXY=XXXXXXX:3128
    TOKEN=`curl -X PUT "http://[IP_ADDRESS]/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
    MAC=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v -s http://[IP_ADDRESS]/latest/meta-data/mac/)
    VPC_CIDR=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v -s http://[IP_ADDRESS]/latest/meta-data/network/interfaces/macs/$MAC/vpc-ipv4-cidr-blocks | xargs | tr ' ' ',')
    
    #Create the containerd and sandbox-image systemd directory
    mkdir -p /etc/systemd/system/containerd.service.d
    mkdir -p /etc/systemd/system/sandbox-image.service.d
    
    #[Optional] 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,[IP_ADDRESS],[IP_ADDRESS],[IP_ADDRESS],.internal,.eks.amazonaws.com
    NO_PROXY=$VPC_CIDR,[IP_ADDRESS],[IP_ADDRESS],[IP_ADDRESS],.internal,.eks.amazonaws.com
    EOF
    
    #Configure Containerd with the proxy
    cloud-init-per instance containerd_proxy_config tee <<EOF /etc/systemd/system/containerd.service.d/http-proxy.conf >/dev/null
    [Service]
    EnvironmentFile=/etc/environment
    EOF
    
    #Configure sandbox-image with the proxy
    cloud-init-per instance sandbox-image_proxy_config tee <<EOF /etc/systemd/system/sandbox-image.service.d/http-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
    
    cloud-init-per instance reload_daemon systemctl daemon-reload
    
    --==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
    
    #Run the bootstrap.sh script
    B64_CLUSTER_CA=YOUR_CLUSTER_CA
    API_SERVER_URL=API_SERVER_ENDPOINT
    
    /etc/eks/bootstrap.sh EKS_CLUSTER_NAME --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL
    
    --==BOUNDARY==--
    **注意:**将 XXXXXXX:3128 替换为您的代理主机名和端口。将 YOUR_CLUSTER_CA 替换为您的集群证书颁发机构 (CA)。将 YOUR_CLUSTER_CA 替换为您的服务器端点。将 EKS_CLUSTER_NAME 替换为您的集群名称。
  9. 选择 Create launch template(创建启动模板)。

验证配置

使用启动模板创建托管节点组后,请验证代理配置:

  1. 要查看您的节点状态,请运行以下命令:

    kubectl get nodes -o wide
  2. 要验证代理环境变量是否已设置,请连接到节点并运行以下命令:

    systemctl show containerd | grep Environment

输出显示为 containerd 配置的代理环境变量。

为 Amazon Linux 2023 节点配置 HTTP 代理

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

Amazon Linux 2023 引入了一个新的节点初始化进程 nodeadm,它使用 YAML 配置架构。对于此进程,nodeadm 分为两个阶段运行:config 和 run。nodeadm-config 阶段在 cloud-init 之前运行,而 nodeadm-runcloud-init 之后运行。

nodeadm-config 阶段,系统会调用 Amazon EC2 服务来检索实例详细信息。要在配置代理设置之前阻止 Amazon EC2 调用,请使用 nodeadm 中的 InstanceIdNodeName 特性门控。

创建 Worker 节点 IAM 角色

  1. 创建新的 Worker 节点 AWS Identity and Access Management (IAM) 角色并附加所需策略。

  2. 使用以下选项之一为 Worker 节点 IAM 角色提供相应的访问权限:

    选项 1: 创建 EKS 访问条目
    要创建 EC2 类型的访问条目,请运行以下 AWS CLI 命令 create-access-entry

    aws eks create-access-entry --cluster-name EKS_CLUSTER_NAME --principal-arn WORKER_NODE_IAM_ROLE_ARN --type EC2

    **注意:**将 EKS_CLUSTER_NAME 替换为您的集群名称。将 WORKER_NODE_IAM_ROLE_ARN 替换为您的 Worker 节点 IAM 角色 ARN。

    选项 2: 更新 aws-auth ConfigMap
    将以下配置以 YAML 格式添加到您的 aws-auth ConfigMap 中:

    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: ROLE_ARN
      username: system:node:{{SessionName}}

    **注意:**将 ROLE_ARN 替换为您的 Worker 节点 IAM 角色 ARN。此配置向 Worker 节点 IAM 角色授予必要的 Kubernetes RBAC 权限。

创建启动模板

  1. 打开 Amazon EC2 控制台
  2. 在导航窗格中,选择 Launch Templates(启动模板)。
  3. 选择 Create launch template(创建启动模板)。
  4. 对于 Launch template name(启动模板名称),为您的模板输入名称。
  5. 对于 Application and OS Images (Amazon Machine Image)(应用程序和操作系统映像(亚马逊机器映像)),选择您的 Amazon Linux 2023 AMI ID。
  6. 配置以下选项:
    对于 Instance type(实例类型),选择所需的实例类型。
    对于 Key pair name(密钥对名称),选择您的 Amazon EC2 SSH 密钥对。
    对于 Security groups(安全组),选择您的安全组。
  7. 展开 Advanced details(高级详细信息)。
  8. 对于 User data(用户数据),输入以下配置:
    MIME-Version: 1.0
    Content-Type: multipart/mixed; boundary="==BOUNDARY=="
    
    --==BOUNDARY==
    Content-Type: text/cloud-boothook; charset="us-ascii"
    
    #!/bin/bash
    
    #Set the proxy hostname and port
    PROXY=XXXXXXX:3128
    TOKEN=`curl -X PUT "http://[IP_ADDRESS]/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
    MAC=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v -s http://[IP_ADDRESS]/latest/meta-data/mac/)
    VPC_CIDR=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v -s http://[IP_ADDRESS]/latest/meta-data/network/interfaces/macs/$MAC/vpc-ipv4-cidr-blocks | xargs | tr ' ' ',')
    
    #[Optional] 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,[IP_ADDRESS],[IP_ADDRESS],[IP_ADDRESS],.internal,.eks.amazonaws.com
    NO_PROXY=$VPC_CIDR,[IP_ADDRESS],[IP_ADDRESS],[IP_ADDRESS],.internal,.eks.amazonaws.com
    EOF
    
    #Configure Containerd with the proxy
    cloud-init-per instance containerd_proxy_config tee <<EOF /etc/systemd/system/containerd.service.d/http-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
    
    cloud-init-per instance reload_daemon systemctl daemon-reload
    
    --==BOUNDARY==
    Content-Type: application/node.eks.aws
    
    ---
    apiVersion: node.eks.aws/v1alpha1
    kind: NodeConfig
    spec:
      featureGates:
        InstanceIdNodeName: true
      cluster:
        name: EKS_CLUSTER_NAME
        apiServerEndpoint: API_SERVER_ENDPOINT
        certificateAuthority: YOUR_CLUSTER_CA
        cidr: KUBERNETES_SERVICE_CIDR_RANGE
    
    --==BOUNDARY==--
    **注意:**将 XXXXXXX:3128 替换为您的代理主机名和端口。将 YOUR_CLUSTER_CA 替换为您的集群证书颁发机构 (CA)。将 YOUR_CLUSTER_CA 替换为您的服务器端点。将 EKS_CLUSTER_NAME 替换为您的集群名称。将 KUBERNETES_SERVICE_CIDR_RANGE 替换为您的集群的服务 CIDR 范围。如果用户数据中未提供服务 CIDR,则 nodeadm-config 阶段将失败。
  9. 选择 Create launch template(创建启动模板)。

验证配置

使用启动模板创建托管节点组后,请验证代理配置:

  1. 要查看您的节点状态,请运行以下命令:

    kubectl get nodes -o wide
  2. 要验证代理环境变量是否已设置,请连接到节点并运行以下命令:

    systemctl show containerd | grep Environment

输出显示为 containerd 配置的代理环境变量。

为 Bottlerocket 节点配置 HTTP 代理

创建启动模板

  1. 打开 Amazon EC2 控制台

  2. 在导航窗格中,选择 Launch Templates(启动模板)。

  3. 选择 Create launch template(创建启动模板)。

  4. 对于 Launch template name(启动模板名称),为您的模板输入名称。

  5. 对于 Application and OS Images (Amazon Machine Image)(应用程序和操作系统映像(亚马逊机器映像)),选择您的 Bottlerocket AMI ID。

  6. 配置以下选项:
    对于 Instance type(实例类型),选择所需的实例类型。
    对于 Key pair name(密钥对名称),选择您的 Amazon EC2 SSH 密钥对。
    对于 Security groups(安全组),选择您的安全组。

  7. 展开 Advanced details(高级详细信息)。

  8. 对于 User data(用户数据),输入以下配置:

    [settings.kubernetes]
    "cluster-name" = "EKS_CLUSTER_NAME"
    "api-server" = "API_SERVER_ENDPOINT"
    "cluster-certificate" = "YOUR_CLUSTER_CA"
    
    [settings.network]
    no-proxy = ["VPC_CIDR_RANGE","[IP_ADDRESS]","[IP_ADDRESS]","[IP_ADDRESS]",".internal",".eks.amazonaws.com"]
    https-proxy = "XXXXXXX:3128"

    **注意:**将 XXXXXXX:3128 替换为您的代理主机名和端口。将 YOUR_CLUSTER_CA 替换为您的集群证书颁发机构 (CA)。将 YOUR_CLUSTER_CA 替换为您的服务器端点。将 EKS_CLUSTER_NAME 替换为您的集群名称。将 VPC_CIDR_RANGE 替换为您的 VPC CIDR。Bottlerocket 会自动为 containerd 和 kubelet 服务配置代理设置。

    要向您的 Bottlerocket 实例添加自签名证书,请在用户数据部分使用以下配置:

    [settings.pki.proxy-bundle]
    data="ENCODED_CA_DATA"
    trusted=true

    **注意:**将 ENCODED_CA_DATA 替换为 base64 编码的证书数据。

    要对您的证书文件进行编码,请运行以下命令:

    base64 -i FILE -w0
  9. 选择 Create launch template(创建启动模板)。

验证配置

使用启动模板创建托管节点组后,请验证代理配置:

  1. 要查看您的节点状态,请运行以下命令:

    kubectl get nodes -o wide
  2. 要验证代理设置,请使用 AWS Systems Manager 会话管理器连接到 Bottlerocket 节点并运行以下命令:

    apiclient get settings.network

输出显示为该节点配置的代理设置。

创建托管节点组

在创建启动模板后,请创建一个使用该自定义启动模板的新托管节点组。

有关使用启动模板创建托管节点组的更多信息,请参阅使用启动模板自定义托管节点

为完全私有集群配置代理

**重要事项:**当您将 EKS 容器组身份关联与代理配置一起使用时,还必须在您的 no_proxy/NO_PROXY 环境变量中包含 [IP_ADDRESS] (IPv4) 或 [[IP_ADDRESS]] (IPv6)。

具有私有 API 服务器端点访问权限、私有子网且没有互联网访问权限的 Amazon EKS 集群需要额外的端点。如果您使用上述配置构建集群,则必须为以下服务创建并添加端点:

  • Amazon EC2
  • 用于拉取容器映像的 Amazon Elastic Container Registry
  • 适用于应用程序负载均衡器和网络负载均衡器的 Amazon Elastic Load Balancing
  • Amazon CloudWatch Logs
  • 将 IAM 角色用于服务账户时的 AWS Security Token Service
  • 使用容器组身份关联时的 Amazon EKS Auth
  • Amazon EKS

在创建这些端点后,请在您的 Amazon EC2 实例启动模板用户数据中配置 NO_PROXYno_proxy 变量。包括特定于您的 AWS 区域和服务的公有端点子域。

例如:

对于 Amazon Simple Storage Service (Amazon S3):

  • 如果您的存储桶位于 us-east-1,则添加:.s3.us-east-1.amazonaws.com
  • 如果您的存储桶位于 eu-west-1,则添加:.s3.eu-west-1.amazonaws.com

对于使用私有端点访问时的 Amazon EKS:

  • 如果您的集群位于 us-east-1,则添加:.us-east-1.eks.amazonaws.com
  • 如果您的集群位于 eu-west-1,则添加:.eu-west-1.eks.amazonaws.com

**注意:**请将区域标识符替换为您部署资源的 AWS 区域,并将这些端点同时添加到 NO_PROXYno_proxy 变量中。根据您集群的工作负载和附加组件,向代理配置中添加其他服务。

为公共集群配置代理

**注意:**如果您有不同的配置,则这些步骤是可选的。

如果您通过 HTTP 代理将流量从集群路由到互联网,并且您的 Amazon EKS 端点为公有端点,请完成以下任务。

创建 ConfigMap 来配置环境值:

apiVersion: v1
kind: ConfigMap
metadata:
  name: proxy-environment-variables
  namespace: kube-system

data:
  HTTP_PROXY: http://XXXXXXX:3128
  HTTPS_PROXY: http://XXXXXXX:3128
  NO_PROXY: KUBERNETES_SERVICE_CIDR_RANGE,[IP_ADDRESS],[IP_ADDRESS],VPC_CIDR_RANGE,[IP_ADDRESS],.internal,.eks.amazonaws.com,ec2.us-east-1.amazonaws.com
  no_proxy: KUBERNETES_SERVICE_CIDR_RANGE,[IP_ADDRESS],[IP_ADDRESS],VPC_CIDR_RANGE,[IP_ADDRESS],.internal,.eks.amazonaws.com,ec2.us-east-1.amazonaws.com

**注意:**将 KUBERNETES_SERVICE_CIDR_RANGEVPC_CIDR_RANGE 替换为 CIDR 范围的值。在创建 VPC 端点(Amazon EKS 和 Amazon EC2)后,请向 NO_PROXY 和 no_proxy 添加 AWS 服务端点。

应用 ConfigMap:

kubectl apply -f proxy-configmap.yaml

配置 aws-node 和 kube-proxy

要将您的 HTTP 代理配置设置为 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

验证代理配置

要验证代理配置是否正常运行,请完成以下步骤:

  1. 要查看您的节点状态,请运行以下命令:

    kubectl get nodes -o wide
  2. 要通过代理测试容器组 (pod) 连接,请运行以下命令:

    kubectl run test-pod --image=amazonlinux:2 --restart=Never -- sleep 300
    kubectl get pods -A
  3. 查看您的代理日志,了解有关节点连接的更多信息。日志应显示与容器注册表端点的成功连接 (TCP_TUNNEL/200)。
    输出示例:

    192.168.100.114 TCP_TUNNEL/200 6230 CONNECT registry-1.docker.io:443 - HIER_DIRECT/XX.XX.XX.XX -
    192.168.100.114 TCP_TUNNEL/200 10359 CONNECT auth.docker.io:443 - HIER_DIRECT/XX.XX.XX.XX -

相关信息

从 Amazon Linux 2 升级到 Amazon Linux 2023

创建自行管理的 Bottlerocket 节点

使用 EKS 访问条目授予 IAM 用户访问 Kubernetes 的权限

AWS 官方已更新 7 个月前