跳到主要内容
版本:3.10.x

在 AWS EKS 上运行基准

本指南将引导你在自己的 AWS 账户上重现 已发布的 AWS EKS 基准测试结果。该设置使用三个独立的 EKS 节点组,每个节点组用于 API7 网关、NGINX 上游和 wrk2 负载生成器,因此这三个组件都不会与其他组件争用 CPU 或网络资源。

一般基准测试方法和优化指导,请先参见性能基准测试在 Kubernetes 上部署 中介绍了 Kubernetes 上 API7 网关的标准生产安装过程;此页面仅记录特定于基准的偏差。

先决条件

步骤 1:创建 EKS 集群

在AWS 控制台中,创建一个新的EKS集群:

  1. 在EKS 控制台添加集群
  2. 附加你在先决条件中创建的 EKS 集群服务角色。
  3. 配置 VPC 和子网,以便三个节点组能够在集群网络上相互访问。
  4. 根据你的喜好配置 可观测性(CloudWatch 日志记录)。
  5. 启用你通常运行的集群插件(例如,VPC、CNI 和 CoreDNS)。
  6. 创建集群并等待其达到 ACTIVE 状态。

步骤 2:创建三个隔离节点组

该基准测试需要三个运行 c5.4xlarge 实例的独立 EC2 节点组,以便 API7 网关、上游和 wrk2 各有 16 个 vCPU 和 32 GB RAM 不会与其他组件争用资源。

对于每个节点组:

  1. 在EKS 控制台中打开计算 > 添加节点组
  2. 为节点组命名(例如,api7eeupstreamwrk2)。
  3. 附加 EKS 节点 IAM 角色。
  4. 选择 Amazon Linux 2 (AL2_x86_64) 作为 AMI 类型。
  5. 选择 c5.4xlarge 作为实例类型。
  6. 将所需大小设置为至少 1 个节点。
  7. 如果要在节点上运行诊断命令,请启用 SSH 访问。 8.保存并等待节点组到达ACTIVE

重复此操作,直到获得三个节点组:api7ee上游wrk2

警告

请勿使用突发型实例系列(例如 t3t4g)进行基准测试。他们基于信用的 CPU 模型产生不可重复的结果。请参阅避免突发云实例

步骤 3:连接 kubectl 并标记节点

配置 kubectl 与新集群通信:

aws eks update-kubeconfig --region <region-code> --name <your-cluster-name>

验证连接:

kubectl get svc

预期输出(自动创建 kubernetes 服务):

NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 39m

在每个节点组中标记一个节点,以便 Kubernetes 可以确定地将 pod 调度到它们上:

kubectl get nodes

kubectl label nodes <api7ee-node-name> nodeName=api7ee
kubectl label nodes <upstream-node-name> nodeName=upstream
kubectl label nodes <wrk2-node-name> nodeName=wrk2

步骤 4:在 api7ee 节点上安装 API7 企业版

创建命名空间并安装 API7 企业版控制面 Helm Chart,将每个 CP 组件(控制台、PostgreSQL、Prometheus)固定到 api7ee 节点。

kubectl create namespace api7

helm repo add api7 https://charts.api7.ai
helm repo update

helm install api7ee3 api7/api7ee3 \
--set nodeSelector."nodeName"=api7ee \
--set postgresql.primary.nodeSelector."nodeName"=api7ee \
--set prometheus.server.nodeSelector."nodeName"=api7ee \
-n api7
备注

捆绑的 PostgreSQL 和 Prometheus 默认启用持久存储。如果你的集群没有默认的 StorageClass 并且你希望保持基准环境无状态,请将 --set postgresql.primary.persistence.enabled=false--set prometheus.server.persistence.enabled=false 添加到上面的命令中。

等待控制面Pod 准备就绪:

kubectl -n api7 get pods -l app.kubernetes.io/name=api7ee3 -w

端口转发控制台并上传你的许可证:

kubectl -n api7 port-forward svc/api7ee3-dashboard 7443:7443

打开https://localhost:7443,使用默认的凭证(admin/admin)登录,从组织 > 设置 > 许可证上传许可证。

在控制台中,转到网关设置并将控制面地址设置为 https://api7ee3-dp-manager:7943,以便你接下来安装的数据面可以连接到它。

禁用全局 Prometheus插件

该基准测试测量原始请求处理性能,因此测试运行时应禁用全局 prometheus插件— 否则每个请求都会产生 Prometheus 指标记录成本。在启动基准测试之前,从控制台禁用全局 prometheus插件。

步骤 5:在 api7ee 节点上安装 API7 网关

在控制台中,单击 添加网关实例 并选择 Kubernetes 以生成安装脚本。控制台生成三个证书(tls.crttls.keyca.crt)以及你需要运行的 Helm 命令。

保存证书并创建 Kubernetes 密钥:

kubectl create secret generic -n api7 api7-ee-3-gateway-tls \
--from-file=tls.crt=/tmp/tls.crt \
--from-file=tls.key=/tmp/tls.key \
--from-file=ca.crt=/tmp/ca.crt

使用特定于基准的覆盖安装网关图表:

helm upgrade --install -n api7 --create-namespace api7-ee-3-gateway api7/gateway \
--set "etcd.auth.tls.enabled=true" \
--set "etcd.auth.tls.existingSecret=api7-ee-3-gateway-tls" \
--set "etcd.auth.tls.certFilename=tls.crt" \
--set "etcd.auth.tls.certKeyFilename=tls.key" \
--set "etcd.auth.tls.verify=true" \
--set "gateway.tls.existingCASecret=api7-ee-3-gateway-tls" \
--set "gateway.tls.certCAFilename=ca.crt" \
--set "apisix.extraEnvVars[0].name=API7_GATEWAY_GROUP_SHORT_ID" \
--set "apisix.extraEnvVars[0].value=default" \
--set "etcd.host[0]=https://api7ee3-dp-manager:7943" \
// Annotate 1
--set "apisix.replicaCount=1" \
--set "apisix.image.repository=api7/api7-ee-3-gateway" \
// Annotate 2
--set "apisix.image.tag=${GATEWAY_VERSION}" \
// Annotate 3
--set "nginx.workerProcesses=1" \
// Annotate 4
--set "apisix.nodeSelector.nodeName=api7ee" \
// Annotate 5
--set "apisix.securityContext.runAsNonRoot=false" \
--set "apisix.securityContext.runAsUser=0"

❶ 测量单实例吞吐量。仅在获得单实例数量后才可对其进行扩展。

❷ 将数据面映像固定到与你的控制面版本匹配的版本。在 Docker Hub或 支持的版本 页面中查找确切的标签。

❸ 从基线的单个工作进程开始。稍后提高它以测量多核扩展。

❹ 将网关 Pod 固定到隔离的基准节点。

❺ 以 root 身份运行,以便在 pod 内安装 perfstracetcpdump 等诊断工具进行分析。 请勿在生产中使用这些设置。

步骤 6:在 upstream 节点上部署 NGINX 上游

上游是一个最小的 NGINX 服务器,它返回 200 字节的静态响应。禁用访问日志记录,以便上游磁盘 I/O 不会成为瓶颈。

创建nginx-upstream.yaml

nginx-upstream.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: api7
name: nginx-config
data:
nginx.conf: |
master_process on;
worker_processes 1;
events {
worker_connections 4096;
}
http {
access_log off;
server_tokens off;
keepalive_requests 10000000;
server {
listen 1980;
server_name _;
location / {
return 200 "hello world\n";
}
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: api7
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
nodeName: upstream
containers:
- name: nginx
image: nginx:1.25.4
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: nginx-config
configMap:
name: nginx-config
---
apiVersion: v1
kind: Service
metadata:
namespace: api7
name: nginx-upstream
spec:
selector:
app: nginx
ports:
- port: 1980
targetPort: 1980

应用它:

kubectl apply -f nginx-upstream.yaml

步骤 7:在 wrk2 节点上部署 wrk2

wrk2 是负载生成器。将其固定到 wrk2 节点,以便它不会与网关或上游共享 CPU。

创建wrk2.yaml

wrk2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: api7
name: wrk2-deployment
spec:
replicas: 1
selector:
matchLabels:
app: wrk2
template:
metadata:
labels:
app: wrk2
spec:
nodeSelector:
nodeName: wrk2
containers:
- name: wrk2
image: bootjp/wrk2
command: ["sleep", "infinity"]

应用它:

kubectl apply -f wrk2.yaml

当你准备好运行负载生成器时,将 exec 添加到 Pod 中:

kubectl -n api7 exec -it deploy/wrk2-deployment -- sh

步骤 8:应用测试场景配置

公共 api7-gateway-performance-benchmark 存储库包含基准表中每个场景的即用型 ADC 配置。克隆存储库并使用 ADC CLI 按顺序应用每个场景:

场景ADC 配置
1 个路由不带插件1-one-route-without-plugin.yaml
1 个路由与 limit-count2-one-route-with-limit-count.yaml
1 个路由与 key-auth + limit-count3-one-route-with-key-auth-and-limit-count.yaml
1 个路由+ 1 个消费者和 key-auth4-one-route-with-key-auth.yaml
100 个路由无插件5-100-route-without-plugin.yaml
100 个路由与 limit-count6-100-route-with-limit-count.yaml
100 个路由+ 100 个消费者与 key-auth + limit-count7-100-route-and-consumer-with-key-auth-limit-count.yaml
100 个路由+ 100 个消费者与 key-auth8-100-route-and-consumer-with-key-auth.yaml

应用 adc sync 的场景:

adc sync \
--server https://<dashboard-host>:7443 \
--token <your-api7-api-key> \
--gateway-group default \
-f 1-one-route-without-plugin.yaml

步骤 9:运行负载测试

wrk2 Pod 内部,针对 API7 网关服务运行负载生成器。以内部服务 DNS 名称为目标,以便流量保留在集群网络上:

// Annotate 1
wrk -t4 -c100 -d120s -R300000 \
// Annotate 2
--latency \
http://api7-ee-3-gateway.api7.svc.cluster.local:9080/get

❶ 使用 4 个线程、100 个并发连接、2 分钟运行以及 300,000 个请求/秒的目标速率来匹配已发布的方法。

❷ 在输出中发出延迟百分位数。

每个测试用例运行 5 次并取结果的平均值。记录每个场景的 QPS、P95 和 P99,然后与 性能基准 中发布的数字进行比较。

如果你的结果与已发布的数字存在显著偏差(超过约 10%),请查看优化建议 并验证:

  • API7 网关和 NGINX 上游上的访问日志均被禁用。
  • ulimit -n 在所有三个节点上至少为 1024000
  • 全局 prometheus插件已禁用。
  • 三个基准节点上没有调度其他 Pod。
  • API7 网关的错误日志是干净的(没有上游DNS 错误,没有连接失败)。

清理

完成后删除测试命名空间:

kubectl delete namespace api7

然后从 AWS 控制台删除这三个节点组和EKS集群,以停止EC2收费。

后续步骤