本教程是将2022 年 3 月微服务中的概念付诸实践的四个教程之一: Kubernetes 网络:
是否想要有关使用 NGINX 实现更多 Kubernetes 网络用例的详细指导? 下载我们的免费电子书《使用 NGINX 管理 Kubernetes 流量》: 实用指南。
您的组织在 Kubernetes 中构建了一个应用程序,现在它越来越流行! 您的访客数量从每天只有几个增加到每天数百个(有时甚至数千个)。 但有一个问题......增加的流量遇到了瓶颈,导致客户出现延迟和超时。 如果您不能改善体验,人们将停止使用该应用程序。
您——勇敢的 Kubernetes 工程师——有一个解决方案。 您部署一个 Ingress 控制器来路由流量并设置自动扩展策略,以便 Ingress 控制器 pod 的数量能够立即扩展和收缩以匹配流量波动。 现在,您的 Ingress 控制器 pod 可以无缝处理流量激增 - “再见,延迟!” - 并在流量减少时缩小规模以节省资源 - “你好,节省成本!” 你真棒。
本博客是2022 年 3 月微服务第 1 单元实验室的配套文章——为高流量网站构建 Kubernetes 集群,演示了如何使用 NGINX Ingress Controller 来公开应用程序,然后根据高流量自动扩展 Ingress 控制器 pod。
要运行本教程,您需要一台具有以下配置的机器:
为了充分利用实验室和教程,我们建议您在开始之前:
本教程使用了以下技术:
每个挑战的说明都包括用于配置应用程序的 YAML 文件的完整文本。 您也可以从我们的GitHub repo复制文本。 每个 YAML 文件的文本都附带有 GitHub 链接。
本教程包括四个挑战:
在本次挑战中,您将创建一个 minikube 集群并安装 Podinfo作为示例应用程序。
创建一个minikube集群。 几秒钟后,会出现一条消息确认部署成功。
$ minikube start 🏄 完成!kubectl 现在配置为默认使用“minikube”集群和“default”命名空间
Podinfo是一个“用 Go 制作的 Web应用,展示了在 Kubernetes 中运行微服务的最佳实践”。 由于其占用空间较小,我们将其用作示例应用程序。
使用您选择的文本编辑器,创建一个名为1-deployment.yaml的 YAML 文件,其中包含以下内容(或从 GitHub 复制)。 它定义了具有单个副本和服务的部署。
api版本:apps/v1 种类: 部署
元数据:
名称:podinfo
规格:
选择器:
匹配标签:
应用程序:podinfo
模板:
元数据:
标签:
应用程序:podinfo
规格:
容器:
-名称:podinfo
图像:stefanprodan / podinfo
端口:
-容器端口: 9898
---
api版本:v1
种类: 服务
元数据:
名称:podinfo
规格:
端口:
- 端口: 80
目标端口: 9898
节点端口: 30001
选择器:
应用程序:podinfo
类型: 负载均衡器
部署应用程序:
$ kubectl apply -f 1-deployment.yaml deploy.apps/podinfo 创建 service/podinfo
确认 Podinfo pod 已部署,如STATUS
列中的值Running
所示。
$ kubectl get pods名称就绪状态重新启动年龄 podinfo-5d76864686-rd2s5 1/1 运行 0 3m38s
在浏览器中打开 Podinfo。 podinfo 页面的问候语表明 Podinfo 正在运行。
$ minikube 服务 podinfo
在这个挑战中,您将部署 NGINX Ingress Controller并将其配置为将流量路由到 Podinfo 应用程序。
安装 NGINX Ingress Controller 最快的方法是使用Helm 。
将 NGINX 存储库添加到 Helm:
$ helm repo 添加 nginx-stable https://helm.nginx.com/stable
下载并安装基于 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 已安装。
确认 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秒
使用您选择的文本编辑器,创建一个名为2-ingress.yaml的 YAML 文件,其中包含以下内容(或从 GitHub 复制)。 它定义了将流量路由到 Podinfo 所需的 Ingress 清单。
api版本:networking.k8s.io/v1 种类: 入口
元数据:
名称:podinfo
规范:
入口类名称:nginx
规则:
-主机:“example.com”
http:
路径:
-后端:
服务:
名称:podinfo
端口:
编号: 80
路径: /
路径类型: 前缀
部署 Ingress 资源:
$ kubectl apply -f 2-ingress.yaml ingress.networking.k8s.io/podinfo 创建
在本次挑战中,您将观察 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 多个指标。
获取 NGINX Ingress Controller pod 的 IP 地址,以便查询其指标列表。 该地址出现在IP
字段中,如下所示172.17.0.4
。 (为了易读,省略了RESTARTS
和AGE
列,并将输出分布在两行。)
$ 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 <无> <无>
在 Kubernetes 集群内的主机上创建一个带有 shell 的临时BusyBox pod:
$ kubectl run -ti --rm=true busybox --image=busybox如果您没有看到命令提示符,请尝试按 Enter。/#
列出 NGINX Ingress Controller 生成的指标,并验证它是否包含nginx_connections_active
。 为了 <IP 地址>
替换步骤 1 中的值。
/# wget -qO- <IP 地址>:9113/指标
退出shell 返回 Kubernetes 服务器。
/#出口
现在您知道 NGINX Ingress Controller 跟踪nginx_connections_active
指标,您需要一个工具来收集(“抓取”)这些指标 – 本教程使用Prometheus 。
至于 NGINX Ingress Controller, Helm是安装 Prometheus 最快的方法。
将 Prometheus 存储库添加到 Helm:
$ helm repo 添加 prometheus-community https://prometheus-community.github.io/helm-charts
下载并安装 Prometheus:
$ helm install prometheus prometheus-community/prometheus \ --设置服务器.服务.类型=NodePort --设置服务器.服务.nodePort=30010
验证安装,通常需要 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 秒
打开 Prometheus。 在 minikube 环境中,运行以下命令,它将在您的默认浏览器中打开 Prometheus 仪表板。
$ minikube 服务 prometheus 服务器
如下页面确认服务器正在运行。
在搜索栏中输入nginx_ingress_nginx_connections_active
以查看活动连接指标的当前值。 您会看到一个活动连接,这是有道理的,因为您已经部署了一个 NGINX Ingress Controller pod。
在下一部分中,您将使用开源负载测试工具Locust来模拟流量激增,以便您可以在 Prometheus 中观察 NGINX Ingress Controller 的性能。 在这里部署 Locust。
使用您选择的文本编辑器,创建一个名为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
类型: 负载均衡器
部署 Locust:
$ kubectl apply -f 3-locust.yaml configmap/locust-script 创建deployment.apps/locust 创建service/locust
在浏览器中打开 Locust。
$ minikube 服务蝗虫
在字段中输入以下值:
单击“开始群集”按钮将流量发送到 Podinfo 应用程序。
返回 Prometheus 仪表板,查看 NGINX Ingress Controller 如何响应。 您可能必须对nginx_ingress_nginx_connections_active
执行新查询才能看到任何变化。
如下面的屏幕输出所示,由于建立了大量连接,单个 NGINX Ingress Controller pod 难以在无延迟的情况下处理增加的流量。 Prometheus 图表显示,每个 NGINX Ingress Controller pod 大约 100 个活跃连接是延迟峰值的临界点。 您可以使用此信息来确定何时需要扩大 NGINX Ingress Controller pod 的数量以避免增加延迟。
在最后的挑战中,您将构建一个随着流量增加而自动扩展资源的配置。 本教程使用 KEDA 进行自动缩放,因此首先安装它并创建一个定义何时以及如何进行缩放的策略。 与挑战 3 一样,然后使用 Locust模拟流量激增,并使用 Prometheus 观察启用自动缩放时的 NGINX Ingress Controller 性能。
KEDA是一个 Kubernetes 事件驱动的自动扩缩器,它集成了一个指标服务器(为 Kubernetes 存储和转换指标的组件),并且可以直接从 Prometheus(以及其他工具)使用指标。 它使用这些指标创建一个水平 Pod 自动扩缩器(HPA),桥接 Prometheus 收集的指标,并将它们提供给 Kubernetes。
与 NGINX Ingress Controller 和 Prometheus 一样,本教程使用 Helm 安装 KEDA。
将 KEDA 添加到 Helm 存储库:
$ helm repo add kedacore https://kedacore.github.io/charts “kedacore”已添加到您的存储库
安装 KEDA:
$ helm install keda kedacore/keda名称:keda 命名空间:默认 状态:已部署 修订: 1 测试套件: 没有任何
验证 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 如何扩展的参数。 以下配置:
nginx_connections_active
指标值触发自动扩缩执行以下步骤:
使用您选择的文本编辑器,创建一个名为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”
部署ScaledObject
:
$ kubectl apply -f 4-scaled-object.yaml scaledobject.keda.sh/nginx-scale 创建
为了真正测试自动扩缩的有效性,与挑战 3 相比,您将连接数量增加一倍。
在浏览器中返回 Locust 服务器。 在字段中输入以下值,然后单击“开始群集”按钮:
返回 Prometheus 和 Locust 仪表板。 Prometheus 图表下方的粉色框描述了 NGINX Ingress Controller pod 的扩大和缩小的数量。
切换回您的终端并手动检查 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 内容。”