使用调试模式
APISIX 提供了一种调试模式,以帮助开发人员更好地理解和排查网关的运行时行为。完整的配置选项可以在 debug.yaml 中找到。
本指南将向你展示如何启用调试模式以检查请求路由上启用了哪些插件,以及如何添加钩子以记录 APISIX 模块函数的输入参数和返回值。
前 置条件
启用基本调试模式
启用基本调试模式将允许你在 Apisix-Plugins 标头中检查请求路由上启用了哪些插件。
默认情况下,调试模式处于关闭状态。要启用调试模式,你可以在 debug.yaml 文件中将 basic.enable 设置为 true。
- Docker
- Kubernetes
docker exec apisix-quickstart /bin/sh -c "echo '
basic:
enable: true
#END
' > /usr/local/apisix/conf/debug.yaml"
debug.yaml 文件在启动时加载到内存中,并定期监控更改,因此更新文件后无需手动重新加载 APISIX。
创建一个 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: apisix-debug
namespace: ingress-apisix
data:
debug.yaml: |
basic:
enable: true
#END
将 ConfigMap 应用到你的集群:
kubectl apply -f apisix-debug-cm.yaml
要挂载 ConfigMap,首先导出所有值(包括默认值):
helm get values -n ingress-apisix apisix --all > values.yaml
在 values 文件中,更新以下部分值如下:
extraVolumes:
- name: debug-config
configMap:
name: apisix-debug
extraVolumeMounts:
- name: debug-config
mountPath: /usr/local/apisix/conf/debug.yaml
subPath: debug.yaml
升级发布:
helm upgrade -n ingress-apisix apisix apisix/apisix -f values.yaml
debug.yaml 配置应以 #END 结尾,否则 APISIX 将不会加载配置。
你也可以使用 #END 标志作为断点,让 APISIX 仅加载到指定点的配置。
要进行验证,请创建一个没有任何插件的路由:
- Admin API
- ADC
- Ingress Controller
curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
"id": "getting-started-anything",
"uri": "/anything",
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
services:
- name: httpbin Service
routes:
- uris:
- /anything
name: getting-started-anything
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到 APISIX:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: ingress-apisix
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: ingress-apisix
name: getting-started-anything
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: ingress-apisix
name: httpbin-external-domain
spec:
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: ingress-apisix
name: getting-started-anything
spec:
ingressClassName: apisix
http:
- name: getting-started-anything
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
将配置应用到你的集群:
kubectl apply -f httpbin-route.yaml
向路由发送请求:
curl -i "http://127.0.0.1:9080/anything"
你应该收到 HTTP/1.1 200 OK 响应并观察到以下标头:
Content-Type: application/json
Content-Length: 390
Connection: keep-alive
Apisix-Plugins: no plugin
...
- Admin API
- ADC
- Ingress Controller
更新带有插件的路由:
curl -i "http://127.0.0.1:9180/apisix/admin/routes/getting-started-anything" -X PATCH -d '
{
"plugins": {
"limit-count": {
"count": 5,
"time_window": 10,
"rejected_code": 429
}
}
}'
此外,添加一个 全局插件:
curl -i "http://127.0.0.1:9180/apisix/admin/global_rules" -X PUT -d '{
"id": "global-prometheus",
"plugins": {
"prometheus":{}
}
}'
更新带有插件的路由并添加另一个 全局插件:
services:
- name: httpbin Service
routes:
- uris:
- /anything
name: getting-started-anything
plugins:
limit-count:
count: 5
time_window: 10
rejected_code: 429
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
global_rules:
prometheus: {}
将配置同步到 APISIX:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
更新路由清单文件以包含插件:
apiVersion: v1
kind: Service
metadata:
namespace: ingress-apisix
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: ingress-apisix
name: limit-count-plugin-config
spec:
plugins:
- name: limit-count
config:
count: 5
time_window: 10
rejected_code: 429
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: ingress-apisix
name: getting-started-anything
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: limit-count-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
此外,更新你的 GatewayProxy 清单以将 prometheus 启用为全局插件:
要在添加其他配置之前查看当前 GatewayProxy 配置,请运行:
kubectl get gatewayproxy apisix-config -o yaml
apiVersion: apisix.apache.org/v1alpha1
kind: GatewayProxy
metadata:
namespace: ingress-apisix
name: apisix-config
spec:
provider:
type: ControlPlane
controlPlane:
auth:
adminKey:
value: edd1c9f034335f136f87ad84b625c8f1
type: AdminKey
service:
name: apisix-admin
port: 9180
plugins:
- name: prometheus
enabled: true
将配置应用到你的集群:
kubectl apply -f httpbin-route.yaml -f gateway-proxy.yaml
更新带有插件的路由:
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: ingress-apisix
name: httpbin-external-domain
spec:
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: ingress-apisix
name: getting-started-anything
spec:
ingressClassName: apisix
http:
- name: getting-started-anything
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: limit-count
enable: true
config:
count: 5
time_window: 10
rejected_code: 429
此外,为全局 Prometheus 插件创建一个 Kubernetes 清单文件:
apiVersion: apisix.apache.org/v2
kind: ApisixGlobalRule
metadata:
namespace: ingress-apisix
name: global-prometheus
spec:
ingressClassName: apisix
plugins:
- name: prometheus
enable: true
将配置应用到你的集群:
kubectl apply -f httpbin-route.yaml -f global-prometheus.yaml
向路由发送另一个请求:
curl -i "http://127.0.0.1:9080/anything"
你应该收到 HTTP/1.1 200 OK 响应并观察到以下标头:
Content-Type: application/json
Content-Length: 388
Connection: keep-alive
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 4
X-RateLimit-Reset: 10
Apisix-Plugins: limit-count, prometheus
...
如果插件信息无法包含在响应标头中(例如 L4 流插件),则调试信息将以 warn 严重性级别记录在错误日志中。
配置高级调试模式
debug.yaml 中还有一些其他高级选项可以配置。
记录函数输入参数和返回值
你可以使用以下配置向 APISIX 阶段 添加钩子,以记录输入参数和返回值:
basic:
enable: true
hook_conf:
// Annotate 1
enable: true
// Annotate 2
name: hook_phase
// Annotate 3
log_level: warn
// Annotate 4
is_print_input_args: true
// Annotate 5
is_print_return_value: true
// Annotate 6
hook_phase:
apisix:
- http_access_phase
- http_header_filter_phase
- http_body_filter_phase
- http_log_phase
#END
❶ 启用钩子调试追踪以记录目标模块函数的输入参数或返回值。
❷ 模块名称和函数列表。
❸ 错误日志中输入参数和返回值的严重性级别。
❹ 记录输入参数。
❺ 记录返回值。
❻ 模块名称和函数列表。
要进行验证,请向路由发送请求:
curl -i "http://127.0.0.1:9080/anything"
你应该收到 HTTP/1.1 200 OK 响应,并在错误日志中看到以下信息:
call require("apisix").http_access_phase() args:{}
call require("apisix").http_access_phase() return:{}
call require("apisix").http_header_filter_phase() args:{}
call require("apisix").http_header_filter_phase() return:{}
call require("apisix").http_body_filter_phase() args:{}
call require("apisix").http_body_filter_phase() return:{}
call require("apisix").http_log_phase() args:{}
call require("apisix").http_log_phase() return:{}
动态应用高级调试设置
你还可以配置为仅当存在特定标头时才动态记录函数输入参数和返回值:
docker exec apisix-quickstart /bin/sh -c "echo '
basic:
enable: true
http_filter:
// Annotate 1
enable: true
// Annotate 2
enable_header_name: X-APISIX-Dynamic-Debug
hook_conf:
enable: true
name: hook_phase
log_level: warn
is_print_input_args: true
is_print_return_value: true
hook_phase:
apisix:
- http_access_phase
- http_header_filter_phase
- http_body_filter_phase
- http_log_phase
#END
❶ 启用 HTTP 过滤器以动态应用高级调试设置。
❷ 仅当请求具有 X-APISIX-Dynamic-Debug 标头时才记录输入参数和返回值。
要进行验证,请向路由发送不带任何标头的请求:
curl -i "http://127.0.0.1:9080/anything"
你应该收到 HTTP/1.1 200 OK 响应,但在错误日志中没有观察到调试信息。
发送另一个带有调试标头的请求:
curl -i "http://127.0.0.1:9080/anything" -H "X-APISIX-Dynamic-Debug: 1"
你应该收到 HTTP/1.1 200 OK 响应,并在错误日志中看到以下信息:
call require("apisix").http_access_phase() args:{}
call require("apisix").http_access_phase() return:{}
call require("apisix").http_header_filter_phase() args:{}
call require("apisix").http_header_filter_phase() return:{}
call require("apisix").http_body_filter_phase() args:{}
call require("apisix").http_body_filter_phase() return:{}
call require("apisix").http_log_phase() args:{}
call require("apisix").http_log_phase() return:{}
按环境管理 debug.yaml
你可能希望为每个环境拥有不同的 debug.yaml 文件,例如使用 conf/debug-dev.yaml 用于开发环境,使用 conf/debug-prod.yaml 用于生产环境。这可以通过设置 APISIX_PROFILE 变量来完成。
有关更多详细信息,请参阅 按环境管理配置文件。
下一步
你现在已经学会了如何利用 APISIX 中的调试模式进行故障排除以及它提供的各种调试选项。你可以在 debug.yaml 中找到完整的配置选项。
如果你正在使用 APISIX Ingress Controller,请参阅 配置故障排除 以了解如何检查内存中转换后的 ADC 配置以及检查实际应用于网关的配置。