云原生 API 网关:apisix使用详解

文章目录

一、简介

官方文档:https://apisix.apache.org/zh/docs/apisix/getting-started/README/

Apache APISIX 是 Apache 软件基金会下的顶级项目。它是一个具有动态、实时、高性能等特点的云原生 API 网关。

可以使用 APISIX 网关作为所有业务的流量入口,它提供了动态路由、动态上游、动态证书、A/B 测试、灰度发布(金丝雀发布)、蓝绿部署、限速、防攻击、收集指标、监控报警、可观测、服务治理等功能。

二、安装

1、docker一键安装

bash 复制代码
# APISIX 可以借助 quickstart 脚本快速安装并启动:
# 该命令启动 apisix-quickstart 和 etcd 两个容器,APISIX 使用 etcd 保存和同步配置。APISIX 和 etcd 容器使用 Docker 的 host 网络模式,因此可以从本地直接访问。
curl -sL https://run.api7.ai/apisix/quickstart | sh

# 验证
curl "http://127.0.0.1:9080" --head | grep Server

2、安装Dashboard

APISIX 内置了 Dashboard UI,默认启用,让用户可以通过图形界面轻松配置路由、插件、上游服务等。

访问:http://192.168.56.10:9180/ui 即可打开管理控制台

(1)可选的配置

conf/config.yaml 文件中可以编辑配置,编辑完成后需要重启apisix

yml 复制代码
deployment:
  admin:
    # 启用内嵌 APISIX Dashboard: 默认true
    enable_admin_ui: true
    # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow
    # 设置 Admin API 的 IP 访问白名单,防止 Apache APISIX 被非法访问和攻击:默认0.0.0.0/0
    allow_admin:
        - 127.0.0.0/24

(2)Admin API Key

conf/config.yaml中配置 Admin API Key:

yml 复制代码
deployment:
  admin:
    admin_key:
      -
        name: admin
        role: admin
        # 使用简单的 Admin API Key 存在安全风险,部署到生产环境时请及时更新
        key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # 也支持通过环境变量配置:
        # 从环境变量读取 使用前需设置环境变量:export ADMIN_KEY=your-secure-api-key
        #key: ${{ADMIN_KEY}}

在右上角的设置按钮,可以填入apikey

三、Dashboard使用

1、配置一个简单的路由转发功能

(1)创建Upstream

Upstream(也称之为上游)是对虚拟主机抽象,即应用层服务或节点的抽象。你可以通过 Upstream 对象对多个服务节点按照配置规则进行负载均衡。

上游的地址信息可以直接配置到路由(或服务)中。(可以参考nginx的upstream)

(2)配置路由Route

Route(也称为路由)是 APISIX 中最基础和最核心的资源对象,APISIX 可以通过路由定义规则来匹配客户端请求,根据匹配结果加载并执行相应的插件,最后将请求转发给到指定的上游服务。

(3)测试

启动我们后台的测试服务:

2、配置服务Service

Service(也称之为服务)是某类 API 的抽象(也可以理解为一组 Route 的抽象)。它通常与上游服务抽象是一一对应的,但与路由之间,通常是 1:N 即一对多的关系。

不同路由规则同时绑定到一个服务上,这些路由将具有相同的上游和插件配置,减少冗余配置。当路由和服务都开启同一个插件时,路由中的插件优先级高于服务中的插件。

3、实战:基于路由优先级实现灰度发布

基于 APISIX 网关实现灰度环境(灰度发布),核心是把指定比例 / 特征的流量路由到灰度版本服务,其余流量走生产版本,以此验证新版本的稳定性和兼容性。

核心思路:

1、设置路由优先级(优先级数字越大,优先级越高)

2、可以根据ip、请求头等参数,来指定灰度用户路由的upstream

四、强大的插件

1、插件简介

Apache APISIX 作为云原生 API 网关,内置70 + 插件,覆盖认证授权、流量控制、安全防护、可观测性、请求转换、缓存、流量管理等核心场景。插件支持热加载,可灵活绑定到 Route、Service、Consumer 或全局,满足复杂 API 治理需求。

1、一般情况下,可以在管理控制台进行插件的设置,设置路由的时候,选择插件,填入插件的json配置即可:

2、也可以使用api的方式修改插件:

json 复制代码
curl -i "http://127.0.0.1:9180/apisix/admin/routes/getting-started-ip" -X PATCH -d '
{
  "plugins": {
    "limit-count": {
        "count": 2,
        "time_window": 10,
        "rejected_code": 503
     }
  }
}'

2、授权类插件

(1)key-auth(密钥认证)

功能:基于 API 密钥的轻量级认证,客户端通过请求头或查询参数传递密钥,APISIX 验证后允许访问

(1)创建一个消费者,插件选择key-auth并输入内容:

lua 复制代码
{
  "key": "secret-key-123"
}

(2)创建路由,插件也选择key-auth,内容为以上。

(3)客户端请求时添加 apikey: secret-key-123 头?apikey=secret-key-123 参数即可访问,否则会提示:{"message":"Missing API key in request"}

3、流量控制类插件

(1)limit-req(请求速率限流)

功能:基于漏桶算法限制请求速率,防止突发流量击垮后端服务

4、安全防护类

(1)ip-restriction(IP 黑白名单)

黑名单、白名单只能选择一种

json 复制代码
{
  "blacklist": [
    "192.168.56.0/16"
  ]
}
json 复制代码
{
    "whitelist": ["192.168.1.0/24", "10.0.0.1"]
}

五、serverless插件

1、serverless-pre-function插件(灵活度高)

serverless-pre-function:请求经过 APISIX 路由匹配、认证鉴权等前置插件后,转发到上游服务之前执行,核心能力可概括为:

修改请求头、请求参数(GET/POST)、请求路径;

校验请求合法性,拦截非法请求(直接返回响应,不转发到上游);

动态调整上游服务地址(如灰度发布、流量路由);

补充请求上下文(如添加全链路追踪 ID、用户身份标识);

自定义日志采集(如记录请求关键参数)。

(1)动态添加全链路 Trace-ID 请求头

为所有请求添加唯一的X-Trace-ID请求头,方便全链路问题排查。

json 复制代码
// 调用APISIX Admin API创建全局规则
curl http://{APISIX_ADMIN_ADDRESS}:9180/apisix/admin/global_rules/1 \
-H "X-API-KEY: {APISIX_ADMIN_KEY}" \
-X PUT \
-d '{
  "plugins": {
    "serverless-pre-function": {
      "phase": "rewrite",
      "functions": [
        "return function(conf, ctx)
          -- 纯Lua原生生成UUID v4(不依赖任何外部模块)
          local function generate_uuid()
            local random = math.random
            local template = \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\"
            return string.gsub(template, \"[xy]\", function(c)
              local v = (c == \"x\") and random(0, 0xf) or random(8, 0xb)
              return string.format(\"%x\", v)
            end)
          end
          -- 先读取客户端传入的Trace-ID,无则生成
          local trace_id = ngx.req.get_headers()[\"X-Trace-ID\"] or generate_uuid()
          ngx.req.set_header(\"X-Trace-ID\", trace_id)
        end"
      ]
    }
  }
}'

(2)动态upstream:从redis获取ip(未验证)

lua 复制代码
curl http://127.0.0.1:9180/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
  "uri": "/redis-dynamic/*",
  "plugins": {
    "serverless-pre-function": {
      "phase": "pre-access",
      "functions": [
        "-- 核心修正:定义并返回一个函数,供APISIX调用
         return function()
             -- 1. 引入redis库
             local redis = require \"resty.redis\"
             local red = redis:new()
             -- 2. 配置Redis连接参数(按需修改)
             local redis_host = \"127.0.0.1\"
             local redis_port = 6379
             local redis_password = \"\"
             local redis_timeout = 1000
             local redis_pool_size = 100
             local redis_idle_timeout = 60000
             -- 3. 提取请求头中的user参数
             local headers = ngx.req.get_headers()
             local user = headers[\"user\"] or \"default\"
             -- 4. 定义默认上游(兜底)
             local default_upstream = \"192.168.1.102:8080\"
             local target_upstream = default_upstream
             -- 5. 连接Redis并查询
             red:set_timeout(redis_timeout)
             local ok, err = red:connect(redis_host, redis_port)
             if ok then
                 -- Redis密码认证(如有)
                 if redis_password ~= \"\" then
                     local auth_ok, auth_err = red:auth(redis_password)
                     if not auth_ok then
                         ngx.log(ngx.WARN, \"Redis认证失败: \", auth_err)
                     else
                         local res, query_err = red:get(\"user_\" .. user)
                         if res and res ~= ngx.null then
                             target_upstream = res
                             ngx.log(ngx.INFO, \"用户\", user, \"匹配到上游: \", target_upstream)
                         end
                     end
                 else
                     -- 无密码直接查询
                     local res, query_err = red:get(\"user_\" .. user)
                     if res and res ~= ngx.null then
                         target_upstream = res
                         ngx.log(ngx.INFO, \"用户\", user, \"匹配到上游: \", target_upstream)
                     end
                 end
                 -- 释放Redis连接到连接池
                 local pool_ok, pool_err = red:set_keepalive(redis_idle_timeout, redis_pool_size)
                 if not pool_ok then
                     ngx.log(ngx.WARN, \"Redis连接池释放失败: \", pool_err)
                 end
             else
                 ngx.log(ngx.ERR, \"Redis连接失败: \", err)
             end
             -- 6. 动态设置Upstream(核心逻辑)
             ngx.ctx.upstream_nodes = {target_upstream}
             ngx.ctx.upstream_type = \"roundrobin\"
             ngx.ctx.upstream_host = \"redis-dynamic-upstream\"
         end"
      ]
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "127.0.0.1:8080": 1  -- 占位默认值,会被插件覆盖
    }
  }
}'

2、serverless-post-function插件(灵活度高)

serverless-post-function:上游服务返回响应后,APISIX 将响应返回给客户端之前执行,核心能力可概括为:

修改响应头(如添加跨域头、缓存头);

编辑响应体(脱敏、格式化、补充字段);

修改响应状态码;

统一异常响应格式;

采集响应关键指标(如响应耗时、状态码)。

相关推荐
m0_485614671 小时前
K8S项目生命周期管理
云原生·容器·kubernetes
忍冬行者1 小时前
k8s的etcd的一键备份和故障恢复
docker·云原生·容器·kubernetes·云计算
QWsin1 小时前
【k8s】为什么statefulSet初始化pod需要service name
云原生·容器·kubernetes
lin张1 小时前
k8s(三)pod详解(精简版)
云原生·容器·kubernetes
youxiao_902 小时前
kubernetes 插件、操作管理(二)
云原生·容器·kubernetes
NineData2 小时前
NineData云原生智能数据管理平台新功能发布|2025年12月版
数据库·云原生·数据库管理工具·ninedata·数据库迁移·数据库迁移工具·智能数据管理平台
Mr_sun.3 小时前
Day03——微服务网关与配置中心
微服务·云原生·架构
叫致寒吧14 小时前
k8s部署
云原生·容器·kubernetes
DeepFlow 零侵扰全栈可观测17 小时前
3分钟定位OA系统GC瓶颈:DeepFlow全栈可观测平台实战解析
大数据·运维·人工智能·云原生·性能优化
海鸥8119 小时前
K8S中使用 reloader 实现滚动升级
云原生·容器·kubernetes