You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache APISIX自定义插件加载失败,请求技术支持

APISIX自定义插件无法加载排查与解决

我按照APISIX官方插件开发文档开发了新插件jwt-extractor,并修改了现有authz-casbin插件,但配置路由时提示插件不存在,请求返回unknown plugin [jwt-extractor]。


目录结构

.
├── all-in-one
│   └── apisix-dashboard
│       └── conf.yaml
├── apisix
│   └── plugins
│       └── custom-plugins
│           ├── authz-casbin.lua
│           └── jwt-extractor.lua
├── apisix_conf
│   ├── apisix-standalone.yaml
│   └── config.yaml
├── apisix-dashboard
│   └── conf.yaml
├── apisix-plugins
├── apisix_plugins
├── docker-compose-arm64.yml
├── docker-compose-standalone.yml
├── docker-compose.yml
├── etcd_conf
│   └── etcd.conf.yml
├── grafana_conf
│   ├── config
│   │   └── grafana.ini
│   ├── dashboards
│   │   └── apisix-grafana-dashboard.json
│   └── provisioning
│       ├── dashboards
│       │   └── all.yaml
│       └── datasources
│           └── all.yaml
├── mkcert
│   ├── lvh.me+1-key.pem
│   ├── lvh.me+1.pem
│   ├── README.md
│   ├── rootCA-key.pem
│   └── rootCA.pem
├── prometheus_conf
│   └── prometheus.yml
└── upstream
    ├── web1.conf
    └── web2.conf

配置文件

APISIX config.yaml

apisix:
  node_listen: 9080              # APISIX监听端口
  enable_ipv6: false
  # 添加以下配置
  extra_lua_path: "/usr/local/apisix/custom-plugin/?.lua"
  log_level: debug
  enable_control: true
  control:
    ip: "0.0.0.0"
    port: 9092
  

deployment:
  admin:
    allow_admin:
      - 0.0.0.0/0              # 仅测试用,生产需限制IP

    admin_key:
      - name: "admin"
        key: edd1c9f034335f136f87ad84b625c8f1
        role: admin

      - name: "viewer"
        key: 4054f7cf07e344346cd3f287985e76a2
        role: viewer

  etcd:
    host:
      - "http://etcd:2379"
    prefix: "/apisix"
    timeout: 30

plugin_attr:
  prometheus:
    export_addr:
      ip: "0.0.0.0"
      port: 9091

APISIX Dashboard conf.yaml

conf:
  listen:
    host: 0.0.0.0
    port: 9000
  etcd:
    endpoints:
      - etcd:2379

  log:
    error_log:
      level: warn
      file_path: logs/error.log
authentication:
  secret: secret
  expire_time: 3600
  users:
    - username: admin
      password: admin
    - username: user
      password: user

plugin_attr:
  prometheus:
    export_addr:
      ip: "0.0.0.0"
      port: 9091

plugins:
  - authz-casbin
  - jwt-extractor
  - jwt-auth

docker-compose.yml

version: "3"

services:
  apisix:
    image: apache/apisix:${APISIX_IMAGE_TAG:-3.11.0-debian}
    restart: always
    volumes:
      - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
      - ./apisix/plugins/custom-plugins:/usr/local/apisix/custom-plugin/apisix/plugins:ro
    depends_on:
      - etcd
    ports:
      - "9180:9180/tcp"
      - "9080:9080/tcp"
      - "9091:9091/tcp"
      - "9443:9443/tcp"
      - "9092:9092/tcp"
    networks:
      apisix:

  etcd:
    image: bitnami/etcd:3.5.11
    restart: always
    volumes:
      - etcd_data:/bitnami/etcd
    environment:
      ETCD_ENABLE_V2: "true"
      ALLOW_NONE_AUTHENTICATION: "yes"
      ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379"
      ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
    ports:
      - "2379:2379/tcp"
    networks:
      apisix:

  web1:
    image: nginx:1.19.0-alpine
    restart: always
    volumes:
      - ./upstream/web1.conf:/etc/nginx/nginx.conf
    ports:
      - "9081:80/tcp"
    environment:
      - NGINX_PORT=80
    networks:
      apisix:

  web2:
    image: nginx:1.19.0-alpine
    restart: always
    volumes:
      - ./upstream/web2.conf:/etc/nginx/nginx.conf
    ports:
      - "9082:80/tcp"
    environment:
      - NGINX_PORT=80
    networks:
      apisix:

  prometheus:
    image: prom/prometheus:v2.25.0
    restart: always
    volumes:
      - ./prometheus_conf/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    networks:
      apisix:

  grafana:
    image: grafana/grafana:7.3.7
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - "./grafana_conf/provisioning:/etc/grafana/provisioning"
      - "./grafana_conf/dashboards:/var/lib/grafana/dashboards"
      - "./grafana_conf/config/grafana.ini:/etc/grafana/grafana.ini"
    networks:
      apisix:

  dashboard:
    image: apache/apisix-dashboard
    restart: always
    ports:
      - "9000:9000"
    volumes:
      - ../all-in-one/apisix-dashboard/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
    networks:
      apisix:
    depends_on:
      - etcd

networks:
  apisix:
    driver: bridge

volumes:
  etcd_data:
    driver: local

问题现象

已确认插件文件已复制到APISIX容器:

❯ docker exec docker-apisix-apisix-1 ls /usr/local/apisix/custom-plugin/apisix/plugins
authz-casbin.lua
jwt-extractor.lua

执行路由配置请求:

curl --request PUT \
  --url http://127.0.0.1:9180/apisix/admin/routes \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
  --data '{
  "id":"jwt-extractor",
  "uri":"/test",
  "plugins": {
        "jwt-extractor": {
            "role_claim": "role"
        }
    }
}'

返回错误:

{
    "error_msg": "unknown plugin [jwt-extractor]"
}

测试另一个自定义插件file-proxy时,同样返回unknown plugin [file-proxy],且相关日志文件中无报错信息。


环境信息

  • APISIX版本:3.11.0-debian
  • 操作系统:debian(Docker镜像)
  • OpenResty/Nginx版本:1.19.0
  • etcd版本:3.5.11
  • APISIX Dashboard版本:3.0.1

根本原因与解决方案

根本原因

  1. Lua路径配置错误:extra_lua_path设置为/usr/local/apisix/custom-plugin/?.lua,但插件实际挂载在/usr/local/apisix/custom-plugin/apisix/plugins/,APISIX无法定位到插件文件。
  2. 未明确启用自定义插件:APISIX不会自动扫描加载自定义插件,需在配置中明确声明。

解决方案

1. 修正Lua路径配置

修改APISIX config.yaml中的extra_lua_path,确保覆盖插件实际路径:

apisix:
  # 其他配置...
  extra_lua_path: "/usr/local/apisix/custom-plugin/apisix/plugins/?.lua"

2. 启用自定义插件

在config.yaml的apisix节点下新增plugins字段,声明要加载的自定义插件:

apisix:
  # 其他配置...
  plugins:
    - jwt-extractor
    - authz-casbin
    # 保留原有默认插件,如jwt-auth等

3. 优化Docker挂载路径(可选)

将本地插件目录直接挂载到APISIX默认插件目录,简化配置:

# 修改docker-compose.yml中apisix服务的volumes
volumes:
  - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
  - ./apisix/plugins/custom-plugins:/usr/local/apisix/plugins:ro

同时调整extra_lua_path为:

extra_lua_path: "/usr/local/apisix/plugins/?.lua"

4. 重启APISIX容器

docker-compose restart apisix

5. 验证插件加载

执行命令查看已加载插件列表:

curl http://127.0.0.1:9180/apisix/admin/plugins/list -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1"

返回结果中应包含jwt-extractor和authz-casbin。


内容的提问来源于stack exchange,提问作者Will

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 13:07:01