Day 17 / 共 20 天 · 第 4 周 高级子系统与运维

Admin API 与 control API

前面都在讲"网关怎么用配置",今天讲"配置怎么进去"——Admin API 是配置管理入口(增删改路由/上游/插件),control API 是运维接口(看健康状态、触发操作)。这是运维 APISIX 的日常。

📍 你在整条链的位置(第 4 周 高级子系统与运维)
服务发现 D16 Admin/control API(配置怎么进去) stream L4 D18 SSL/secret/wasm D19
L01

两套管理接口

🤔 痛点:前 16 天都在"用配置",可配置到底怎么进 etcd 的? 路由、上游、插件都是从 etcd watch 来的(Day 07)。但谁往 etcd 写的?总不能让运维手动 etcdctl put 一串 JSON 吧——写错格式、漏了必填字段,坏配置直接污染全站。
💡 本质:物业的"办事窗口" vs "监控室" Admin API 是小区物业的办事窗口——你来办"新增一条路由/改个插件",窗口先审你的表格(schema 校验)合格才登记进档案(写 etcd)。control API 是物业的监控室——只能看屏幕(哪个上游不健康、当前 schema 是啥),不改档案。一个"改配置"、一个"看运行状态",端口和权限通常分开。
  • Admin APIapisix/admin/):管配置——PUT/GET/DELETE /apisix/admin/routes/{id} 等。写入 etcd(然后 watch 生效)。
  • control APIapisix/control/):管运行时——查健康检查状态、schema、触发 GC 等。只读/运维,不改配置。
配置管理 vs 运维观测 Admin API 是"改东西"(加路由、改插件)——写 etcd。control API 是"看/操作运行状态"(哪个上游不健康、当前 schema 是啥)——不碰 etcd。两者端口/权限通常分开(Admin 需要 key 鉴权,control 一般内网访问)。回想 Day 03 http_init_workeradmin.initcontrol_api_router.init_worker——两套接口各自初始化。
L02

Admin 目录

apisix/admin/
  init.lua         入口 + 鉴权 + 路由分发
  resource.lua     ★ 通用 CRUD 逻辑(各资源共用)
  routes.lua services.lua upstreams.lua consumers.lua
  plugin_configs.lua global_rules.lua ssl.lua ...  各资源
  schema.lua       暴露 schema 查询
  standalone.lua   standalone 模式的 admin
  v3_adapter.lua   API 版本适配
读法:每种资源(routes/services/upstreams…)一个文件,但它们大多复用 resource.lua 的通用 CRUD——只提供自己的 schema 和特殊逻辑。这和上一站 Higress Console 的 controller 一一对应(都是每种资源一个 CRUD 端点)。
L03

resource 通用 CRUD

admin/resource.lua 抽象了所有资源共同的 CRUD 流程:GET(查)、PUT(建/改)、DELETE(删)、PATCH(部分改)。各资源文件只传入自己的"名字 + schema + 校验钩子"。

"模板方法"减少重复 所有资源的 CRUD 骨架都一样:校验入参 → 校验 schema → 读/写 etcd → 返回结果。差异只在"用哪个 schema、有没有特殊校验"。所以抽出 resource.lua 通用骨架,routes.lua 只填"我是 routes、我的 schema 是 route、我有这些额外校验"。加一种资源类型 = 加个薄文件传参给 resource。又是"通用核心 + 具体参数"——和 balancer/discovery 的可插拔一个思路。
L04

写入即校验

Admin API 写 etcd 前用对应 schema 校验(Day 09)——回收 Day 09 的"校验在写入端"。不合法返回 400 + 具体错误,坏配置进不了 etcd。

# 示例:建一条路由
curl -X PUT http://127.0.0.1:9180/apisix/admin/routes/1 \
  -H "X-API-KEY: $admin_key" \
  -d '{"uri":"/hello","upstream":{"nodes":{"127.0.0.1:8080":1},"type":"roundrobin"}}'
# → 校验通过 → 写 /apisix/routes/1 到 etcd → watch 秒级生效(Day 07)
一条 PUT 请求的"全动态"闭环(全程零 reload) PUT /routes/1带 X-API-KEY schema 校验不合法→400 写 etcd 各节点 watch内存更新 radixtree 重建Day 06 新路由生效
Admin 校验 → 写 etcd → watch → 内存更新 → radixtree 重建 → 秒级生效,串起了 Day 06/07/09 的全部机制。

👶 小白:Admin API 这么强(能改全站配置),随便谁都能调岂不是很危险?

👨‍🏫 老师:所以它有两道锁:① X-API-KEY 鉴权(admin/init.lua 校验,key 不对直接拒);② 通常单独监听 9180 端口、只开放给内网/运维。control API 同理走另一个端口、只读为主。管理面和数据面(9080 处理业务)从端口就隔开——这是网关安全的基本功。

读法:这条 curl 就是"全动态"的完整闭环:Admin 校验 → 写 etcd → 所有节点 watch → 内存更新 → radixtree 重建 → 新路由立即可用,全程零 reloadX-API-KEY 是 Admin API 的鉴权(admin/init.lua 里校验)——管理接口必须保护好。
L05

standalone admin

admin/standalone.lua:standalone(config_yaml,Day 07)模式下的 Admin——配置不写 etcd 而是操作 apisix.yaml/内存。

两种模式的 Admin 都统一 etcd 模式 Admin 写 etcd,standalone 模式 Admin 操作内存/文件——但对外的 API 形状一样(PUT /routes/1)。这样用户/Dashboard 不用管底层是哪种模式,用同一套 API。又是"接口统一、实现可换"。
L06

control API

apisix/control/ + init.lua:1058http_control。提供运维接口,例如:

  • GET /v1/healthcheck:查各上游节点的健康检查状态。
  • GET /v1/schema:查所有资源/插件的 schema。
  • GET /v1/routes:查当前内存里的路由(调试)。
  • POST /v1/gc:触发 Lua GC 等。
读法:control API 是"运行时的观测窗口"——不改配置,只看/操作运行状态。比如排查"为什么请求打不到某个上游",查 /v1/healthcheck 看是不是被健康检查剔除了(Day 10)。它通常在单独端口、只允许内网访问。插件也能注册自己的 control 接口(如 prometheus 的 /apisix/prometheus/metrics)。
📝 举个例子(排障) 线上"某上游偶尔 502"。curl http://127.0.0.1:9090/v1/healthcheck → 返回 [{"name":"upstream#/routes/1","nodes":[{"ip":"10.0.0.7","status":"unhealthy",...}]}]
一眼看出 10.0.0.7 被健康检查(Day 10)判成不健康、已剔除——不是配置问题,是那台后端自己挂了。control API 就是这种"看运行时真相"的窗口。
L07

Dashboard 与生态

Admin API 之上有 APISIX Dashboard(独立项目,本机 apisix-dashboard/)——一个 Web 界面,调 Admin API 让你点点点管配置(类似上一站的 Higress Console)。

界面 vs API 的分层 Admin API 是"机器接口"(给程序/CI 调),Dashboard 是"人的界面"(给运维点)。Dashboard 本质就是个前端 + 后端,把界面操作翻译成 Admin API 调用。这和上一站 Higress Console 的定位完全一样——网关本体提供 API,单独的 Dashboard/Console 提供界面。你也能用 curl/Terraform/CRD(apisix-ingress-controller)等各种方式调 Admin API,不限于 Dashboard。
L08

今日小结 + 动手

🧠 今天你应该能回答

  • Admin API 和 control API 的分工?
  • resource.lua 怎么用"通用 CRUD"减少重复?
  • 一条 PUT /routes 请求怎么走完"全动态"闭环?
  • control API 能查什么?Dashboard 和 Admin API 的关系?

✋ 动手

cd /Users/bitmart/work/codes/github/apisix
ls apisix/admin/ apisix/control/
grep -n "function\|resource" apisix/admin/routes.lua | head
sed -n '1058,1066p' apisix/init.lua
明天预告 · Day 18stream 子系统——APISIX 不只代理 HTTP,还能代理 L4(TCP/UDP)。看 stream_preread_phase 怎么处理 L4 流量、和 HTTP 子系统的异同。
← Day 16 Day 18 · stream →