

 **帮助改进此页面** 

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

# 使用应用程序负载均衡器路由应用程序和 HTTP 流量
<a name="alb-ingress"></a>

**注意**  
 **新增：**Amazon EKS 自动模式可自动执行负载均衡例行任务。有关更多信息，请参阅：  
 [将示例负载均衡器工作负载部署到 EKS 自动模式](auto-elb-example.md) 
 [创建 IngressClass 以配置应用程序负载均衡器](auto-configure-alb.md) 

当您创建 Kubernetes `ingress` 时，会预置一个 Amazon Application Load Balancer ALB)，以实现应用程序流量负载均衡。要了解详情，请参阅 *Application Load Balancer 用户指南*中的“[什么是 Application Load Balancer？](https://docs.amazonaws.cn/elasticloadbalancing/latest/application/introduction.html)”，以及 Kubernetes 文档中的[入口](https://kubernetes.io/docs/concepts/services-networking/ingress/)。ALB 可以与部署到节点或 Amazon Fargate 的 Pod 一起使用。您可以将 ALB 部署到公有子网或私有子网。

应用程序流量在 OSI 模型的 `L7` 上实现均衡。要在 `L4` 上对网络流量进行负载均衡，您可以部署 `LoadBalancer` 类型的 Kubernetes `service`。这种类型将预置 Amazon Network Load Balancer。有关更多信息，请参阅 [使用网络负载均衡器路由 TCP 和 UDP 流量](network-load-balancing.md)。要了解更多有关两种负载均衡类型之间差异的信息，请参阅 Amazon 网站上的 [Elastic Load Balancing 功能](https://www.amazonaws.cn/elasticloadbalancing/features/)。

## 先决条件
<a name="_prerequisites"></a>

在对应用程序的应用程序流量进行负载均衡之前，您必须符合以下要求。
+ 拥有现有集群。如果您没有现有集群，请参阅[开始使用 Amazon EKS](getting-started.md)。如果您需要更新现有集群的版本，请参阅 [将现有集群更新到新的 Kubernetes 版本](update-cluster.md)。
+ 在集群上部署 Amazon Load Balancer Controller。有关更多信息，请参阅 [使用 Amazon 负载均衡器控制器路由互联网流量](aws-load-balancer-controller.md)。建议升级到版本 `2.7.2` 或更高版本。
+ 至少两个子网位于不同的可用区。Amazon 负载均衡器控制器会从每个可用区中选择一个子网。如果在一个可用区中发现多个标记子网，则该控制器会按子网 ID 的字典顺序选择第子网。每个子网必须具有至少 8 个可用 IP 地址。

  如果您使用的是挂载到 Worker 节点的多个安全组，则必须按如下方式标记一个安全组。将 *my-cluster* 替换为您的集群名称。
  +  **密钥** – `kubernetes.io/cluster/<my-cluster>` 
  +  **值** – `shared` 或 `owned` 
+ 如果您使用的是 Amazon 负载均衡器控制器版本 `2.1.1` 或更早版本，则必须按如下格式标记子网。如果使用版本 `2.1.2` 或更高版本，则此标记是可选的。但是，如果出现以下任一情况，我们建议您标记子网。您有多个集群在同一 VPC 中运行，或者有多个 Amazon 服务在 VPC 中共享子网。或者，您希望更好地控制为每个集群配置的负载均衡器的位置。将 *my-cluster* 替换为您的集群名称。
  +  **密钥** – `kubernetes.io/cluster/<my-cluster>` 
  +  **值** – `shared` 或 `owned` 
+ 您的公有子网和私有子网必须满足以下要求。除非您明确指定子网 ID 作为服务或入口对象的注释。假设您通过明确指定子网 ID 作为服务或入口对象的注释来预置负载均衡器。在这种情况下，Kubernetes 和 Amazon 负载均衡器控制器会直接使用这些子网创建负载均衡器，并且不需要以下标签。
  +  **私有子网**：必须采用以下格式标记。这样 Kubernetes 和 Amazon 负载均衡器控制器就会知道子网可用于内部负载均衡器。如果您在 2020 年 3 月 26 日之后使用 `eksctl` 或 Amazon EKS Amazon CloudFormation 模板创建 VPC，则在创建子网时会对子网进行适当标记。有关 Amazon EKS Amazon CloudFormation VPC 模板的更多信息，请参阅[为您的 Amazon EKS 集群创建 Amazon VPC](creating-a-vpc.md)。
    +  **密钥** – `kubernetes.io/role/internal-elb` 
    +  **值** – `1` 
  +  **公有子网**：必须采用以下格式标记。如此一来，Kubernetes 将知道仅使用为外部负载均衡器指定的子网。这样，Kubernetes 就不会在每个可用区中选择一个公有子网（根据其子网 ID 按字典顺序排列）。如果您在 2020 年 3 月 26 日之后使用 `eksctl` 或 Amazon EKS Amazon CloudFormation 模板创建 VPC，则在创建子网时会对子网进行适当标记。有关 Amazon EKS Amazon CloudFormation VPC 模板的更多信息，请参阅[为您的 Amazon EKS 集群创建 Amazon VPC](creating-a-vpc.md)。
    +  **密钥** – `kubernetes.io/role/elb` 
    +  **值** – `1` 

  如果未显式添加子网角色标签，则 Kubernetes 服务控制器将检查集群 VPC 子网的路由表。这是为了确定子网是私有还是公有。我们建议您不要依赖此行为。相反，明确添加私有或公有角色标签。Amazon 负载均衡器控制器不会检查路由表。它还需要私有标签和公有标签才能成功实现自动发现。
+ 每当使用 `kubernetes.io/ingress.class: alb` 注释在集群上创建 Kubernetes 入口资源时，[Amazon 负载均衡器控制器](https://github.com/kubernetes-sigs/aws-load-balancer-controller)就会创建 ALB 和必要的支持 Amazon 资源。入口资源会配置 ALB 以便将 HTTP 或 HTTPS 流量路由到集群中的不同容器组（pod）。要确保您的入口对象使用 Amazon 负载均衡器控制器，请将以下注释添加到您的 Kubernetes 入口规范。有关更多信息，请参阅 GitHub 上的[入口规范](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/spec/)。

  ```
  annotations:
      kubernetes.io/ingress.class: alb
  ```
**注意**  
如果要对 `IPv6` 容器组（pod）进行负载均衡，请将以下注释添加到入口规范。您只能通过 `IPv6` 对 IP 目标进行负载均衡，无法对实例目标进行负载均衡。如果没有此注释，则通过 `IPv4` 进行负载均衡。

  ```
  alb.ingress.kubernetes.io/ip-address-type: dualstack
  ```
+ Amazon负载均衡器控制器支持以下流量模式：
  +  **实例** – 将您的集群中的节点注册为 ALB 的目标。传输到 ALB 的流量将路由到服务的 `NodePort`，然后转发到容器组（pod）。这是默认流量模式。您也可以使用 `alb.ingress.kubernetes.io/target-type: instance` 注释明确地指定该模式。
**注意**  
Kubernetes 服务必须指定 `NodePort` 或 `LoadBalancer` 类型，才能使用此流量模式。
  +  **IP**：将 Pod 注册为 ALB 的目标。传输到 ALB 的流量将直接路由到服务的容器组（pod）。您必须指定 `alb.ingress.kubernetes.io/target-type: ip` 注释，才能使用此流量模式。当目标容器组（pod）在 Fargate 或 Amazon EKS 混合节点功能上运行时，必须使用 IP 目标类型。
+ 要标记由控制器创建的 ALB，请向控制器添加以下注释：`alb.ingress.kubernetes.io/tags`。有关Amazon负载均衡器控制器支持的所有可用注释的列表，请参阅 GitHub 上的[入口注释](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/)。
+ 升级或降级 ALB 控制器版本可能会对依赖它的功能带来重大变化。有关在每个版本中引入的突发性更改的更多信息，请参阅 GitHub 上的 [ALB 控制器发布说明](https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases)。

## 在入口组中重复使用 ALB
<a name="_reuse_albs_with_ingress_groups"></a>

您可以使用 `IngressGroups` 跨多个服务资源共享应用程序负载均衡器

要将入口加入到组，请将以下注释添加到 Kubernetes 入口资源规范中。

```
alb.ingress.kubernetes.io/group.name: my-group
```

组名称必须为：
+ 长度不超过 63 个字符。
+ 它们包含小写字母、数字、`-` 和 `.`。
+ 以字母或数字开头和结尾。

控制器将自动合并同一入口组中所有入口的入口规则。它用单个 ALB 提供支持。在入口上定义的大多数注释仅适用于由该入口定义的路径。默认情况下，入口资源不属于任何入口组。

**警告**  
 **潜在的安全风险**   
仅当所有具有创建或修改入口资源的 RBAC 权限的 Kubernetes 用户均在同一信任边界内时，为入口指定一个入口组。如果添加具有组名称的注释，则其他 Kubernetes 用户可创建或修改其入口，以使其属于同一入口组。这样做可能会导致不良行为，例如使用优先级更高的规则覆盖现有规则。

您可以添加入口资源的编号。

```
alb.ingress.kubernetes.io/group.order: '10'
```

该号码可以为 1-1000。首先计算同一入口组中所有入口的最小数目。没有此注释的所有入口将使用零值进行评估。数字越大的重复规则可以覆盖具有较小数字的规则。默认情况下，同一入口组中不同入口之间的规则顺序由入口的命名空间和名称的字典顺序决定。

**重要**  
确保同一入口组中的每个入口都具有唯一的优先级编号。不同入口中不能有重复的编号。

## （可选）部署示例应用程序
<a name="application-load-balancer-sample-application"></a>
+ 集群 VPC 中至少有一个公有或私有子网。
+ 在集群上部署 Amazon Load Balancer Controller。有关更多信息，请参阅 [使用 Amazon 负载均衡器控制器路由互联网流量](aws-load-balancer-controller.md)。建议升级到版本 `2.7.2` 或更高版本。

您可以在具有 Amazon EC2 节点、Fargate Pod 或这两者的集群上运行示例应用程序。

1. 如果您不部署到 Fargate，请跳过此步骤。如果您要部署到 Fargate，请创建一个 Fargate 配置文件。您可以通过运行以下命令来创建配置文件，也可以在 [Amazon Web Services 管理控制台](fargate-profile.md#create-fargate-profile) 中，使用该命令中 `name` 和 `namespace` 的相同值创建配置文件。将 example values 替换为您自己的值。

   ```
   eksctl create fargateprofile \
       --cluster my-cluster \
       --region region-code \
       --name alb-sample-app \
       --namespace game-2048
   ```

1. 将游戏 [2048](https://play2048.co/) 部署为示例应用程序，以确认作为入口对象的结果，Amazon 负载均衡器控制器是否会创建 Amazon ALB。完成您要部署到的子网类型的步骤。

   1. 如果要部署到使用 `IPv6` 系列创建的集群中的容器组（pod），请跳至下一步。
      +  **公有**：

      ```
      kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/examples/2048/2048_full.yaml
      ```
      +  **私有**：

        1. 下载清单。

           ```
           curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/examples/2048/2048_full.yaml
           ```

        1. 编辑文件并找到显示 `alb.ingress.kubernetes.io/scheme: internet-facing` 的行。

        1. 将 *internet-facing* 更改为 `internal` 并保存该文件。

        1. 将清单应用于集群。

           ```
           kubectl apply -f 2048_full.yaml
           ```

   1. 如果要部署到使用 [IPv6 系列](cni-ipv6.md)创建的集群中的容器组（pod），请完成以下步骤。

      1. 下载清单。

         ```
         curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/examples/2048/2048_full.yaml
         ```

      1. 在编辑器中打开文件，并将以下行添加到入口规范的注释中。

         ```
         alb.ingress.kubernetes.io/ip-address-type: dualstack
         ```

      1. 如果要对内部容器组（pod）[而不是面向互联网的容器组（pod）] 进行负载均衡，请将显示 `alb.ingress.kubernetes.io/scheme: internet-facing ` 的行更改为 `alb.ingress.kubernetes.io/scheme: internal` 

      1. 保存该文件。

      1. 将清单应用于集群。

         ```
         kubectl apply -f 2048_full.yaml
         ```

1. 几分钟后，验证是否已使用以下命令创建入口资源。

   ```
   kubectl get ingress/ingress-2048 -n game-2048
   ```

   示例输出如下。

   ```
   NAME           CLASS    HOSTS   ADDRESS                                                                   PORTS   AGE
   ingress-2048   <none>   *       k8s-game2048-ingress2-xxxxxxxxxx-yyyyyyyyyy.region-code.elb.amazonaws.com   80      2m32s
   ```
**注意**  
如果您在私有子网中创建了负载均衡器，则之前输出中 `ADDRESS` 下的值前面加上 `internal-`。

如果几分钟后仍未成功创建入口，请运行以下命令以查看 Amazon 负载均衡器控制器日志。这些日志包含可让您诊断部署中问题的错误消息。

```
kubectl logs -f -n kube-system -l app.kubernetes.io/instance=aws-load-balancer-controller
```

1. 如果您部署到了公有子网，请打开浏览器并从上一命令输出导航到 `ADDRESS` URL 以查看示例应用程序。如果您没有看到任何内容，请刷新浏览器并重试。如果您已部署到私有子网，则需要从 VPC 中的设备（例如堡垒主机）查看页面。有关更多信息，请参阅 [Amazon 上的 Linux 堡垒主机](https://www.amazonaws.cn/quickstart/architecture/linux-bastion/)。  
![\[2048 示例应用程序\]](http://docs.amazonaws.cn/eks/latest/userguide/images/2048.png)

1. 在完成对示例应用程序的试验后，通过运行以下命令之一将其删除。
   + 如果您应用了清单，而不是应用下载的副本，请使用以下命令。

     ```
     kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.1/docs/examples/2048/2048_full.yaml
     ```
   + 如果您下载并编辑了清单，请使用以下命令。

     ```
     kubectl delete -f 2048_full.yaml
     ```