

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 增加 Amazon EKS 节点的可用 IP 地址
<a name="cni-increase-ip-addresses-procedure"></a>

您可以通过分配 IP 前缀而不是为节点分配单个辅助 IP 地址，来增加节点可以分配给容器组（pod）的 IP 地址数量。

## 先决条件
<a name="_prerequisites"></a>
+ 您需要现有集群。要部署一个角色，请参阅[创建一个 Amazon EKS 集群。](create-cluster.md)。
+ 您的 Amazon EKS 节点所在的子网必须有足够的连续 `/28`（适用于 `IPv4` 集群）或 `/80`（适用于 `IPv6` 集群）无类别域间路由 (CIDR) 块。`IPv6` 集群中只能有 Linux 节点。如果 IP 地址分散在整个子网 CIDR 中，则使用 IP 前缀可能会失败。我们建议执行下列操作：
  + 使用子网 CIDR 预留，这样即使保留范围内的任何 IP 地址仍在使用，在其释放后，这些 IP 地址也不会重新分配。这样可以确保前缀在不分段的情况下进行分配。
  + 使用专门用于运行分配 IP 前缀的工作负载的新子网。分配 IP 前缀时，Windows 和 Linux工作负载可以在同一个子网中运行。
+ 要为节点分配 IP 前缀，您的节点必须基于 Amazon Nitro。不基于 Nitro 的实例会继续分配单个辅助 IP 地址，但分配给容器组（pod）的 IP 地址数量比基于 Nitro 的实例少得多。
+  **仅适用于具有 Linux 节点的集群** – 如果集群针对 `IPv4` 系列配置，则必须安装适用于 Kubernetes 附加组件的 Amazon VPC CNI 插件的版本 `1.9.0` 或更高版本。您可以使用以下命令检查当前版本。

  ```
  kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
  ```

  如果您的集群是针对 `IPv6` 系列配置的，则必须安装附加组件的 `1.10.1` 版。如果您的插件版本低于所需版本，则必须进行更新。要了解更多信息，请参阅[向具有 Amazon VPC CNI 的容器组（pod）分配 IP](managing-vpc-cni.md) 的更新部分。
+  **仅适用于具有 Windows 节点的集群** 
  + 必须为集群启用 Windows 支持。有关更多信息，请参阅 [在 EKS 集群上部署 Windows 节点](windows-support.md)。

## 将 IP 地址前缀分配给节点
<a name="cni-increase-ip-procedure"></a>

配置集群以将 IP 地址前缀分配给节点。完成与节点的操作系统相匹配的步骤。

### Linux
<a name="_linux"></a>

1. 启用参数，以便为 Amazon VPC CNI DaemonSet 的网络接口分配前缀。部署集群时，版本 `1.10.1` 或更高版本的适用于 Kubernetes 附加组件的 Amazon VPC CNI 插件随之部署。如果您使用 `IPv6` 系列创建集群，这个设置将被默认设置为 `true`。如果您使用 `IPv4` 系列创建集群，这个设置将被默认设置为 `false`。

   ```
   kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
   ```
**重要**  
即使子网有可用的 IP 地址，如果子网没有任何连续 `/28` 数据块可用，您还是会在适用于 Kubernetes 的 Amazon VPC CNI 插件日志中看到以下错误。  

   ```
   InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks to satisfy the request
   ```
发生这种情况的原因可能是分散在子网中的现有辅助 IP 地址的碎片。要解决此错误，请创建一个新子网并在其中启动容器组（pod），或者使用 Amazon EC2 子网 CIDR 预留，在子网中预留空间以便与前缀分配结合使用。有关更多信息，请参阅《Amazon VPC 用户指南》中的[子网 CIDR 预留](https://docs.amazonaws.cn/vpc/latest/userguide/subnet-cidr-reservation.html)。

1. 如果计划在没有启动模板的情况下部署托管节点组，或者采用尚未在其中指定 AMI ID 的启动模板，并且使用的是在先决条件中列出的适用于 Kubernetes 的 Amazon VPC CNI 插件版本或更高版本，则跳至下一步。托管节点组会自动为您计算最大容器组（pod）数量。

   如果正在部署自主管理型节点组或带有启动模板的托管节点组，且其启动模板已指定 AMI ID，则必须确定 Amazon EKS 为节点推荐的最大容器组（pod）数量。按照 中的说明进行操作，将 `--cni-prefix-delegation-enabled` 添加到步骤 3。请记下输出的内容，以便在下一个步骤中使用。
**重要**  
托管节点组强制执行 `maxPods` 的值的最大数量。对于 vCPUs 少于 30 个的实例，最大数量为 110，对于所有其他实例，最大数量为 250。无论是否启用前缀委派，均应用此最大数量。

1. 如果使用为 `IPv6` 配置的集群，则跳至下一步。

   在以下选项中指定参数。要确定哪个选项适合您以及为其提供哪些值，请参阅 GitHub 上的 [WARM\$1PREFIX\$1TARGET, WARM\$1IP\$1TARGET, and MINIMUM\$1IP\$1TARGET](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/prefix-and-ip-target.md)。

   您可以将示例值替换为大于零的值。
   +  `WARM_PREFIX_TARGET` 

     ```
     kubectl set env ds aws-node -n kube-system WARM_PREFIX_TARGET=1
     ```
   +  `WARM_IP_TARGET` 或 `MINIMUM_IP_TARGET`：如果设置了两种值之一，则其会覆盖所设置的 `WARM_PREFIX_TARGET` 的值。

     ```
     kubectl set env ds aws-node -n kube-system WARM_IP_TARGET=5
     ```

     ```
     kubectl set env ds aws-node -n kube-system MINIMUM_IP_TARGET=2
     ```

1. 使用至少一种 Amazon EC2 Nitro Amazon Linux 2023 实例类型创建以下类型之一的节点组。有关 Nitro 实例类型的列表，请参阅《Amazon EC2 用户指南》中的[基于 Nitro 系统构建的实例](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances)。Windows 中不支持此功能。对于包含 *110* 的选项，将其替换为第 3 步中的值（建议）或您自己的值。
   +  **自行管理** – 按照[创建自行管理的 Amazon Linux 节点](launch-workers.md)中的说明部署节点组。在创建 CloudFormation 堆栈之前，请打开模板文件并将 `NodeLaunchTemplate` 中的 `UserData` 调整为如下所示

     ```
     ...
                 apiVersion: node.eks.aws/v1alpha1
                 kind: NodeConfig
                 spec:
                   cluster:
                     name: ${ClusterName}
                     apiServerEndpoint: ${ApiServerEndpoint}
                     certificateAuthority: ${CertificateAuthorityData}
                     cidr: ${ServiceCidr}
                   kubelet:
                     config:
                       maxPods: 110
     ...
     ```

     如果使用 `eksctl` 创建节点组，可以使用下面的命令。

     ```
     eksctl create nodegroup --cluster my-cluster --managed=false --max-pods-per-node 110
     ```
   +  **托管**：使用以下选项之一部署您的节点组：
     +  **没有启动模板或者没有指定 AMI ID 的启动模板**：完成[为集群创建托管式节点组](create-managed-node-group.md)中的过程。托管节点组会自动为您计算 Amazon EKS 建议的 `max-pods` 值。
     +  **使用具有指定 AMI ID 的启动模板**：在启动模板中，指定 Amazon EKS 优化的 AMI ID，或者指定基于 Amazon EKS 优化 AMI 构建的自定义 AMI，然后[使用启动模板部署节点组](launch-templates.md)并在启动模板中提供以下用户数据。此用户数据传递一个 `NodeConfig` 对象，供 `nodeadm` 工具在节点上读取。有关 `nodeadm` 的详细信息，请参阅 [nodeadm 文档](https://awslabs.github.io/amazon-eks-ami/nodeadm)。

       ```
       MIME-Version: 1.0
       Content-Type: multipart/mixed; boundary="//"
       
       --//
       Content-Type: application/node.eks.aws
       
       ---
       apiVersion: node.eks.aws/v1alpha1
       kind: NodeConfig
       spec:
        cluster:
          apiServerEndpoint: [.replaceable]`my-cluster`
          certificateAuthority: [.replaceable]`LS0t...`
          cidr: [.replaceable]`10.100.0.0/16`
          name: [.replaceable]`my-cluster
        kubelet:
          config:
            maxPods: [.replaceable]`110`
       --//--
       ```

       如果使用 `eksctl` 创建节点组，可以使用下面的命令。

       ```
       eksctl create nodegroup --cluster my-cluster --max-pods-per-node 110
       ```

       如果您创建的自定义 AMI 不是基于 Amazon EKS 优化版 AMI 构建的，则需要自行自定义创建配置。
**注意**  
如果还想将 IP 地址分配给不同于实例子网的容器组（pod），则需要在此步骤中启用该功能。有关更多信息，请参阅 [使用自定义网络在备用子网中部署容器组（pod）](cni-custom-network.md)。

### Windows
<a name="_windows"></a>

1. 启用 IP 前缀的分配。

   1. 打开 `amazon-vpc-cni` `ConfigMap` 进行编辑。

      ```
      kubectl edit configmap -n kube-system amazon-vpc-cni -o yaml
      ```

   1. 将以下行添加到 `data` 部分。

      ```
        enable-windows-prefix-delegation: "true"
      ```

   1. 保存文件，然后关闭编辑器。

   1. 确认该行已添加到 `ConfigMap`。

      ```
      kubectl get configmap -n kube-system amazon-vpc-cni -o "jsonpath={.data.enable-windows-prefix-delegation}"
      ```

      如果返回的输出并非 `true`，则可能存在错误。尝试再次完成该步骤。
**重要**  
即使子网有可用的 IP 地址，如果子网没有任何连续 `/28` 数据块可用，您还是会在适用于 Kubernetes 的 Amazon VPC CNI 插件日志中看到以下错误。  

      ```
      InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks to satisfy the request
      ```
发生这种情况的原因可能是分散在子网中的现有辅助 IP 地址的碎片。要解决此错误，请创建一个新子网并在其中启动容器组（pod），或者使用 Amazon EC2 子网 CIDR 预留，在子网中预留空间以便与前缀分配结合使用。有关更多信息，请参阅《Amazon VPC 用户指南》中的[子网 CIDR 预留](https://docs.amazonaws.cn/vpc/latest/userguide/subnet-cidr-reservation.html)。

1. （可选）指定其他配置以控制集群的预扩展和动态扩展行为。有关更多信息，请参阅 GitHub 上的[在 Windows 上使用前缀委派模式的配置选项](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/docs/windows/prefix_delegation_config_options.md)。

   1. 打开 `amazon-vpc-cni` `ConfigMap` 进行编辑。

      ```
      kubectl edit configmap -n kube-system amazon-vpc-cni -o yaml
      ```

   1. 用大于零的值替换示例值，然后将所需的条目添加到 `ConfigMap` 的 `data` 部分。如果您为 `warm-ip-target` 或 `minimum-ip-target` 设置了值，则该值将覆盖为 `warm-prefix-target` 设置的任何值。

      ```
        warm-prefix-target: "1"
        warm-ip-target: "5"
        minimum-ip-target: "2"
      ```

   1. 保存文件，然后关闭编辑器。

1. 创建至少包含一种 Amazon EC2 Nitro 实例类型的 Windows 节点组。有关 Nitro 实例类型的列表，请参阅《Amazon EC2 用户指南》中的[基于 Nitro 系统构建的实例](https://docs.amazonaws.cn/AWSEC2/latest/WindowsGuide/instance-types.html#ec2-nitro-instances)。默认情况下，可以部署到节点的最大容器组（pod）数量为 110。如果要增加或减少该数量，则请在引导配置的用户数据中指定以下内容。将 *max-pods-quantity* 替换为最大容器组（pod）值。

   ```
   -KubeletExtraArgs '--max-pods=max-pods-quantity'
   ```

   如果您要部署托管节点组，则需要在启动模板中添加此配置。有关更多信息，请参阅 [使用启动模板自定义托管式节点](launch-templates.md)。有关 Windows 引导脚本配置参数的更多信息，请参阅[引导脚本配置参数](eks-optimized-windows-ami.md#bootstrap-script-configuration-parameters)。

## 确定最大容器组（pod）数量和可用的 IP 地址
<a name="cni-increase-ip-verify"></a>

1. 节点部署完成后，请查看集群中的节点。

   ```
   kubectl get nodes
   ```

   示例输出如下。

   ```
   NAME                                             STATUS     ROLES    AGE   VERSION
   ip-192-168-22-103.region-code.compute.internal   Ready      <none>   19m   v1.XX.X-eks-6b7464
   ip-192-168-97-94.region-code.compute.internal    Ready      <none>   19m   v1.XX.X-eks-6b7464
   ```

1. 描述其中一个节点以确定该节点的 `max-pods` 值和可用 IP 地址数量。将 *192.168.30.193* 替换为之前输出中返回的其中一个节点名称中的 `IPv4` 地址。

   ```
   kubectl describe node ip-192-168-30-193.region-code.compute.internal | grep 'pods\|PrivateIPv4Address'
   ```

   示例输出如下。

   ```
   pods:                                  110
   vpc.amazonaws.com/PrivateIPv4Address:  144
   ```

   在之前的输出中，尽管有 *144* 个 IP 地址可用，但 `110` 是 Kubernetes 将部署到节点的最大容器组（pod）数量。