除了 APISIX 官方内置的插件除外,咱们也不错阐明我方的需求去自界说插件,要自界说插件需要使用到 APISIX 提供的 Runner,当今依然援助 Java、Go 和 Python 言语的 Runner,这个 Runner 超越于是 APISIX 和自界说插件之间的桥梁,比如 apache-apisix-python-runner 这个状貌通过 Python Runner 不错把 Python 径直哄骗到 APISIX 的插件开发中,举座架构如下所示:
其中的 Plugin Runner 即是各言语的插件开动器,当竖立 Plugin Runner 后,APISIX 会启动一个子程度开动 Plugin Runner,该子程度与 APISIX 程度属于团结个用户,当咱们重启或再行加载 APISIX 时,Plugin Runner 也将被重启。
要是你为一个给定的路由竖立了 ext-plugin-* 插件,肯求掷中该路由时将触发 APISIX 通过 Unix Socket 向 Plugin Runner 发起 RPC 调用。调用分为两个阶段:
ext-plugin-pre-req:在本质 APISIX 内置插件之前 ext-plugin-post-req:在本质 APISIX 内置插件之后接下来咱们就以 Python 为例来诠释如何自界说插件,当先取得 apache-apisix-python-runner 状貌:
➜ git clone https://github.com/apache/apisix-python-plugin-runner.git ➜ cd apisix-python-plugin-runner ➜ git checkout 0.1.0 # 切换刀0.1.0版块
要是是开发风景,则咱们不错径直使用底下的号召启动 Python Runner:
➜ APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock python3 apisix/main.py start
启动后需要在 APISIX 竖立文献中新增外部插件竖立,如下所示:
➜ vim /path/to/apisix/conf/config.yaml apisix: admin_key: - name: "admin" key: edd1c9f034335f136f87ad84b625c8f1 role: admin ext-plugin: path_for_test: /tmp/runner.sock
通过 ext-plugin.path_for_test 指定 Python Runner 的 unix socket 文献旅途即可,要是是坐褥环境则不错通过 ext-plugin.cmd 来指定 Runner 的启动号召即可:
ext-plugin: cmd: [ "python3", "/path/to/apisix-python-plugin-runner/apisix/main.py", "start" ]
咱们这里的 APISIX 是开动 Kubernetes 集群中的,是以要在 APISIX 的 Pod 中去本质 Python Runner 的代码,咱们当然需要将咱们的 Python 代码放到 APISIX 的容器中去,然后安设自界说插件的相干依赖,径直在 APISIX 竖立文献中添加上头的竖立即可,是以咱们这里基于 APISIX 的镜像来再行定制包含插件的镜像,国产精品国产三级国产av在 apisix-python-plugin-runner 状貌根目次下新增如下所示的 Dockerfile 文献:
FROM apache/apisix:2.10.0-alpine ADD . /apisix-python-plugin-runner RUN apk add --update python3 py3-pip && \ cd /apisix-python-plugin-runner && \ python3 -m pip install --upgrade pip && \ python3 -m pip install -r requirements.txt --ignore-installed && \ python3 setup.py install --force
基于上头 Dockerfile 构建一个新的镜像,推送到 Docker Hub:
➜ docker build -t cnych/apisix:py3-plugin-2.10.0-alpine . # 推送到DockerHub ➜ docker push cnych/apisix:py3-plugin-2.10.0-alpine
接下来咱们需要使用上头构建的镜像来安设 APISIX,咱们这里使用的是 Helm Chart 进行安设的,是以需要通过 Values 文献进行掩饰,如下所示:
# ci/prod.yaml apisix: enabled: true image: repository: cnych/apisix tag: py3-plugin-2.10.0-alpine ......
由于官方的 Helm Chart 莫得提供对 ext-plugin 竖立的援助,是以需要咱们手动修改模板文献 templates/configmap.yaml,在 apisix 属性同级目次底下新增 ext-plugin 相干竖立,如下所示:
{{- if .Values.extPlugins.enabled }} ext-plugin: {{- if .Values.extPlugins.pathForTest }} path_for_test: {{ .Values.extPlugins.pathForTest }} {{- end }} {{- if .Values.extPlugins.cmds }} cmd: {{- range $cmd := .Values.extPlugins.cmds }} - {{ $cmd }} {{- end }} {{- end }} {{- end }} nginx_config: user: root # fix 本质 python runner没权限的问题
然后在定制的 Values 文献中添加如下所示的竖立:
# ci/prod.yaml extPlugins: enabled: true cmds: ["python3", "/apisix-python-plugin-runner/apisix/main.py", "start"]
接着就不错再行部署 APISIX 了:
➜ helm upgrade --install apisix ./apisix -f ./apisix/ci/prod.yaml -n apisix
部署完成后在 APISIX 的 Pod 中不错看到会启动一个 Python Runner 的子程度:
在插件目次 /apisix-python-plugin-runner/apisix/plugins 中的 .py 文献都会被自动加载,上头示例中有两个插件 stop.py 和 rewrite.py,天天摸夜夜添添到高潮水汪汪咱们以 stop.py 为例进行诠释,该插件代码如下所示:
from apisix.runner.plugin.base import Base from apisix.runner.http.request import Request from apisix.runner.http.response import Response class Stop(Base): def __init__(self): super(Stop, self).__init__(self.__class__.__name__) def filter(self, request: Request, response: Response): # 不错通过 `self.config` 取得竖立信息,要是插件竖立为JSON将自动调遣为字典结构 # print(self.config) # 开导反馈 Header 头 response.headers["X-Resp-A6-Runner"] = "Python" # 开导反馈body response.body = "Hello, Python Runner of APISIX" # 开导反馈情景码 response.status_code = 201 # 通过调用 `self.stop()` 中断肯求经由,此时将立即反馈肯求给客户端 # 要是未知道调用 `self.stop()` 或 知道调用 `self.rewrite()`将不竭将肯求 # 默许为 `self.rewrite()` self.stop()
结束插件当先必须要接管 Base 类,必须结束 filter 函数,插件本质中枢业务逻辑即是在 filter 函数中,该函数只包含 Request 和 Response 类对象当作参数,Request 对象参数不错取得肯求信息,Response 对象参数不错开导反馈信息 ,self.config 不错取得插件竖立信息,在 filter 函数中调用 self.stop() 时将随即中断肯求,反馈数据,调用 self.rewrite() 时,将会不竭肯求。
然后咱们在前边的 Nexus 哄骗中新增一个路由来测试咱们上头的 stop 插件,在 ApisixRoute 对象中新增一个路由规则,如下所示:
apiVersion: apisix.apache.org/v2beta2 kind: ApisixRoute metadata: name: nexus namespace: default spec: http: - name: ext match: hosts: - ops.qikqiak.com paths: - "/extPlugin" plugins: - name: ext-plugin-pre-req # 启用ext-plugin-pre-req插件 enable: true config: conf: - name: "stop" # 使用 stop 这个自界说插件 value: "{\"body\":\"hello\"}" backends: - serviceName: nexus servicePort: 8081
径直创建上头的路由即可,中枢竖立是启用 ext-plugin-pre-req 插件(前提是在竖立文献中依然启用该插件,在 Helm Chart 的 Values 中添加上),然后在 config 底下使用 conf 属性进行竖立,conf 为数组设施不错同期开导多个插件,插件竖立对象中 name 为插件称号,该称号需要与插件代码文献和对象称号一致,value 为插件竖立,不错为 JSON 字符串。
创建后一样在 Dashboard 中也不错看到 APISIX 中的路由竖立设施:
接着咱们不错来造访 http://ops.qikqiak.com/extPlugin 这个旅途来考据咱们的自界说插件:
➜ curl -i http://ops.qikqiak.com/extPlugin HTTP/1.1 201 Created Date: Thu, 13 Jan 2022 07:04:50 GMT Content-Type: text/plain; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive accept: */* user-agent: curl/7.64.1 host: ops.qikqiak.com X-Resp-A6-Runner: Python Server: APISIX/2.10.0 Hello, Python Runner of APISIX
造访肯求着力中有一个 X-Resp-A6-Runner: Python 头信息,复返的 body 数据为 Hello, Python Runner of APISIX,和咱们在插件中的界说是妥当的。到这里就完成了使用 Python 进行 APISIX 自界说插件,咱们有任何的业务逻辑需要科罚径直去界说一个对应的插件即可。