news 2026/9/14 7:51:55

使用 AWS CDK 在 AWS Fargate 上部署 Apache APISIX 无服务器 API 网关

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 AWS CDK 在 AWS Fargate 上部署 Apache APISIX 无服务器 API 网关

使用 AWS CDK 在 AWS Fargate 上部署 Apache APISIX 无服务器 API 网关

【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix

导读

本文基于 APISIX 官方部署文档,完整演示如何借助 AWS CDK(Cloud Development Kit)将 Apache APISIX 以 Serverless Container 的方式部署到 AWS Fargate,并串联 etcd 作为配置存储、ALB/NLB 作为流量入口,最终通过 APISIX Dashboard 配置 Upstream 与 Route,将/index.php等后端请求代理到运行在 Fargate 上的 PHP 服务。读完本文,你将掌握从projen初始化 CDK 工程、编写基础设施即代码(IaC)、执行cdk deploy、用 nslookup 获取 NLB 静态 IP 并完成 APISIX 路由配置,以及如何在 AWS 中国区部署和清理资源的完整实战链路。

架构总览

APISIX 是一个云原生微服务 API 网关,为所有 API 与微服务提供高性能、安全、开源且可水平扩展的流量入口。本参考架构的目标是在 AWS Fargate 上把 APISIX 构建为无服务器容器形态的 API 网关,基础设施全部由 AWS CDK 声明式生成(图中底部标注 "Stack Created by AWS CDK")。

整体拓扑包含四类角色:

  • 客户端(Client):浏览器或任意 HTTP 客户端,流量先到达负载均衡器。
  • 应用负载均衡器(ALB):面向 APISIX 网关任务,承载 HTTP 流量的分发。
  • APISIX Gateway(Fargate Task):部署在 AWS Fargate 上的无服务器容器,可开启 Autoscaling 实现按需扩缩容;同任务内还以 Sidecar 方式运行 etcd 容器,作为 APISIX 的配置中心。
  • 后端服务(Fargate Task):以 NLB(Network Load Balancer,面向 TCP/UDP 优化)暴露多个静态 IP 地址,后端任务可动态扩缩容,负载均衡地址保持不变。
Client ──► ALB ──► APISIX Gateway (Fargate Task, Autoscaling) │ ├── etcd (同任务 Sidecar 容器, 端口 2379) │ └──► NLB ──► Backend PHP Tasks (Fargate, 多静态 IP)

在 APISIX 侧,网关默认监听9080端口接收代理流量(见 conf/config.yaml.example 中node_listen配置);控制面 Admin API 则监听9180端口(conf/config.yaml.example 中admin_listen配置),供 Dashboard 与 curl 调用。

用 projen 生成 AWS CDK 工程

先创建工程目录并用projen生成一个 TypeScript 版 AWS CDK 应用骨架:

$ mkdir apisix-aws $ cd $_ $ npx projen new awscdk-app-ts

接着把.projenrc.js更新为如下内容,声明依赖aws-ec2aws-ecsaws-ecs-patterns三个 CDK 模块:

const { AwsCdkTypeScriptApp } = require('projen'); const project = new AwsCdkTypeScriptApp({ cdkVersion: "1.70.0", name: "apisix-aws", cdkDependencies: [ '@aws-cdk/aws-ec2', '@aws-cdk/aws-ecs', '@aws-cdk/aws-ecs-patterns', ] }); project.synth();

然后运行npx projen让工程根据.projenrc.js重新生成package.jsontsconfig.jsonsrc/main.ts等脚手架文件:

$ npx projen

说明:cdkVersion锁定为1.70.0,对应 AWS CDK v1 语法(如@aws-cdk/core@aws-cdk/aws-ecs-patterns下的ApplicationLoadBalancedFargateService);若改用 CDK v2,需要将导入路径调整为aws-cdk-lib系列,本文示例保持与原文档一致的 v1 写法。

编写src/main.ts定义 APISIX + etcd + PHP 三套任务

将生成的src/main.ts替换为以下完整栈定义:

import * as cdk from '@aws-cdk/core'; import { Vpc, Port } from '@aws-cdk/aws-ec2'; import { Cluster, ContainerImage, TaskDefinition, Compatibility } from '@aws-cdk/aws-ecs'; import { ApplicationLoadBalancedFargateService, NetworkLoadBalancedFargateService } from '@aws-cdk/aws-ecs-patterns'; export class ApiSixStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const vpc = Vpc.fromLookup(this, 'VPC', { isDefault: true }) const cluster = new Cluster(this, 'Cluster', { vpc }) /** * ApiSix service */ const taskDefinition = new TaskDefinition(this, 'TaskApiSix', { compatibility: Compatibility.FARGATE, memoryMiB: '512', cpu: '256' }) taskDefinition .addContainer('apisix', { image: ContainerImage.fromRegistry('iresty/apisix'), }) .addPortMappings({ containerPort: 9080 }) taskDefinition .addContainer('etcd', { image: ContainerImage.fromRegistry('gcr.azk8s.cn/etcd-development/etcd:v3.3.12'), // image: ContainerImage.fromRegistry('gcr.io/etcd-development/etcd:v3.3.12'), }) .addPortMappings({ containerPort: 2379 }) const svc = new ApplicationLoadBalancedFargateService(this, 'ApiSixService', { cluster, taskDefinition, }) svc.targetGroup.setAttribute('deregistration_delay.timeout_seconds', '30') svc.targetGroup.configureHealthCheck({ interval: cdk.Duration.seconds(5), healthyHttpCodes: '404', healthyThresholdCount: 2, unhealthyThresholdCount: 3, timeout: cdk.Duration.seconds(4) }) /** * PHP service */ const taskDefinitionPHP = new TaskDefinition(this, 'TaskPHP', { compatibility: Compatibility.FARGATE, memoryMiB: '512', cpu: '256' }) taskDefinitionPHP .addContainer('php', { image: ContainerImage.fromRegistry('abiosoft/caddy:php'), }) .addPortMappings({ containerPort: 2015 }) const svcPHP = new NetworkLoadBalancedFargateService(this, 'PhpService', { cluster, taskDefinition: taskDefinitionPHP, assignPublicIp: true, }) // allow Fargate task behind NLB to accept all traffic svcPHP.service.connections.allowFromAnyIpv4(Port.tcp(2015)) svcPHP.targetGroup.setAttribute('deregistration_delay.timeout_seconds', '30') svcPHP.loadBalancer.setAttribute('load_balancing.cross_zone.enabled', 'true') new cdk.CfnOutput(this, 'ApiSixDashboardURL', { value: `http://${svc.loadBalancer.loadBalancerDnsName}/apisix/dashboard/` }) } } const devEnv = { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION, }; const app = new cdk.App(); new ApiSixStack(app, 'apisix-stack-dev', { env: devEnv }); app.synth();

代码要点解读

  • VPC 与 ECS ClusterVpc.fromLookup直接复用账号内的默认 VPC;Cluster将承载后面创建的 Fargate 服务。
  • APISIX 任务定义Compatibility.FARGATE声明 Serverless 运行模式,资源规格为 512 MiB 内存 + 256 vCPU;容器使用iresty/apisix镜像,并把9080端口映射出去(对应 APISIX 的node_listen默认端口)。
  • etcd Sidecar:同一 TaskDefinition 内再挂一个 etcd 容器(v3.3.12),端口2379与 APISIX 同 Task 共享网络命名空间,APISIX 可通过http://127.0.0.1:2379直连 etcd——这正是 conf/config.yaml.example 中etcd.host默认值的形态。
  • 健康检查技巧:目标组健康检查期望 HTTP 返回码为404,因为 APISIX 对未匹配任何 Route 的请求默认返回 404;利用这一默认行为探测网关存活状态,而无需额外配置健康检查 URI。
  • PHP 后端:使用abiosoft/caddy:php镜像(Caddy 内嵌 PHP),容器端口2015,通过 NLB 对外暴露并开启跨可用区负载均衡;由于 NLB 目标是 IP 类型,还需allowFromAnyIpv4放行 2015 端口流量。
  • 输出变量ApiSixDashboardURL将 ALB 的 DNS 拼接为 Dashboard 访问地址,cdk deploy结束后会打印出来。

用 AWS CDK 部署 APISIX Stack

先对比将要产生的变更,再执行部署:

$ cdk diff $ cdk deploy

部署完成后,控制台会返回如下 Outputs:

Outputs: apiSix.PhpServiceLoadBalancerDNS5E5BAB1B = apiSi-PhpSe-FOL2MM4TW7G8-09029e095ab36fcc.elb.us-west-2.amazonaws.com apiSix.ApiSixDashboardURL = http://apiSi-ApiSi-1TM103DN35GRY-1477666967.us-west-2.elb.amazonaws.com/apisix/dashboard/ apiSix.ApiSixServiceLoadBalancerDNSD4E5B8CB = apiSi-ApiSi-1TM103DN35GRY-1477666967.us-west-2.elb.amazonaws.com apiSix.ApiSixServiceServiceURLF6EC7872 = http://apiSi-ApiSi-1TM103DN35GRY-1477666967.us-west-2.elb.amazonaws.com

在浏览器打开apiSix.ApiSixDashboardURL,即可看到 APISIX Dashboard 的登录页面,登录后就可以开始配置网关资源。

配置 Upstream 节点

后端所有节点都以AWS Fargate Task运行,并注册到NLB(Network Load Balancer)下,对外暴露多个静态 IP 地址。用nslookup解析apiSix.PhpServiceLoadBalancerDNS5E5BAB1B即可拿到这些 IP:

$ nslookup apiSi-PhpSe-FOL2MM4TW7G8-09029e095ab36fcc.elb.us-west-2.amazonaws.com Server: 192.168.31.1 Address: 192.168.31.1#53 Non-authoritative answer: Name: apiSi-PhpSe-FOL2MM4TW7G8-09029e095ab36fcc.elb.us-west-2.amazonaws.com Address: 44.224.124.213 Name: apiSi-PhpSe-FOL2MM4TW7G8-09029e095ab36fcc.elb.us-west-2.amazonaws.com Address: 18.236.43.167 Name: apiSi-PhpSe-FOL2MM4TW7G8-09029e095ab36fcc.elb.us-west-2.amazonaws.com Address: 35.164.164.178 Name: apiSi-PhpSe-FOL2MM4TW7G8-09029e095ab36fcc.elb.us-west-2.amazonaws.com Address: 44.226.102.63

把这些 IP 地址作为 Upstream 节点填入 APISIX Dashboard,然后依次完成ServicesRoutes的配置。以/index.php作为第一条 Route 的 URI,绑定到第一个 Service,最终指向上述 Upstream IP 列表。

Dashboard 配置与 Admin API 的对应关系

Dashboard 上对 Upstream 的操作本质上是在调用 APISIX 的 Admin API。例如在 Dashboard 中创建 Upstream,等价于向/apisix/admin/upstreams/{id}发送请求;创建 Route 则对应/apisix/admin/routes/{id}。Admin API 的完整接口说明见 admin-api.md,核心请求方式如下(Admin API 默认监听9180,需携带X-API-KEY):

$ curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -H "X-API-KEY: $admin_key" -X PUT -d '{ "type": "roundrobin", "nodes": { "44.224.124.213:2015": 1, "18.236.43.167:2015": 1, "35.164.164.178:2015": 1, "44.226.102.63:2015": 1 } }' $ curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '{ "uri": "/index.php", "upstream_id": "1" }'

这里使用type: roundrobin(加权轮询,默认负载均衡算法)。Upstream 还支持chash(一致性哈希)、ewma(按最低延迟选择节点)、least_conn(按(active_conn + 1) / weight选择节点)等算法,并可通过checks字段开启健康检查、通过retries/retry_timeout控制重试、通过timeout设置连接/发送/读取超时(参数完整说明见 admin-api.md)。Route 侧则可用uri/urishost/hostsmethodsvars等匹配规则,并通过upstream_id引用已创建的 Upstream(Route 参数表见 admin-api.md)。

提醒:在 Fargate 这种按需扩缩容场景中,后端 Task 重建后 NLB 的 IP 可能变化,建议定期重新解析 NLB 域名并同步更新 Upstream 节点;如需完全自动化,可结合 DNS 服务发现(如 APISIX 的 discovery 机制)替代静态节点列表。

验证:请求被代理到 PHP 后端

在浏览器访问{apiSix.ApiSixServiceServiceURL}/index.php,即http://apiSi-ApiSi-1TM103DN35GRY-1477666967.us-west-2.elb.amazonaws.com/index.php

页面显示 Caddy Web Server 与 PHP 环境信息(PHP 版本、构建配置等),说明请求已经走通「ALB → APISIX → NLB → Fargate PHP Task」的完整链路——APISIX 已成功作为无服务器容器 API 网关在 AWS Fargate 上运行。

清理资源

验证完毕后,销毁整个 Stack 以释放资源、避免持续计费:

$ cdk destroy

cdk destroy会按依赖顺序删除 CloudFormation 管理的全部资源(ALB/NLB、ECS 服务与任务、安全组等)。

在 AWS 中国区运行 APISIX

由于 AWS 中国区(北京cn-north-1、宁夏cn-northwest-1)无法直接拉取gcr.io镜像,需要把 etcd 镜像源替换为国内可访问的镜像仓库。更新src/main.ts中 etcd 容器的镜像地址:

taskDefinition .addContainer('etcd', { image: ContainerImage.fromRegistry('gcr.azk8s.cn/etcd-development/etcd:v3.3.12'), // image: ContainerImage.fromRegistry('gcr.io/etcd-development/etcd:v3.3.12'), }) .addPortMappings({ containerPort: 2379 })

随后使用中国区的 AWS Profile 指定区域部署:

# let's say we have another AWS_PROFILE for China regions called 'cn' # make sure you have aws configure --profile=cn properly. # # deploy to NingXia region $ cdk deploy --profile cn -c region=cn-northwest-1 # deploy to Beijing region $ cdk deploy --profile cn -c region=cn-north-1

AWS 宁夏区域(cn-northwest-1)为例,部署完成后返回的 Outputs 形如:

Outputs: apiSix.PhpServiceLoadBalancerDNS5E5BAB1B = apiSi-PhpSe-1760FFS3K7TXH-562fa1f7f642ec24.elb.cn-northwest-1.amazonaws.com.cn apiSix.ApiSixDashboardURL = http://apiSi-ApiSi-123HOROQKWZKA-1268325233.cn-northwest-1.elb.amazonaws.com.cn/apisix/dashboard/ apiSix.ApiSixServiceLoadBalancerDNSD4E5B8CB = apiSi-ApiSi-123HOROQKWZKA-1268325233.cn-northwest-1.elb.amazonaws.com.cn apiSix.ApiSixServiceServiceURLF6EC7872 = http://apiSi-ApiSi-123HOROQKWZKA-1268325233.cn-northwest-1.elb.amazonaws.com.cn

打开apiSix.ApiSixDashboardURL并登录,即可在 AWS 中国区完成 APISIX 的后续配置(Dashboard 本身作为 Caddy/PHP 静态资源由同一集群提供,无需额外拉取镜像)。注意中国区 NLB 域名后缀为amazonaws.com.cn

进一步思考:在 AWS 上将 APISIX 与 etcd3 解耦

出于高可用与状态一致性考量,可将etcd3 独立成单独的集群,与 APISIX 解耦部署。这样带来的收益包括:APISIX 与 etcd 可以独立扩缩容、互不影响;etcd 集群自身可配置多副本实现故障容错;APISIX 重启或滚动更新时不依赖同 Task 内 etcd 的生命周期;同时 etcd 数据独立持久化,具备更可靠的状态一致性保障。

若采用解耦方案,需调整两处:一是在 CDK 中为 etcd 单独定义 ECS 服务(建议挂载 EBS/EFS 卷或使用 Amazon EKS 上的有状态工作负载),并开启 etcd 集群模式(--initial-cluster指定多个成员);二是将 conf/config.yaml.example 中etcd.host指向 etcd 服务的内网地址列表(可配置多个地址、设置prefix、连接超时timeout、启动重试startup_retry等),并在需要时启用 etcd TLS(etcd.tls.cert/key/verify/sni)。原文将这一部分标记为_TBD_,属于可继续深入的演进方向。

小结

本文完整走通了「projen 初始化 → CDK 定义 APISIX + etcd + PHP 任务 →cdk deploy→ nslookup 解析 NLB IP → Dashboard/Admin API 配置 Upstream 与 Route → 验证/index.phpcdk destroy清理」的端到端流程,并覆盖 AWS 中国区镜像源替换与 etcd 解耦的演进思路。该方案的核心价值在于:网关与后端都运行在按需计费、自动扩缩容的 Fargate 上,基础设施全部由 CDK 声明式管理,适合以低成本、可复现的方式在 AWS 上快速落地 APISIX 网关能力。

【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix

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

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

政府科技管理部门技术转移体系构建与实践

1. 政府科技管理部门推动技术转移的现状与挑战技术转移作为科技创新成果转化为现实生产力的关键环节,一直是政府科技管理部门工作的重点。但在实际操作中,我们常常面临以下典型问题:信息不对称:高校科研院所的研究成果与企业需求之…

作者头像 李华
网站建设 2026/9/14 7:48:36

Simulink中强化学习与VR可视化融合实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 7:48:31

国产大模型DeepSeek与Qwen的技术解析与应用实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 7:47:09

Java程序员职业发展路径与核心技术解析

1. Java程序员的职业发展路径解析作为一名从业十年的Java开发者,我见证了太多同行在职业发展中的迷茫与突破。Java程序员的职业发展绝非简单的技术堆砌,而是一个需要系统规划的成长体系。从初级工程师到架构师,每个阶段都有其独特的技术重点和…

作者头像 李华