fault-injection
fault-injection 插件通过模拟受控故障或延迟来测试应用的弹性。它在 rewrite 阶段运行。在同一 rewrite 执行轮次中,插件按优先级从高到低运行,_meta.priority 可以覆盖插件的默认优先级。fault-injection 的默认优先级为 11000,在该轮次中先于低优先级的 rewrite 阶段处理器运行,后于高优先级的 rewrite 阶段处理器运行。全局规则插件与路由或服务插件在不同的 rewrite 执行轮次中运行。因此,该插件适用于混沌工程等场景,可用来分析系统在故障条件下的行为。
该插件支持两种动作。abort 会立即以指定的 HTTP 状态码(例如 503 Service Unavailable)结束请求处理,因此后续的 rewrite 和 access 阶段处理器不会运行,但响应过滤和日志处理器仍可针对注入的响应运行。delay 会将请求处理暂停指定时长。这些动作可模拟服务中断或延迟,帮助你验证错误处理逻辑并提高系统可靠性。
示例
以下示例演示了如何在不同场景下配置 fault-injection 插件。
注入故障
以下示例演示了如何在路由上配置 fault-injection 插件,以拦截进一步的请求发送,并返回特定的 HTTP 代码。
创建一个使用 fault-injection 插件的路由,使用 abort 动作将任何请求响应为 404 并返回指定的响应体:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "fault-injection-route",
"uri": "/anything",
"plugins": {
"fault-injection": {
"abort": {
"http_status": 404,
"body": "APISIX Fault Injection"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: httpbin
routes:
- name: fault-injection-route
uris:
- /anything
plugins:
fault-injection:
abort:
http_status: 404
body: "APISIX Fault Injection"
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
预览变更,并 确认仅影响本指南使用的资源:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=fault-injection
将配置同步到网关:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=fault-injection
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: fault-injection-plugin-config
spec:
plugins:
- name: fault-injection
config:
abort:
http_status: 404
body: "APISIX Fault Injection"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: fault-injection-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: fault-injection-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
将配置应用到集群:
kubectl apply -f fault-injection-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: fault-injection-route
spec:
ingressClassName: apisix
http:
- name: fault-injection-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: fault-injection
enable: true
config:
abort:
http_status: 404
body: "APISIX Fault Injection"
将配置应用到集群:
kubectl apply -f fault-injection-ic.yaml
发送请求到路由:
curl -i "http://127.0.0.1:9080/anything"
你应该收到 HTTP/1.1 404 Not Found 响应并看到以下响应体,而请求不会被转发到上游服务:
APISIX Fault Injection
注入延迟
以下示例演示了如何在路由上配置 fault-injection 插件以注入请求延迟。
创建一个使用 fault-injection 插件的路由,使用 delay 动作将响应发送延迟 3 秒:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "fault-injection-route",
"uri": "/anything",
"plugins": {
"fault-injection": {
"delay": {
"duration": 3
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: httpbin
routes:
- name: fault-injection-route
uris:
- /anything
plugins:
fault-injection:
delay:
duration: 3
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
预览变更,并确认仅影响本指南使用的资源:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=fault-injection
将配置同步到网关:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=fault-injection
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: fault-injection-plugin-config
spec:
plugins:
- name: fault-injection
config:
delay:
duration: 3
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: fault-injection-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: fault-injection-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
将配置应用到集群:
kubectl apply -f fault-injection-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: fault-injection-route
spec:
ingressClassName: apisix
http:
- name: fault-injection-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: fault-injection
enable: true
config:
delay:
duration: 3
将配置应用到集群:
kubectl apply -f fault-injection-ic.yaml
发送请求到路由,并使用 time 命令总结请求完成所需的时间:
time curl -i "http://127.0.0.1:9080/anything"
你应该收到来自上游服务的 HTTP/1.1 200 OK 响应,并看到以下计时摘要:
0.01s user
0.01s system
0% cpu
3.685 total
有条件地注入故障
以下示例演示了如何在路由上配置 fault-injection 插件,以拦截进一步的请求发送,并返回特定的 HTTP 代码。
创建一个使用 fault-injection 插件的路由,使用 abort 动作,如下所示:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "fault-injection-route",
"uri": "/anything",
"plugins": {
"fault-injection": {
"abort": {
"http_status": 404,
"body": "APISIX Fault Injection",
"headers": {
"X-APISIX-Remote-Addr": "$remote_addr"
},
"vars": [
[
[ "arg_name","==","john" ]
]
]
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: httpbin
routes:
- name: fault-injection-route
uris:
- /anything
plugins:
fault-injection:
abort:
http_status: 404
body: "APISIX Fault Injection"
headers:
X-APISIX-Remote-Addr: $remote_addr
vars:
- - - arg_name
- "=="
- john
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
预览变更,并确认仅影响本指南使用的资源:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=fault-injection
将配置同步到网关:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=fault-injection
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: fault-injection-plugin-config
spec:
plugins:
- name: fault-injection
config:
abort:
http_status: 404
body: "APISIX Fault Injection"
headers:
X-APISIX-Remote-Addr: $remote_addr
vars:
- - - arg_name
- "=="
- john
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: fault-injection-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: fault-injection-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
将配置应用到集群:
kubectl apply -f fault-injection-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: fault-injection-route
spec:
ingressClassName: apisix
http:
- name: fault-injection-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: fault-injection
enable: true
config:
abort:
http_status: 404
body: "APISIX Fault Injection"
headers:
X-APISIX-Remote-Addr: $remote_addr
vars:
- - - arg_name
- "=="
- john
将配置应用到集群:
kubectl apply -f fault-injection-ic.yaml
❶ 使用 HTTP 状态码 404 响应请求。
❷ 使用 APISIX Fault Injection 作为响应体。
❸ 响应请求时添加头 X-APISIX-Remote-Addr 和请求来源的 IP。
❹ 仅当 URL 参数 name 的值为 john 时,才按上述规范响应请求。
发送带有 URL 参数 name 为 john 的请求到路由:
curl -i "http://127.0.0.1:9080/anything?name=john"
你应该收到 HTTP/1.1 404 Not Found 响应:
HTTP/1.1 404 Not Found
...
X-APISIX-Remote-Addr: 192.168.65.1
APISIX Fault Injection
发送带有 URL 参数 name 为不同值的请求到路由:
curl -i "http://127.0.0.1:9080/anything?name=jane"
你应该收到来自上游服务的 HTTP/1.1 200 OK 响应,而没有注入故障。