fault-injection
fault-injection 插件旨在通过模拟受控故障或延迟来测试应用程序的弹性。它在其他配置的插件之前执行,确保故障被一致地应用。这使其非常适合混沌工程等场景,在这些场景中,需要分析系统在故障条件下的行为。
该插件支持两个关键动作:abort,它会立即以指定的 HTTP 状态码(例如 503 Service Unavailable)终止请求,并跳过所有后续插件;以及 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 sync -f adc.yaml
- 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 sync -f adc.yaml
- 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 sync -f adc.yaml
- 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 响应,而没有注入故障。