news 2026/10/10 1:42:30

Kong 性能测试 Terraform 驱动契约解析:Equinix Metal 基础设施自动化指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kong 性能测试 Terraform 驱动契约解析:Equinix Metal 基础设施自动化指南
  • API网关
  • 后端
  • LLM 网关
  • 微服务
  • 人工智能

【免费下载链接】kong

🦍 The API and AI Gateway

项目地址:https://gitcode.com/GitHub_Trending/ko/kong
点击查看免费下载

导读:本文围绕 Kong 开源仓库中性能测试(perf test)基础设施的 Equinix Metal 驱动契约展开,逐条解读spec/fixtures/perf/terraform/equinix-metal/README.md定义的三大前置条件(id_rsa私钥、四个 IP 输出项、internal-ip 回退规则),并结合该目录下完整的 Terraform 配置与spec/helpers/perf/drivers/terraform.lua驱动源码,说明这套基础设施如何被 Kong 性能测试框架自动拉起、读取和销毁。读完本文,你将掌握 Equinix Metal 上部署 Kong 压测环境的完整机制,并能理解如何将该契约推广到其他云厂商(AWS、DigitalOcean、BYO)。

一、契约文档:Kong perf 测试对 Terraform 驱动的最低要求

Kong 仓库中,性能测试的 Terraform 驱动被组织在 spec/fixtures/perf/terraform 目录下,每个云厂商一个子目录。其中 equinix-metal/README.md 是唯一一份以 README 形式固化契约的驱动,全文内容如下:

Perf test terraform driver expects:

  • id_rsaas the private key present
  • kong-ip,kong-internal-ip,worker-ipandworker-internal-ipto present in terraform output. If instance has no private IP, use<type>-ipas<type>-internal-ipis also accepted.

这份文档虽然短,却是整个 perf 测试驱动体系与云资源之间唯一正式的"接口协议",包含三个核心约定:

  1. 私钥契约:工作目录下必须存在名为id_rsa的 SSH 私钥文件,驱动通过它免密登录所有被创建的实例;
  2. 输出契约:terraform output必须提供kong-ip、kong-internal-ip、worker-ip、worker-internal-ip四个 IP 值,驱动据此定位 Kong 节点与压测 worker 节点;
  3. 回退契约:若实例没有私有 IP(如某些精简网络配置),允许将<type>-ip直接当作<type>-internal-ip使用。

下文将逐一验证这三个约定在仓库源码中的实际落地方式。

二、私钥契约:id_rsa从生成、落盘到使用的完整链路

2.1 密钥生成与落盘

在 tls.tf 中,驱动使用 Terraform 的tlsprovider 动态生成一对 RSA 密钥:

resource "tls_private_key" "key" { algorithm = "RSA" }

密钥生成后,ssh.tf 负责将其私钥以id_rsa文件名写入驱动工作目录,并强制权限为0600:

resource "local_sensitive_file" "key_priv" { content = tls_private_key.key.private_key_pem filename = "./id_rsa" file_permission = "0600" }

这里filename = "./id_rsa"正是 README 中"id_rsaas the private key present"的出处:Terraform apply 完成时,驱动所在目录必然出现该私钥文件。

2.2 驱动如何消费私钥

spec/helpers/perf/drivers/terraform.lua中的ssh_execute_wrap方法拼装了全部 SSH 参数,其中明确引用id_rsa:

return "ssh " .. "-o IdentityFile=" .. self.work_dir .. "/id_rsa " .. -- TODO: no hardcode "-o TCPKeepAlive=yes -o ServerAliveInterval=10 " .. "-o ControlPath=" .. self.work_dir .. "/cm-%r@%h:%p " .. "-o ControlMaster=auto -o ControlPersist=5m " .. "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no " .. "-o LogLevel=ERROR " .. self.ssh_user .. "@" .. ip .. " '" .. cmd .. "'"

从源码可以看出,id_rsa契约背后还有一层隐性约束:SSH 连接必须依赖连接复用(ControlMaster=auto、ControlPersist=5m)与跳过主机指纹校验(StrictHostKeyChecking=no),否则批量执行命令时会反复建立连接或被指纹提示阻塞。工作目录work_dir由驱动new()方法解析:"./spec/fixtures/perf/terraform/" .. provider,所以对于 Equinix Metal 即 spec/fixtures/perf/terraform/equinix-metal。

三、输出契约:四个 IP 输出项与terraform output -json的读取

3.1 output.tf 中的四个核心输出

output.tf 完整实现了 README 要求的输出契约:

output "kong-ip" { value = equinix_metal_device.kong.access_public_ipv4 } output "kong-internal-ip" { value = equinix_metal_device.kong.access_private_ipv4 } output "db-ip" { value = var.seperate_db_node ? equinix_metal_device.db.0.access_public_ipv4: "" } output "db-internal-ip" { value = var.seperate_db_node ? equinix_metal_device.db.0.access_private_ipv4: "" } output "worker-ip" { value = equinix_metal_device.worker.access_public_ipv4 } output "worker-internal-ip" { value = equinix_metal_device.worker.access_private_ipv4 }

可见除契约要求的四个输出外,还额外提供db-ip与db-internal-ip用于独立数据库节点(受seperate_db_node开关控制)。值得注意的是kong-ip取access_public_ipv4、kong-internal-ip取access_private_ipv4,这正是 README 所述"公有 IP + 私有 IP"两种地址的映射来源。

3.2 驱动侧如何读取输出

terraform.lua的setup()方法在terraform apply成功后,通过terraform output -json一次性拉取全部输出并解析:

res, err = perf.execute("cd " .. self.work_dir .. " && terraform output -json") res = cjson.decode(res) self.kong_ip = res["kong-ip"].value self.kong_internal_ip = res["kong-internal-ip"].value if self.opts.seperate_db_node then self.db_ip = res["db-ip"].value self.db_internal_ip = res["db-internal-ip"].value else self.db_ip = self.kong_ip self.db_internal_ip = self.kong_internal_ip end self.worker_ip = res["worker-ip"].value self.worker_internal_ip = res["worker-internal-ip"].value

这段代码同时体现了输出契约的两个细节:

  • 驱动使用cjson解析terraform output -json的标准 JSON 结构(res["kong-ip"].value);
  • 当seperate_db_node为 false 时,数据库直接复用 Kong 节点 IP,不额外拉起独立数据库实例。

3.3 各 provider 输出契约的一致性

输出契约并不局限于 Equinix Metal,其余 provider 也遵循完全相同的输出命名。例如 aws-ec2/output.tf 输出kong-ip、kong-internal-ip、worker-ip、worker-internal-ip、db-ip、db-internal-ip;bring-your-own/output.tf 则将用户传入的变量原样输出为同名输出。这种"输出名统一"的设计让 terraform.lua 驱动可以用同一套解析逻辑兼容所有云厂商。

四、回退契约:无私有 IP 场景的<type>-ip降级

README 的第三句话规定:若实例没有私有 IP,允许将<type>-ip直接当作<type>-internal-ip。仓库中该规则有两处落地:

1. 驱动层自动降级(Equinix Metal 场景)

terraform.lua的start_worker()中,压测请求默认发送到worker_internal_ip:

if not uri then uri = string.format("http://%s:8000", self.kong_internal_ip) end

而setup_kong()中 Kong 的pg_host默认使用db_internal_ip。一旦terraform output -json返回空字符串,驱动随后通过 SSH 命令执行会失败——因此回退必须发生在更上游。

2. 变量层显式回退(bring-your-own 场景)

bring-your-own/variables.tf 给出了最清晰的降级实现:

locals { kong_internal_ip_fallback = var.kong_internal_ip != "" ? var.kong_internal_ip : var.kong_ip worker_internal_ip_fallback = var.worker_internal_ip != "" ? var.worker_internal_ip : var.worker_ip }

kong_internal_ip、worker_internal_ip变量默认值为空字符串,当用户未提供时自动回退到公网 IP。注释# db IP fallback is done in the lua part则指明数据库节点的回退由 Lua 驱动完成——即上文setup()中self.db_ip = self.kong_ip的逻辑。

此外,在 spec/helpers/perf.lua 的use_defaults()中,用户可通过环境变量PERF_TEST_BYO_KONG_INTERNAL_IP等显式指定内部 IP,其默认值即对应公网 IP 变量:

kong_internal_ip = os.getenv("PERF_TEST_BYO_KONG_INTERNAL_IP"), -- fallback to kong_ip

五、实例资源定义:metal.tf 与 variables.tf 的可调参数

5.1 三节点资源模型

metal.tf 定义了 perf 测试的标准拓扑:kong 节点(被压测对象)+ worker 节点(压测发起方)+ 可选 db 节点(独立数据库)。

resource "equinix_metal_device" "kong" { hostname = "kong-${random_string.ident.result}" plan = var.metal_plan facilities = var.metal_region operating_system = var.metal_os billing_cycle = "hourly" project_id = var.metal_project_id tags = [] depends_on = [ equinix_metal_ssh_key.key ] } resource "equinix_metal_device" "db" { count = var.seperate_db_node ? 1: 0 ... } resource "equinix_metal_device" "worker" { hostname = "worker-${random_string.ident.result}" ... }

关键设计点:

  • billing_cycle = "hourly"按小时计费,与压测"用完即毁"的节奏匹配;
  • depends_on = [equinix_metal_ssh_key.key]保证 SSH 公钥先于设备创建上传(metal.tf 顶部定义了equinix_metal_ssh_key资源,其public_key来自tls_private_key.key.public_key_openssh);
  • random_string.ident(4 位随机串)用于生成唯一 hostname,避免多轮压测命名冲突;
  • db资源使用count = var.seperate_db_node ? 1 : 0实现条件创建。

5.2 可调变量清单

variables.tf 暴露了完整的参数面:

变量类型默认值说明
metal_auth_tokenstring无必须提供,Equinix Metal API token
metal_project_idstring无必须提供,设备创建所属项目 ID
metal_planstringc3.small.x86Kong 节点机型
metal_worker_planstringc3.small.x86worker 节点机型
metal_db_planstringc3.small.x86数据库节点机型
metal_regionlist(string)11 个 AMER 机房(dc13/da11/sv15/sv16/sp4/ch3/ny5/ny7/la4/tr2/se4)可用区候选列表,Metal 会从中分配
metal_osstringubuntu_20_04设备操作系统
seperate_db_nodeboolfalse是否创建独立数据库实例

main.tf中声明了版本约束:Terraform~> 1.2、equinix provider~> 1.6,以及 local/null/tls/random 四个辅助 provider。provider "equinix"仅配置auth_token = var.metal_auth_token。

5.3 参数如何从环境变量注入

用户无需手写.tfvars文件——perf.lua 的use_defaults()会把环境变量转换成terraform apply的-var参数(驱动new()中实现为-var 'k=v'拼接):

tfvars = { metal_project_id = os.getenv("PERF_TEST_METAL_PROJECT_ID"), metal_auth_token = os.getenv("PERF_TEST_METAL_AUTH_TOKEN"), metal_plan = os.getenv("PERF_TEST_METAL_PLAN"), -- "c3.small.x86" metal_os = os.getenv("PERF_TEST_METAL_OS"), -- "ubuntu_20_04", } tfvars.seperate_db_node = seperate_db_node

对应关系为:PERF_TEST_METAL_PROJECT_ID→metal_project_id、PERF_TEST_METAL_AUTH_TOKEN→metal_auth_token、PERF_TEST_METAL_PLAN→metal_plan、PERF_TEST_METAL_OS→metal_os,以及PERF_TEST_SEPERATE_DB_NODE→seperate_db_node(注意源码中的拼写为SEPERATE)。驱动选择则通过PERF_TEST_DRIVER=terraform与PERF_TEST_TERRAFORM_PROVIDER=equinix-metal完成。

六、契约之上的完整压测生命周期

README 描述的契约只是起点,terraform.lua 在拿到 IP 后继续完成如下完整流程:

6.1 数据库准备(db 节点)

setup()在 db 节点上依次执行:卸载 unattended-upgrades、安装 Docker、清理历史容器,然后启动 PostgreSQL 13 容器:

"sudo docker run -d -p5432:5432 ".. "-e POSTGRES_PASSWORD=" .. PG_PASSWORD .. " " .. "-e POSTGRES_DB=kong_tests " .. "-e POSTGRES_USER=kong --name=kong-database postgres:13 postgres -N 2333"

并通过docker logs -f kong-database轮询"is ready to accept connections"确认数据库就绪。PG_PASSWORD是每次驱动实例化时生成的随机密码,postgres -N 2333提高了最大连接数以支撑高并发压测。

6.2 Kong 安装(kong 节点)

setup_kong(version)支持两种版本来源:

  • 发布包:从download.konghq.com下载kong-<version>_amd64.deb并dpkg -i安装;
  • git 源码 + daily 镜像:以git:<分支>形式传入版本时,驱动会 checkout 对应分支,并把kong/kong:master-ubuntu每日镜像内的 Lua 源码与 OpenResty 组件提取到节点上(docker cp方式)。

安装前后还会做系统调优:将 CPU 调速器设为performance、扩大本地端口范围net.ipv4.ip_local_port_range='10240 65535',这些细节保证了压测结果不被系统默认配置干扰。

6.3 worker 节点环境与压测工具

start_worker(conf, port_count)在 worker 节点安装 nginx 与wrk/wrk2,并写入一段预生成的 nginx 配置:默认监听8088起始的端口,location /返回固定大体积字符串(模拟真实上游响应体)。压测脚本目录 scripts/wrk.lua 提供动态 URL 生成逻辑,可通过KONG_DEMO_CONSUMER_COUNT、KONG_DEMO_SERVICE_COUNT、KONG_DEMO_WORKSPACE_COUNT、KONG_DEMO_ROUTE_PER_SERVICE环境变量调节服务/消费者/路由规模:

local consumer_count = os.getenv("KONG_DEMO_CONSUMER_COUNT") or 5 local service_count = os.getenv("KONG_DEMO_SERVICE_COUNT") or 5 local workspace_count = os.getenv("KONG_DEMO_WORKSPACE_COUNT") or 1 local route_per_service = os.getenv("KONG_DEMO_ROUTE_PER_SERVICE") or 5 function request() local random_consumer = rand(consumer_count) local random_service = rand(service_count) local random_route = rand(route_per_service) if workspace_count == 1 then url_path = string.format("/s%s-r%s?apikey=consumer-%s", random_service, random_route, random_consumer) else random_workspace = rand(workspace_count) url_path = string.format("/w%s-s%s-r%s?apikey=consumer-%s", random_workspace, random_service, random_route, random_consumer) end return wrk.format(nil, url_path, headers) end

6.4 压测启动与负载均衡等待

get_start_load_cmd()有一个容易被忽略的重要机制:发起压测前会持续检查 Kong 节点的 1 分钟 loadavg,直到loadavg / 物理核数 < 0.2才允许开压(源码常量LOAD_NORMALIZED_THRESHOLD = 0.2),从而保证每轮压测都从"空闲基线"开始,结果可横向比较。

6.5 销毁与回收

teardown(full)分两级清理:默认仅卸载 Kong 相关文件与进程(dpkg -r kong、pkill nginx),保留实例以加速下一轮测试;传入 full 参数时才执行terraform destroy -auto-approve彻底销毁所有设备,与billing_cycle = "hourly"的计费模型闭环。

七、验证与配套:从契约到可运行的 perf 测试

7.1 最小接入条件

要在一台机器上跑通 Equinix Metal 压测,需要满足:

  1. 本机安装 Terraform~> 1.2(驱动setup()会先执行which terraform做存在性检查);
  2. 具备 Equinix Metal 账号的 auth token 与 project ID;
  3. 以PERF_TEST_DRIVER=terraform、PERF_TEST_TERRAFORM_PROVIDER=equinix-metal等环境变量启动任一 perf spec,例如 spec/04-perf/01-rps/01-simple_spec.lua。

7.2 与 perf spec 的对接方式

性能测试用例通过require("spec.helpers.perf")使用驱动,核心 API 包括use_defaults()、setup_kong(version)、start_kong()、start_worker()、start_load()、wait_result()、teardown(),压测版本可通过PERF_TEST_VERSIONS环境变量以逗号分隔传入多个版本做对比测试。驱动操作默认带 3 次重试(RETRY_COUNT = 3),任意一次失败都会抛错终止用例。

7.3 可替换性:一份契约,四套实现

Equinix Metal 只是 Terraform 驱动的默认 provider。仓库中 aws-ec2、digitalocean、bring-your-own 均实现了同一套输出契约,切换 provider 只需修改PERF_TEST_TERRAFORM_PROVIDER及对应的PERF_TEST_*环境变量。因此,本文解析的三条契约(id_rsa、四个 IP 输出、internal-ip 回退)实际上构成了 Kong perf 测试框架与任意云基础设施之间的通用接入标准。

八、总结

equinix-metal/README.md用三句话定义了一套严谨的驱动-基础设施契约:私钥id_rsa保障免密运维通道,四个 IP 输出项统一了节点寻址方式,internal-ip 回退规则兼容无私有网络的环境。从 tls.tf、ssh.tf、output.tf 到 terraform.lua 驱动的逐行落地,再到 perf.lua 的环境变量注入与 scripts/wrk.lua 的负载生成,这套最小契约支撑起了 Kong 在真实云主机上的可重复、可对比的吞吐与延迟基准测试能力。无论是为 Kong 贡献新的云厂商 provider,还是理解现有压测流程的每一环,这份契约都是最值得先读的入口。

  • API网关
  • 后端
  • LLM 网关
  • 微服务
  • 人工智能

【免费下载链接】kong

🦍 The API and AI Gateway

项目地址:https://gitcode.com/GitHub_Trending/ko/kong
点击查看免费下载

相关推荐

上一篇:如何用Refs.cn元件库在3分钟内构建专业原型:免费开源的多平台设计解决方案
下一篇:广东工业大学计算机学院课程攻略:一站式获取大学四年学习资源的终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 1:39:03

JavaWeb开发环境配置全攻略:JDK、Tomcat、MySQL与IDEA避坑指南

最近隔三差五就有人来问我 JAVAWeb 的配置和安装问题&#xff0c;尤其是刚接触 JavaWeb 的同学&#xff0c;项目代码还没写几行&#xff0c;先被环境折腾得怀疑人生。环境变量、JDK、Tomcat、MySQL、IDEA&#xff0c;这几样东西单独拿出来都不难&#xff0c;但凑到一起就会冒出…

作者头像 李华
网站建设 2026/10/10 1:38:47

ruoyi-vue-pro SQL脚本导入避坑指南:从建表到Flyway迁移

简介&#xff1a;这份资源是芋道 ruoyi-vue-pro 企业级快速开发平台的配套数据库脚本合集&#xff0c;面向使用 Spring Boot Vue 前后端分离架构进行中大型系统开发的 Java 工程师、数据库管理员及二次开发人员&#xff0c;帮助其快速搭建项目数据库结构、理解业务数据模型。压…

作者头像 李华
网站建设 2026/10/10 1:37:59

tiny-dnn 导入 Caffe 训练模型:caffe_converter 示例完整解析

人工智能深度学习嵌入式 【免费下载链接】tiny-dnn header only, dependency-free deep learning framework in C14 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ti/tiny-dnn 点击查看 免费下载 导读 tiny-dnn 是一个 header-only、无第三方依赖的 C14 深度学习框架…

作者头像 李华