在 AWS EKS 上运行基准
本指南将引导你在自己的 AWS 账户上重现 已发布的 AWS EKS 基准测试结果。该设置使用三个独立的 EKS 节点组,每个节点组用于 API7 网关、NGINX 上游和 wrk2 负载生成器,因此这三个组件都不会与其他组件争用 CPU 或网络资源。
一般基准测试方法和优化指导,请先参见性能基准测试。 在 Kubernetes 上部署 中介绍了 Kubernetes 上 API7 网关的标准生产安装过程;此页面仅记录特定于基准的偏差。
先决条件
- 有权创建 EKS 集群和 EC2 实例的 AWS 账户。
kubectl和helm本地安装,版本与目标 EKS 集群兼容。- EKS 集群服务角色和 EKS 节点 IAM 角色。请参阅Amazon EKS 集群 IAM 角色 和 Amazon EKS 节点 IAM 角色。
- 有效的 API7 企业版许可证。 请求试用(如果你还没有)。
步骤 1:创建 EKS 集群
在AWS 控制台中,创建一个新的EKS集群:
- 在EKS 控制台添加集群。
- 附加你在先决条件中创建的 EKS 集群服务角色。
- 配置 VPC 和子网,以便三个节点组能够在集群网络上相互访问。
- 根据你的喜好配置 可观测性(CloudWatch 日志记录)。
- 启用你通常运行的集群插件(例如,VPC、CNI 和 CoreDNS)。
- 创建集群并等待其达到
ACTIVE状态。
步骤 2:创建三个隔离节点组
该基准测试需要三个运行 c5.4xlarge 实例的独立 EC2 节点组,以便 API7 网关、上游和 wrk2 各有 16 个 vCPU 和 32 GB RAM 不会与其他组件争用资源。
对于每个节点组:
- 在EKS 控制台中打开计算 > 添加节点组。
- 为节点组命名(例如,
api7ee、upstream或wrk2)。 - 附加 EKS 节点 IAM 角色。
- 选择 Amazon Linux 2 (AL2_x86_64) 作为 AMI 类型。
- 选择 c5.4xlarge 作为实例类型。
- 将所需大小设置为至少 1 个节点。
- 如果要在节点上运行诊断命令,请启用 SSH 访问。
8.保存并等待节点组到达
ACTIVE。
重复此操作,直到获得三个节点组:api7ee、上游 和 wrk2。
请勿使用突发型实例系列(例如 t3 或 t4g)进行基准测试。他们基于信用的 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.crt、tls.key、ca.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 内安装 perf、strace 和 tcpdump 等诊断工具进行分析。 请勿在生产中使用这些设置。
步骤 6:在 upstream 节点上部署 NGINX 上游
上游是一个最小的 NGINX 服务器,它返回 200 字节的静态响应。禁用访问日志记录,以便上游磁盘 I/O 不会成为瓶颈。
创建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:
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-count | 2-one-route-with-limit-count.yaml |
1 个路由与 key-auth + limit-count | 3-one-route-with-key-auth-and-limit-count.yaml |
1 个路由+ 1 个消费者和 key-auth | 4-one-route-with-key-auth.yaml |
| 100 个路由无插件 | 5-100-route-without-plugin.yaml |
100 个路由与 limit-count | 6-100-route-with-limit-count.yaml |
100 个路由+ 100 个消费者与 key-auth + limit-count | 7-100-route-and-consumer-with-key-auth-limit-count.yaml |
100 个路由+ 100 个消费者与 key-auth | 8-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收费。
后续步骤
- 性能基准 — 方法、已发布的结果和优化指南。
- 扩展数据面 — 将你从基准测试中学到的知识应用到生产扩展计划中。
- 在 Kubernetes 上部署 — 标准生产安装过程。