

 **帮助改进此页面** 

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

# 为 Amazon EKS 创建节点类
<a name="create-node-class"></a>

Amazon EKS 节点类是模板，可对 EKS 自动模式托管式节点的配置进行精细控制。节点类定义了适用于 EKS 集群中节点组的基础设施级别设置，包括网络配置、存储设置和资源标记等。本主题旨在介绍如何创建和配置节点类以满足您的具体运行要求。

如果需要在默认设置之外自定义 EKS 自动模式预置和配置 EC2 实例的方式，创建节点类可让您精准控制关键基础设施参数。例如，您可以指定私有子网放置来增强安全性，为性能敏感型工作负载配置实例临时存储，或者应用自定义标记以满足成本分配的需要。

## 创建节点类
<a name="_create_a_node_class"></a>

要创建 `NodeClass`，请按以下步骤操作：

1. 创建一个包含节点类配置的 YAML 文件（例如 `nodeclass.yaml`）

1. 使用 `kubectl` 将此配置应用到集群 

1. 在节点池配置中引用该节点类。有关更多信息，请参阅 [为 EKS 自动模式创建节点池](create-node-pool.md)。

您需要已经安装并配置好 `kubectl`。有关更多信息，请参阅 [进行设置以使用 Amazon EKS](setting-up.md)。

### 基本节点类示例
<a name="_basic_node_class_example"></a>

以下是一个节点类示例：

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: private-compute
spec:
  subnetSelectorTerms:
    - tags:
        Name: "private-subnet"
        kubernetes.io/role/internal-elb: "1"
  securityGroupSelectorTerms:
    - tags:
        Name: "eks-cluster-sg"
  ephemeralStorage:
    size: "160Gi"
```

此节点类增加了节点上的临时存储量。

使用以下命令应用此配置：

```
kubectl apply -f nodeclass.yaml
```

然后在节点池配置中引用该节点类。有关更多信息，请参阅 [为 EKS 自动模式创建节点池](create-node-pool.md)。

## 创建节点类访问条目
<a name="auto-node-access-entry"></a>

如果您创建自定义节点类，则需要创建 EKS 访问条目以允许节点加入集群。如果您使用内置节点类和节点池，EKS 会自动创建访问条目。

有关访问条目工作原理的信息，请参阅[使用 EKS 访问条目向 IAM 用户授予 Kubernetes 访问权限](access-entries.md)。

为 EKS 自动模式节点类创建访问条目时，需要使用 `EC2` 访问条目类型。

### 使用 CLI 创建访问条目
<a name="_create_access_entry_with_cli"></a>

 **要为 EC2 节点创建访问条目并关联 EKS 自动节点策略，请执行以下操作：**

使用集群名称和节点角色 ARN 更新以下 CLI 命令。在节点类 YAML 中指定节点角色 ARN。

```
# Create the access entry for EC2 nodes
aws eks create-access-entry \
  --cluster-name <cluster-name> \
  --principal-arn <node-role-arn> \
  --type EC2

# Associate the auto node policy
aws eks associate-access-policy \
  --cluster-name <cluster-name> \
  --principal-arn <node-role-arn> \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSAutoNodePolicy \
  --access-scope type=cluster
```

### 使用 CloudFormation 创建访问条目
<a name="_create_access_entry_with_cloudformation"></a>

 **要为 EC2 节点创建访问条目并关联 EKS 自动节点策略，请执行以下操作：**

使用集群名称和节点角色 ARN 更新以下 CloudFormation。在节点类 YAML 中指定节点角色 ARN。

```
EKSAutoNodeRoleAccessEntry:
  Type: AWS::EKS::AccessEntry
  Properties:
    ClusterName: <cluster-name>
    PrincipalArn: <node-role-arn>
    Type: "EC2"
    AccessPolicies:
      - AccessScope:
          Type: cluster
        PolicyArn: arn:aws:eks::aws:cluster-access-policy/AmazonEKSAutoNodePolicy
  DependsOn: [ <cluster-name> ] # previously defined in CloudFormation
```

有关部署 CloudFormation 堆栈的信息，请参阅 [CloudFormation 入门](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/GettingStarted.html) 

## 节点类规范
<a name="auto-node-class-spec"></a>

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: my-node-class
spec:
  # Required fields

  # role and instanceProfile are mutually exclusive fields.
  role: MyNodeRole  # IAM role for EC2 instances
  # instanceProfile: eks-MyNodeInstanceProfile  # IAM instance-profile for EC2 instances

  subnetSelectorTerms:
    - tags:
        Name: "private-subnet"
        kubernetes.io/role/internal-elb: "1"
    # Alternative using direct subnet ID
    # - id: "subnet-0123456789abcdef0"

  securityGroupSelectorTerms:
    - tags:
        Name: "eks-cluster-sg"
    # Alternative approaches:
    # - id: "sg-0123456789abcdef0"
    # - name: "eks-cluster-security-group"

  # Optional: Pod subnet selector for advanced networking
  podSubnetSelectorTerms:
    - tags:
        Name: "pod-subnet"
        kubernetes.io/role/pod: "1"
    # Alternative using direct subnet ID
    # - id: "subnet-0987654321fedcba0"
  # must include Pod security group selector also
  podSecurityGroupSelectorTerms:
    - tags:
        Name: "eks-pod-sg"
    # Alternative using direct security group ID
    # - id: "sg-0123456789abcdef0"

  # Optional: Selects on-demand capacity reservations and capacity blocks
  # for EKS Auto Mode to prioritize.
  capacityReservationSelectorTerms:
    - id: cr-56fac701cc1951b03
    # Alternative Approaches
    - tags:
        Name: "targeted-odcr"
      # Optional owning account ID filter
      owner: "012345678901"

  # Optional fields
  snatPolicy: Random  # or Disabled

  networkPolicy: DefaultAllow  # or DefaultDeny
  networkPolicyEventLogs: Disabled  # or Enabled

  ephemeralStorage:
    size: "80Gi"    # Range: 1-59000Gi or 1-64000G or 1-58Ti or 1-64T
    iops: 3000      # Range: 3000-16000
    throughput: 125 # Range: 125-1000
    # Optional KMS key for encryption
    kmsKeyID: "arn:aws:kms:region:account:key/key-id"
    # Accepted formats:
    # KMS Key ID
    # KMS Key ARN
    # Key Alias Name
    # Key Alias ARN

  advancedNetworking:
    # Optional: Controls whether public IP addresses are assigned to instances that are launched with the nodeclass.
    # If not set, defaults to the MapPublicIpOnLaunch setting on the subnet.
    associatePublicIPAddress: false

    # Optional: Forward proxy, commonly requires certificateBundles as well
    # for EC2, see https://repost.aws/knowledge-center/eks-http-proxy-containerd-automation
    httpsProxy: http://192.0.2.4:3128 #commonly port 3128 (Squid) or 8080 (NGINX) #Max 255 characters
    #httpsProxy: http://[2001:db8::4]:3128 # IPv6 address with port, use []
    noProxy: #Max 50 entries
        - localhost #Max 255 characters each
        - 127.0.0.1
        #- ::1 # IPv6 localhost
        #- 0:0:0:0:0:0:0:1 # IPv6 localhost
        - 169.254.169.254 # EC2 Instance Metadata Service
        #- [fd00:ec2::254] # IPv6 EC2 Instance Metadata Service
        # Domains to exclude, put all VPC endpoints here
        - .internal
        - .eks.amazonaws.com
    # ipv4PrefixSize is default to Auto which is prefix and fallback to secondary IP. "32" is the secondary IP mode.
    ipv4PrefixSize: Auto # or "32"

    # enableV4Egress is default to true. Setting it to false when using network policy or blocking IPv4 traffic in IPv6 clusters
    enableV4Egress: false

  advancedSecurity:
    # Optional, US regions only: Specifying `fips: true` will cause nodes in the nodeclass to run FIPS compatible AMIs.
    fips: false

  # Optional: Custom certificate bundles.
  certificateBundles:
    - name: "custom-cert"
      data: "base64-encoded-cert-data"

  # Optional: Additional EC2 tags (with restrictions)
  tags:
    Environment: "production"
    Team: "platform"
    # Note: Cannot use restricted tags like:
    # - kubernetes.io/cluster/*
    # - karpenter.sh/provisioner-name
    # - karpenter.sh/nodepool
    # - karpenter.sh/nodeclaim
    # - karpenter.sh/managed-by
    # - eks.amazonaws.com/nodeclass
```

## 注意事项
<a name="_considerations"></a>
+ 如果要验证实例的本地存储空间大小，您可以描述该节点以查看临时存储资源。
+  **卷加密**：EKS 使用配置的自定义 KMS 密钥来加密实例的只读根卷和读/写数据卷。
+  **替换节点 IAM 角色** – 如果您更改与 `NodeClass` 关联的节点 IAM 角色，则需要创建一个新的访问条目。在创建集群期间，EKS 会自动为节点 IAM 角色创建一个访问条目。节点 IAM 角色需要具有 `AmazonEKSAutoNodePolicy` EKS 访问策略。有关更多信息，请参阅 [使用 EKS 访问条目向 IAM 用户授予 Kubernetes 访问权限](access-entries.md)。
+  **最大容器组（pod）密度**：在 EKS 中，一个节点上最多可以有 110 个容器组（pod）。此限制将在计算现有最大容器组（pod）数量之后应用。有关更多信息，请参阅 [选择最优的 Amazon EC2 节点实例类型](choosing-instance-type.md)。
+  **标签** – 如果要将标签从 Kubernetes 传播到 EC2，则需要配置额外的 IAM 权限。有关更多信息，请参阅 [了解 EKS 自动模式中的身份和访问权限](auto-learn-iam.md)。
+  **默认节点类** – 不要将自定义节点类命名为 `default`。这是因为 EKS 自动模式包含一个名为 `default` 的 `NodeClass`，您启用至少一个内置 `NodePool` 时，系统会自动预置该节点类。有关启用内置 `NodePools` 的信息，请参阅[启用或禁用内置节点池](set-builtin-node-pools.md)。
+  **多个子网的 `subnetSelectorTerms` 行为** – 如果存在多个符合 `subnetSelectorTerms` 条件或您按照 ID 提供的子网，则 EKS 自动模式会创建分布在子网中的节点。
  + 如果子网位于不同的可用区（AZ），则可以使用 Kubernetes 功能 [例如[容器组（pod）拓扑分布约束](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#pod-topology-spread-constraints)和[拓扑感知路由](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)] 分别在各个区域之间分布容器组（pod）和流量。
  + 如果*同一个可用区中*有多个子网与 `subnetSelectorTerms` 匹配，则 EKS 自动模式会在分布在该可用区子网中的每个节点上创建容器组（pod）。EKS 自动模式在同一可用区内其他子网中的每个节点上创建辅助网络接口。它根据每个子网中可用 IP 地址的数量进行选择，以便更高效地使用子网。但是，您无法指定 EKS 自动模式为每个容器组（pod）使用哪个子网；如果您需要容器组（pod）在特定子网中运行，请改用 [为容器组（pod）配置独立的子网和安全组](#pod-subnet-selector)。

## 为容器组（pod）配置独立的子网和安全组
<a name="pod-subnet-selector"></a>

`podSubnetSelectorTerms` 和 `podSecurityGroupSelectorTerms` 字段允许容器组（pod）在与其节点不同的子网和安全组中运行，从而实现高级联网配置。两个字段必须同时指定。这种分离增强了对网络流量路由和安全策略的控制。

**注意**  
此功能不同于用于非 EKS Auto Mode 计算环境中与 AWS VPC CNI 配合使用的[容器组（pod）安全组](security-groups-for-pods.md)（SGPP）功能。EKS Auto Mode 不支持 SGPP。如需为容器组（pod）流量应用不同的安全组，请改用 `NodeClass` 中的 `podSecurityGroupSelectorTerms`。安全组在 `NodeClass` 级别生效，这意味着使用该 `NodeClass` 的节点上的所有容器组（pod）共享相同的容器组（pod）安全组。

### 工作原理
<a name="_how_it_works"></a>

在配置 `podSubnetSelectorTerms` 和 `podSecurityGroupSelectorTerms` 时：

1. 节点的主要 ENI 使用来自 `subnetSelectorTerms` 和 `securityGroupSelectorTerms` 的子网与安全组。该接口仅分配节点自身的 IP 地址。

1. EKS Auto Mode 在与 `podSubnetSelectorTerms` 匹配的子网中创建辅助 ENI，并附加 `podSecurityGroupSelectorTerms` 中的安全组。默认情况下，容器组（pod）IP 地址从这些辅助 ENI 中以 /28 前缀分配，当连续前缀块不可用时，自动回退到辅助 IP（/32）。如果 `advancedNetworking` 中的 `ipv4PrefixSize` 设置为 `"32"`，则仅使用辅助 IP。

1. `podSecurityGroupSelectorTerms` 中指定的安全组适用于 VPC 内的容器组（pod）流量。对于发往 VPC 之外的流量，Pod 使用节点的主 ENI（及其安全组），因为源网络地址转换 (SNAT) 会将容器组（pod）IP 转换为节点 IP。您可以通过 `NodeClass` 中的 `snatPolicy` 字段修改此行为。

### 使用案例
<a name="_use_cases"></a>

在以下场景中，使用 `podSubnetSelectorTerms` 和 `podSecurityGroupSelectorTerms`：
+ 应用不同的安全组分别控制节点和容器组（pod）的流量。
+ 需要将基础设施流量（节点间通信）与应用流量（容器组（pod）间通信）分开。
+ 对节点子网应用与容器组（pod）子网不同的网络配置。
+ 在不影响容器组（pod）流量的情况下，专门为节点流量配置反向代理或网络筛选。使用 `advancedNetworking` 和 `certificateBundles` 定义您的反向代理以及代理的任何自签名证书或私有证书。

### 示例配置
<a name="_example_configuration"></a>

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: advanced-networking
spec:
  role: MyNodeRole

  # Subnets and security groups for EC2 instances (nodes)
  subnetSelectorTerms:
    - tags:
        Name: "node-subnet"
        kubernetes.io/role/internal-elb: "1"

  securityGroupSelectorTerms:
    - tags:
        Name: "eks-cluster-sg"

  # Separate subnets and security groups for Pods
  podSubnetSelectorTerms:
    - tags:
        Name: "pod-subnet"
        kubernetes.io/role/pod: "1"

  podSecurityGroupSelectorTerms:
  - tags:
      Name: "eks-pod-sg"
```

### 为容器组（pod）配置独立子网和安全组的注意事项
<a name="_considerations_for_separate_pod_subnets_and_security_groups"></a>
+  **安全组范围**：`podSecurityGroupSelectorTerms` 中的安全组附加到辅助 ENI，适用于 VPC 内的容器组（pod）流量。当 SNAT 启用时（默认 `snatPolicy: Random`），离开 VPC 的流量会转换为节点主 ENI 的 IP 地址，因此节点的 `securityGroupSelectorTerms` 安全组将应用于此类流量。如果您设置 `snatPolicy: Disabled`，容器组（pod）将使用自己的 IP 地址来处理所有流量，此时必须确保路由和安全组已相应配置。
+  **NodeClass 级别的粒度**：容器组（pod）安全组适用于调度到使用 `NodeClass` 的节点上的所有容器组（pod） 如需为不同工作负载应用不同的安全组，请创建独立的 `NodeClass` 和 `NodePool` 资源，并使用污点、容忍度或节点选择器将工作负载调度到合适的节点。
+  **降低容器组（pod）密度**：每个节点上可运行的容器组（pod）数量减少，因为节点的主网络接口预留给节点 IP，无法用于容器组（pod）。
+  **子网选择器限制**：标准 `subnetSelectorTerms` 和 `securityGroupSelectorTerms` 配置不适用于容器组（pod）子网或安全组选择。
+  **网络规划**：确保节点和容器组（pod）子网中有足够的 IP 地址空间，以满足工作负载需求。
+  **路由配置**：验证容器组（pod）子网的路由表和网络访问控制列表（ACL）是否已针对节点和容器组（pod）子网之间的通信进行正确配置。
+  **可用区**：确认已跨多个可用区创建容器组（pod）子网。如果您使用的是特定容器组（pod）子网，则该子网必须与节点子网可用区位于同一可用区中。

## 容器组（pod）的辅助 IP 模式
<a name="secondary-IP-mode"></a>

`ipv4PrefixSize` 字段通过仅为节点分配辅助 IP 地址的方式，实现高级网络配置。此功能不会为节点分配前缀（/28），并且只保留一个辅助 IP 作为 MinimalIPTarget。

### 使用案例
<a name="_use_cases_2"></a>

在需要执行以下操作时使用 `ipv4PrefixSize`：
+  **降低了 IP 利用率**：每个节点中只会预热一个 IP 地址。
+  **降低容器组（pod）流失率**：容器组（pod）的创建速度不是主要问题。
+  **没有前缀分段**：前缀导致的分段是使用自动模式的主要问题或障碍。

### 示例配置
<a name="_example_configuration_2"></a>

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: advanced-networking
spec:
  role: MyNodeRole

  advancedNetworking:
    ipv4PrefixSize: "32"
```

### 辅助 IP 模式的注意事项
<a name="_considerations_for_secondary_ip_mode"></a>
+  **降低了容器组（pod）创建速度**：由于只预热了一个辅助 IP，因此 IPAM 服务需要更多时间在创建更多容器组（pod）时预置 IP。

## 在 IPv6 集群中禁用 IPv6 容器组（pod）的 IPv4 出口。
<a name="enableV4Egress"></a>

默认情况下，`enableV4Egress` 字段为 `true`。对于自动模式 IPv6 集群，该功能可以被禁用，这样一来，自动模式就不会为 IPv6 容器组（pod）创建仅用于出站的 IPv4 接口。IPv4 出口接口不受网络策略强制约束，这一点非常重要。网络策略仅在容器组（pod）的主接口（eth0）上强制执行。

### 使用案例
<a name="_use_cases_3"></a>

在需要执行以下操作时使用 `enableV4Egress`：
+  **使用 IPv6 集群**：默认情况下允许 IPv4 出口流量。
+  **使用网络策略**：目前 EKS 网络策略不支持双堆栈。禁用 `enableV4Egress` 可防止容器组（pod）流量意外通过 IPv4 流出。

### 示例配置
<a name="_example_configuration_3"></a>

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: advanced-networking
spec:
  role: MyNodeRole

  advancedNetworking:
    enableV4Egress: false
```

### 禁用 enableV4Egress 的注意事项
<a name="_considerations_for_disabling_enablev4egress"></a>
+  **IPv6 集群中的网络策略**：默认情况下，IPv6 集群允许 IPv4 流量。设置 `enableV4Egress: false` 可阻止 IPv4 出口流量，从而增强安全性，尤其是在与网络策略一起使用时。