博客 | NGINX

NGINX 教程: 通过自动扩展减少 Kubernetes 延迟

NGINX-F5-horiz-black-type-RGB 的一部分
Daniele Polencic 缩略图
丹尼尔·波伦契奇
2022 年 3 月 15 日发布

本教程是将2022 年 3 月微服务中的概念付诸实践的四个教程之一: Kubernetes 网络

是否想要有关使用 NGINX 实现更多 Kubernetes 网络用例的详细指导? 下载我们的免费电子书《使用 NGINX 管理 Kubernetes 流量》: 实用指南

您的组织在 Kubernetes 中构建了一个应用程序,现在它越来越流行! 您的访客数量从每天只有几个增加到每天数百个(有时甚至数千个)。 但有一个问题......增加的流量遇到了瓶颈,导致客户出现延迟和超时。 如果您不能改善体验,人们将停止使用该应用程序。

您——勇敢的 Kubernetes 工程师——有一个解决方案。 您部署一个 Ingress 控制器来路由流量并设置自动扩展策略,以便 Ingress 控制器 pod 的数量能够立即扩展和收缩以匹配流量波动。 现在,您的 Ingress 控制器 pod 可以无缝处理流量激增 - “再见,延迟!” - 并在流量减少时缩小规模以节省资源 - “你好,节省成本!” 你真棒。

实验室和教程概述

本博客是2022 年 3 月微服务第 1 单元实验室的配套文章——为高流量网站构建 Kubernetes 集群,演示了如何使用 NGINX Ingress Controller 来公开应用程序,然后根据高流量自动扩展 Ingress 控制器 pod。

要运行本教程,您需要一台具有以下配置的机器:

  • 2 个或更多 CPU
  • 2 GB 可用内存
  • 20 GB 可用磁盘空间
  • 互联网连接
  • 容器或虚拟机管理器,例如 Docker、Hyperkit、Hyper‑V、KVM、Parallels、Podman、VirtualBox 或 VMware Fusion/Workstation
  • minikube安装
  • 安装Helm
  • 允许您启动浏览器窗口的配置。 如果不可能的话,您需要弄清楚如何通过浏览器获取相关服务。

为了充分利用实验室和教程,我们建议您在开始之前:

本教程使用了以下技术:

每个挑战的说明都包括用于配置应用程序的 YAML 文件的完整文本。 您也可以从我们的GitHub repo复制文本。 每个 YAML 文件的文本都附带有 GitHub 链接。

本教程包括四个挑战:

  1. 在 Kubernetes 集群上配置一个简单的应用程序
  2. 使用 NGINX Ingress Controller 将流量路由到应用程序
  3. 生成和监控流量
  4. 自动缩放 NGINX 入口控制器

挑战1: 在 Kubernetes 集群上配置一个简单的应用程序

在本次挑战中,您将创建一个 minikube 集群安装 Podinfo作为示例应用程序。

创建 Minikube 集群

创建一个minikube集群。 几秒钟后,会出现一条消息确认部署成功。

$ minikube start 🏄 完成!kubectl 现在配置为默认使用“minikube”集群和“default”命名空间 

安装 Podinfo 应用程序

Podinfo是一个“用 Go 制作的 Web应用,展示了在 Kubernetes 中运行微服务的最佳实践”。 由于其占用空间较小,我们将其用作示例应用程序。

  1. 使用您选择的文本编辑器,创建一个名为1-deployment.yaml的 YAML 文件,其中包含以下内容(或从 GitHub 复制)。 它定义了具有单个副本和服务的部署。

    api版本:apps/v1 种类: 部署 
    元数据: 
    名称:podinfo 
    规格: 
    选择器: 
    匹配标签: 
    应用程序:podinfo 
    模板: 
    元数据: 
    标签: 
    应用程序:podinfo 
    规格: 
    容器: 
    -名称:podinfo 
    图像:stefanprodan / podinfo 
    端口: 
    -容器端口: 9898 
    --- 
    api版本:v1 
    种类: 服务 
    元数据: 
    名称:podinfo 
    规格: 
    端口: 
    - 端口: 80 
    目标端口: 9898 
    节点端口: 30001 
    选择器:
    应用程序:podinfo 
    类型: 负载均衡器 
    
  2. 部署应用程序:

    $ kubectl apply -f 1-deployment.yaml deploy.apps/podinfo 创建 service/podinfo
    
  3. 确认 Podinfo pod 已部署,如STATUS列中的值Running所示。

    $ kubectl get pods名称就绪状态重新启动年龄 podinfo-5d76864686-rd2s5 1/1 运行 0 3m38s
    
  4. 在浏览器中打开 Podinfo。 podinfo 页面的问候语表明 Podinfo 正在运行。

    $ minikube 服务 podinfo
    

挑战2: 使用 NGINX Ingress Controller 将流量路由到应用程序

在这个挑战中,您将部署 NGINX Ingress Controller并将其配置为将流量路由到 Podinfo 应用程序

部署 NGINX Ingress 控制器

安装 NGINX Ingress Controller 最快的方法是使用Helm

  1. 将 NGINX 存储库添加到 Helm:

    $ helm repo 添加 nginx-stable https://helm.nginx.com/stable 
    
  2. 下载并安装基于 NGINX 开源的NGINX Ingress Controller ,由 F5 NGINX 维护。输出的最后一行确认安装成功。

    $ helm install main nginx-stable/nginx-ingress \ --set controller.watchIngressWithoutClass=true \ --set controller.service.type=NodePort \ --set controller.service.httpPort.nodePort=30005名称:main 最后部署: 2022 年 3 月 15 日星期二 09:49:17 命名空间:默认状态:已部署修订: 1 测试套件: 无 注意: NGINX Ingress Controller 已安装。
    
  3. 确认 NGINX Ingress Controller pod 已部署,如STATUS列中的Running值所示(为了便于阅读,输出分布在两行)。

    $ kubectl get pods名称 就绪状态... main-nginx-ingress-779b74bb8b-mtdkr 1/1 正在运行... podinfo-5d76864686-fjncl 1/1 正在运行... ... 重新开始年龄... 0 18 秒... 0 2分36秒
    

将流量路由到您的应用

  1. 使用您选择的文本编辑器,创建一个名为2-ingress.yaml的 YAML 文件,其中包含以下内容(或从 GitHub 复制)。 它定义了将流量路由到 Podinfo 所需的 Ingress 清单。

    api版本:networking.k8s.io/v1 种类: 入口 
    元数据: 
    名称:podinfo 
    规范: 
    入口类名称:nginx 
    规则: 
    -主机:“example.com” 
    http: 
    路径: 
    -后端: 
    服务: 
    名称:podinfo 
    端口: 
    编号: 80 
    路径: / 
    路径类型: 前缀 
    
  2. 部署 Ingress 资源:

    $ kubectl apply -f 2-ingress.yaml ingress.networking.k8s.io/podinfo 创建 
    

挑战3: 生成和监控流量

在本次挑战中,您将观察 NGINX Ingress Controller 在不同流量负载下的性能。 作为准备步骤,列出 NGINX Ingress Controller 提供的指标部署 Prometheus安装 Locust 。 然后,您可以使用 Locust模拟流量激增并跟踪对 Prometheus 中性能的影响

正如您已经发现的,Ingress 控制器是一个常规的 Kubernetes pod,它将反向代理(在我们的例子中是 NGINX)与一些代码捆绑在一起以便与 Kubernetes 集成。 如果您的应用程序接收大量流量,您可能需要增加 NGINX Ingress Controller pod 副本的数量,以避免 NGINX Ingress Controller 不堪重负时造成的延迟。

列出可用指标

要知道何时以及扩展多少,您需要有关 NGINX Ingress Controller 性能的准确信息。 在本教程中,用于确定何时扩展的 NGINX 指标是活动连接数 ( nginx_connections_active )。 在这里,您可以验证您的 NGINX Ingress Controller 是否跟踪该指标。

NGINX Ingress Controller公开多个指标: 我们在本教程中使用基于 NGINX 开源模型的 8 个指标和基于 NGINX Plus模型的 80 多个指标。

  1. 获取 NGINX Ingress Controller pod 的 IP 地址,以便查询其指标列表。 该地址出现在IP字段中,如下所示172.17.0.4。 (为了易读,省略了RESTARTSAGE列,并将输出分布在两行。)

    $ kubectl get pods -o wide NAME READY STATUS...main-nginx-ingress-779b74bb8b-6hdwx 1/1 正在运行...podinfo-5d76864686-nl8ws 1/1 正在运行...... IP 节点指定节点就绪门...172.17.0.4 minikube <无> <无> ... 172.17.0.3 minikube <无> <无>
    
  2. 在 Kubernetes 集群内的主机上创建一个带有 shell 的临时BusyBox pod:

    $ kubectl run -ti --rm=true busybox --image=busybox如果您没有看到命令提示符,请尝试按 Enter。/# 
    
  3. 列出 NGINX Ingress Controller 生成的指标,并验证它是否包含nginx_connections_active 。 为了 <IP 地址> 替换步骤 1 中的值。

    /# wget -qO- <IP 地址>:9113/指标
    
  4. 退出shell 返回 Kubernetes 服务器。

    /#出口 
    

部署 Prometheus

现在您知道 NGINX Ingress Controller 跟踪nginx_connections_active指标,您需要一个工具来收集(“抓取”)这些指标 – 本教程使用Prometheus

至于 NGINX Ingress Controller, Helm是安装 Prometheus 最快的方法。

  1. 将 Prometheus 存储库添加到 Helm:

    $ helm repo 添加 prometheus-community https://prometheus-community.github.io/helm-charts
    
  2. 下载并安装 Prometheus:

    $ helm install prometheus prometheus-community/prometheus \ --设置服务器.服务.类型=NodePort --设置服务器.服务.nodePort=30010
    
  3. 验证安装,通常需要 60 秒才能完成。 在下面的示例输出中,验证命令在helm install命令之后仅运行了几秒钟,因此我们看到安装正在进行中,并且某些 Prometheus pod 的STATUS字段报告了ContainerCreating 。 当所有 Pod 的状态均为Running 时,安装完成。 (为了易读,输出分为两行。)

    $ kubectl 获取 Pod名称已就绪...main-nginx-ingress-779b74bb8b-mtdkr 1/1...podinfo-5d76864686-fjncl 1/1...prometheus-alertmanager-d6d94cf4b-85ww5 0/2...prometheus-kube-state-metrics-7cd8f95cb-86hhs 0/1...prometheus-node-exporter-gqxfz 1/1...prometheus-pushgateway-56745d8d8b-qnwcb 0/1...prometheus-server-b78c9449f-kwhzp 0/2... 状态重新开始年龄... 正在运行 0 3分23秒 ... 正在运行 0 5分41秒 ... 容器创建 0 7 秒 ... 正在运行 0 7 秒... 正在运行 0 7 秒... 容器创建 0 7 秒 ... 容器创建 0 7 秒
    
  4. 打开 Prometheus。 在 minikube 环境中,运行以下命令,它将在您的默认浏览器中打开 Prometheus 仪表板。

    $ minikube 服务 prometheus 服务器
    

    如下页面确认服务器正在运行。

  5. 在搜索栏中输入nginx_ingress_nginx_connections_active以查看活动连接指标的当前值。 您会看到一个活动连接,这是有道理的,因为您已经部署了一个 NGINX Ingress Controller pod。

安装 Locust

在下一部分中,您将使用开源负载测试工具Locust来模拟流量激增,以便您可以在 Prometheus 中观察 NGINX Ingress Controller 的性能。 在这里部署 Locust。

  1. 使用您选择的文本编辑器,创建一个名为3-locust.yaml的 YAML 文件,其中包含以下内容(或从 GitHub 复制)。 Deployment 和 Service 对象定义了 Locust pod。 ConfigMap 对象定义了一个名为locustfile.py的脚本,该脚本生成要发送到 pod 的请求,并带有正确的标头。

    api版本:v1 
    种类: ConfigMap 
    元数据: 
    名称:locust-script 
    数据: 
    locustfile.py:|- 
    来自 locust 导入 HttpUser、task、between 
    
    类 QuickstartUser(HttpUser): 
    wait_time = between(0.7, 1.3) 
    
    @task 
    def hello_world(self): 
    self.client.get(“/”,headers={“Host”:“example.com”}) 
    --- 
    apiVersion:apps/v1 
    种类: 部署 
    元数据: 
    名称:locust 
    规格: 
    选择器: 
    匹配标签: 
    应用程序:locust 
    模板: 
    元数据: 
    标签: 
    应用程序:locust 
    规格: 
    容器: 
    -名称:locust 
    图像:locustio/locust 
    端口: 
    -容器端口: 8089 
    volumeMounts: 
    -mountPath:/home/locust 
    名称:locust-script 
    volumes: 
    -名称:locust-script 
    configMap: 
    名称:locust-script 
    --- 
    apiVersion:v1 
    种类: 服务 
    元数据: 
    名称: locust 
    规格: 
    端口: 
    - 端口: 8089 
    目标端口: 8089 
    节点端口: 30015 
    选择器:
    应用程序: locust 
    类型: 负载均衡器 
    
  2. 部署 Locust:

    $ kubectl apply -f 3-locust.yaml configmap/locust-script 创建deployment.apps/locust 创建service/locust 
    

模拟流量激增并观察对性能的影响

  1. 在浏览器中打开 Locust。

    $ minikube 服务蝗虫
    

  2. 在字段中输入以下值:

    • 用户数量– 1000
    • 生成率— 10
    • 主机– http://main-nginx-ingress
  3. 单击“开始群集”按钮将流量发送到 Podinfo 应用程序。

  4. 返回 Prometheus 仪表板,查看 NGINX Ingress Controller 如何响应。 您可能必须对nginx_ingress_nginx_connections_active执行新查询才能看到任何变化。

    如下面的屏幕输出所示,由于建立了大量连接,单个 NGINX Ingress Controller pod 难以在无延迟的情况下处理增加的流量。 Prometheus 图表显示,每个 NGINX Ingress Controller pod 大约 100 个活跃连接是延迟峰值的临界点。 您可以使用此信息来确定何时需要扩大 NGINX Ingress Controller pod 的数量以避免增加延迟。

挑战4: 自动缩放 NGINX 入口控制器

在最后的挑战中,您将构建一个随着流量增加而自动扩展资源的配置。 本教程使用 KEDA 进行自动缩放,因此首先安装它创建一个定义何时以及如何进行缩放的策略。 与挑战 3 一样,然后使用 Locust模拟流量激增,并使用 Prometheus 观察启用自动缩放时的 NGINX Ingress Controller 性能。

安装 KEDA

KEDA是一个 Kubernetes 事件驱动的自动扩缩器,它集成了一个指标服务器(为 Kubernetes 存储和转换指标的组件),并且可以直接从 Prometheus(以及其他工具)使用指标。 它使用这些指标创建一个水平 Pod 自动扩缩器(HPA),桥接 Prometheus 收集的指标,并将它们提供给 Kubernetes。

与 NGINX Ingress Controller 和 Prometheus 一样,本教程使用 Helm 安装 KEDA。

  1. 将 KEDA 添加到 Helm 存储库:

    $ helm repo add kedacore https://kedacore.github.io/charts “kedacore”已添加到您的存储库 
    
  2. 安装 KEDA:

    $ helm install keda kedacore/keda名称:keda 命名空间:默认 状态:已部署 修订: 1 测试套件: 没有任何
    
  3. 验证 KEDA 是否作为两个 pod 运行。 (为了易读, NAME列中的某些值被缩短了。 此外,省略了RESTARTS列;该值为0适用于所有 Pod。)

    $ kubectl get pods NAME READY STATUS AGE keda-operator-8644dcdb79-492x5 1/1 运行 59 秒 keda-operator-metrics-apiserver-66d...  1/1 运行 59 秒locust-77c699c94d-dvb5n 1/1 运行 8m59 秒 main-nginx-ingress-779b74bb8b-v7ggw 1/1 运行 48 分钟 podinfo-5d76864686-c98rb 1/1 运行 50 分钟 prometheus-alertmanager-d6d94cf4b-8...  2/2 运行 37 分钟 prometheus-kube-state-metrics-7cd8f…  1/1 运行 37 分钟 prometheus-node-exporter-j4qf4 1/1 运行 37 分钟 prometheus-pushgateway-56745d8d8b-9n4nl 1/1 运行 37 分钟 prometheus-server-b78c9449f-6ktn9 2/2 运行 37 分钟
    

创建自动扩展策略

现在使用 KEDA ScaledObject自定义资源定义 (CRD) 来定义决定 NGINX Ingress Controller 如何扩展的参数。 以下配置:

  • 根据 Prometheus 收集的nginx_connections_active指标值触发自动扩缩
  • 当现有 Pod 达到 100 个活跃连接时,部署一个新 Pod
  • 自动将 NGINX Ingress Controller Pod 从单个 Pod 扩缩至最多 20 个 Pod

执行以下步骤:

  1. 使用您选择的文本编辑器,创建一个名为4-scaled-object.yaml的 YAML 文件,其中包含以下内容(或从 GitHub 复制)。 它定义了一个 KEDA ScaledObject

    api版本:keda.sh/v1alpha1 种类: ScaledObject 
    元数据: 
    名称:nginx-scale 
    规格: 
    scaleTargetRef: 
    种类: 部署 
    名称:main-nginx-ingress 
    minReplicaCount: 1 
    最大副本数: 20 
    冷却时间: 30 
    轮询间隔: 1 
    触发器: 
    - 类型:prometheus 
    元数据: 
    服务器地址:http://prometheus-server 
    指标名称:nginx_connections_active_keda 
    查询:| 
    总和(avg_over_time(nginx_ingress_nginx_connections_active{app="main-nginx-ingress"}[1m])) 
    阈值: “100” 
    
  2. 部署ScaledObject

    $ kubectl apply -f 4-scaled-object.yaml scaledobject.keda.sh/nginx-scale 创建 
    

模拟流量激增并观察自动扩展对性能的影响

为了真正测试自动扩缩的有效性,与挑战 3 相比,您将连接数量增加一倍。

  1. 在浏览器中返回 Locust 服务器。 在字段中输入以下值,然后单击“开始群集”按钮:

    • 用户数量– 2000
    • 生成率— 10
    • 主机– http://main-nginx-ingress
  2. 返回 Prometheus 和 Locust 仪表板。 Prometheus 图表下方的粉色框描述了 NGINX Ingress Controller pod 的扩大和缩小的数量。

  3. 切换回您的终端并手动检查 KEDA HPA。 输出中的REPLICAS字段显示当前部署的 pod 副本数。 (为了易读,输出分为两行。)

    $ kubectl 获取 hpa名称引用... keda-hpa-nginx-scale 部署/main-nginx-ingress... ... 目标 MINPODS MAXPODS 复制品年龄... 101500米/100(平均)1 20 10 2分45秒
    

下一步

当您仅根据活动连接数进行自动扩展时,可能会存在潜在的限制。 如果(即使经过扩展)NGINX Ingress Controller 过于繁忙而不得不断开连接,则自动扩展器会看到较少的活动连接,将其解释为请求已减少,并减少副本数量。 这可能会使性能变差,但利用多种指标可以确保这种情况不会发生。 例如, nginxplus_connections_dropped (可由基于 NGINX Plus 的 NGINX Ingress Controller 提供)会跟踪那些丢失的客户端连接。

要尝试使用 NGINX Ingress Controller 与 NGINX Plus 和 NGINX App Protect,请立即开始30 天免费试用联系我们讨论您的用例

要使用 NGINX 开源尝试 NGINX Ingress Controller,您可以获取发布源代码,或从DockerHub下载预构建的容器。


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”