配置上游健康检查
健康检查是一种根据上游服务响应情况判断其健康或不健康的机制。启用健康检查后,网关只会将请求转发到被认为健康的上游服务,不会转发到被认为不健康的服务。
健康检查通常有两种方式:
- 主动检查:网关主动、定期向上游服务发送请求,并根据这些请求的响应判断上游服务健康状态。
- 被动检查:网关不主动探测,而是根据上游服务对客户端请求的响应判断健康状态。
本文介绍如何通过 Ingress Controller 为上游服务配置主动和被动健康检查。
前提条件
启动示例上游服务
创建 Kubernetes manifest 文件,部署两个 NGINX 实例作为示例上游服务:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: nginx1
spec:
replicas: 1
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: nginx1
spec:
selector:
app: nginx1
ports:
- port: 8080
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: nginx2
spec:
replicas: 1
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: nginx2
spec:
selector:
app: nginx2
ports:
- port: 8081
targetPort: 80
将配置应用到集群:
kubectl apply -f nginx.yaml
通过端口转发将 NGINX Service 端口暴露到本地:
kubectl port-forward svc/nginx1 8080:8080 &
kubectl port-forward svc/nginx2 8081:8081 &
验证两个 NGINX 实例是否正常运行:
for port in 8080 8081; do
curl -s "http://127.0.0.1:$port" | grep -q "Welcome to nginx" &&
echo "NGINX welcome page available on port $port."
done
你应看到以下响应:
NGINX welcome page available on port 8080.
NGINX welcome page available on port 8081.
启用 Control API
升级网关以启用 Control API。
- APISIX 网关
- API7 网关
导出所有 values(包括默认值):
helm get values -n aic apisix --all > values.yaml
在 values 文件中按如下方式更新配置:
apisix:
enabled: true
control:
enabled: true
升级 Helm release:
helm upgrade -n aic apisix apisix/apisix -f values.yaml
转发 Control API 端口:
kubectl port-forward service/apisix-control 9090:9090 &
默认情况下,Control API 会在 9090 端口启用:
control:
enabled: true
ip: 127.0.0.1
port: 9090
转发 Control API 端口:
kubectl port-forward pod/<api7-gateway-pod-name> 9090:9090 &
配置主动健康检查
主动检查会定期向上游服务发送请求或探针,并根据响应判断上游服务的健康状态。
本节通过两个示例帮助你理解:
- 主动检查如何检测上游状态变化。
- 当所有上游状态均为不健康时,网关如何向上游服务转发客户端请求。
示例:上游服务状态变化
以下示例演示当健康的上游服务变为部分不可用、全部不可用以及全部恢复时,主动健康检查如何响应。
创建指向两个服务的路由,并配置每 2 秒运行一次的主动健康检查:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: aic
name: nginx1
spec:
targetRefs:
- name: nginx1
kind: Service
group: ""
healthCheck:
active:
type: http
httpPath: /
healthy:
interval: 2s
successes: 1
unhealthy:
interval: 1s
timeouts: 3
---
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: aic
name: nginx2
spec:
targetRefs:
- name: nginx2
kind: Service
group: ""
healthCheck:
active:
type: http
httpPath: /
healthy:
interval: 2s
successes: 1
unhealthy:
interval: 1s
timeouts: 3
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: example-hc-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /
backendRefs:
- name: nginx1
port: 8080
weight: 1
- name: nginx2
port: 8081
weight: 1
将配置应用到集群:
kubectl apply -f active-health-checks.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: nginx
spec:
ingressClassName: apisix
externalNodes:
- type: Service
name: nginx1
port: 8080
- type: Service
name: nginx2
port: 8081
healthCheck:
active:
type: http
httpPath: /
healthy:
interval: 2s
successes: 1
unhealthy:
interval: 1s
timeout: 3
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: example-hc-route
spec:
ingressClassName: apisix
http:
- name: nginx-hc
match:
paths:
- /
upstreams:
- name: nginx
❶ type:主动健康检 查的类型。
❷ httpPath:主动探测使用的 HTTP 请求路径。
❸ healthy.interval:定期检查健康节点的时间间隔,单位为秒。
❹ healthy.successes:判定上游节点健康所需的成功次数阈值。
❺ unhealthy.interval:定期检查不健康节点的时间间隔,单位为秒。
❻ unhealthy.timeout:判定上游节点不健康所需的超时次数阈值。
将配置应用到集群:
kubectl apply -f active-health-checks.yaml
验证
你将验证以上配置,以了解上游健康检查在不同场景下的响应方式:
- 所有上游服务均健康时。
- 只有部分服务健康时。
- 所有服务均不健康时。
- 所有服务恢复健康时。
继续之前,先将网关 Service 端口暴露到本地:
# 替换为你的网关 Service 名称
kubectl port-forward svc/<gateway-service-name> 9080:80 &
验证两个上游服务均健康
向路由发送请求以启动健康检查:
curl "http://127.0.0.1:9080/"
如需查看上游健康状态,请向 Control API 中的健康检查端点发送请求:
curl "http://127.0.0.1:9090/v1/healthcheck"
你应看到类似如下响应:
[
{
"name": "/apisix/routes/example-hc-route",
"type": "http",
"nodes": [
{
"port": 80,
"counter": {
"http_failure": 0,
"tcp_failure": 0,
"timeout_failure": 0,
"success": 0
},
"ip": "172.24.0.5",
"status": "healthy"
},
{
"port": 80,
"counter": {
"http_failure": 0,
"tcp_failure": 0,
"timeout_failure": 0,
"success": 0
},
"ip": "172.24.0.4",
"status": "healthy"
}
]
}
]
验证一个上游服务不可用
临时将一个上游服务设为不可用,验证网关是否将其中一个上游服务报告为不健康:
kubectl scale deployment nginx1 -n aic --replicas=0
等待几秒后,向健康检查端点发送请求:
curl "http://127.0.0.1:9090/v1/healthcheck"
你应看到类似如下响应,表示其中一个上游节点出现 3 次超时失败并被标记为不健康:
[
{
"name": "/apisix/routes/example-hc-route",
"type": "http",
"nodes": [
{
"port": 80,
"counter": {
"http_failure": 0,
"tcp_failure": 0,
"timeout_failure": 0,
"success": 0
},
"ip": "172.24.0.5",
"status": "healthy"
},
{
"port": 80,
"counter": {
"http_failure": 0,
"tcp_failure": 0,
"timeout_failure": 3,
"success": 0
},
"ip": "172.24.0.4",
"status": "unhealthy"
}
]
}
]
向路由发送请求,确认网关是否会将请求转发到另一个健康节点:
curl -i "http://127.0.0.1:9080/"
你应收到 HTTP/1.1 200 OK 响应.
验证两个上游服务均不可用
临时将另一个上游服务也设为不可用,验证网关是否将两个上游服务都报告为不健康:
kubectl scale deployment nginx2 -n aic --replicas=0
等待几秒后,向健康检查端点发送请求:
curl "http://127.0.0.1:9090/v1/healthcheck"
你应看到类似如下响应,表示两个上游节点均出现 3 次超时失败并被标记为不健康:
[
{
"name": "/apisix/routes/example-hc-route",
"type": "http",
"nodes": [
{
"port": 80,
"counter": {
"http_failure": 0,
"tcp_failure": 0,
"timeout_failure": 3,
"success": 0
},
"ip": "172.24.0.5",
"status": "unhealthy"
},
{
"port": 80,
"counter": {
"http_failure": 0,
"tcp_failure": 0,
"timeout_failure": 3,
"success": 0
},
"ip": "172.24.0.4",
"status": "unhealthy"
}
]
}
]
向路由发送请求:
curl -i "http://127.0.0.1:9080/"
你应 receive an HTTP/1.1 502 Bad Gateway response.
验证两个上游服务均已恢复
重新启用两个服务,验证网关是否将两个上游服务都报告为健康:
kubectl scale deployment -n aic nginx1 nginx2 --replicas=1
等待几秒后,向健康检查端点发送请求:
curl "http://127.0.0.1:9090/v1/healthcheck"
你应看到一个响应,显示两个上游节点均处于健康状态,类似于开始时两个服务都健康的场景。
示例:状态不健康时转发请求
以下示例演示即使所有上游都被标记为不健康,网关仍会将客户端请求转发到上游服务。
创建指向两个服务的路由,并配置每 2 秒运行一次的主动健康检查:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: aic
name: nginx1
spec:
targetRefs:
- name: nginx1
kind: Service
group: ""
healthCheck:
active:
type: http
httpPath: /404
healthy:
interval: 2s
successes: 1
unhealthy:
interval: 1s
httpFailures: 2
---
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: aic
name: nginx2
spec:
targetRefs:
- name: nginx2
kind: Service
group: ""
healthCheck:
active:
type: http
httpPath: /404
healthy:
interval: 2s
successes: 1
unhealthy:
interval: 1s
httpFailures: 2
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: example-hc-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /
backendRefs:
- name: nginx1
port: 8080
weight: 1
- name: nginx2
port: 8081
weight: 1
将配置应用到集群:
kubectl apply -f active-health-checks.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: nginx
spec:
ingressClassName: apisix
externalNodes:
- type: Service
name: nginx1
port: 8080
- type: Service
name: nginx2
port: 8081
healthCheck:
active:
type: http
httpPath: /404
healthy:
interval: 2s
successes: 1
unhealthy:
interval: 1s
httpFailures: 2
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: example-hc-route
spec:
ingressClassName: apisix
http:
- name: nginx-hc
match:
paths:
- /
upstreams:
- name: nginx
❶ type:主动健康检查的类型。
❷ httpPath:主动探测使用的 HTTP 请求路径。为便于演示,这里设置为 /404,这是上游服务中不存在的路径。因此,两个服务都会始终被主动健康检查判定为不健康。
❸ unhealthy.httpFailures:判定上游节点不健康所需的 HTTP 失败次数阈值。
将配置应用到集群:
kubectl apply -f active-health-checks.yaml
验证
将网关 Service 端口暴露到本地机器:
# 替换为你的网关 Service 名称
kubectl port-forward svc/<gateway-service-name> 9080:80 &
向路由发送请求以启动健康检查:
curl -i "http://127.0.0.1:9080/"
你应收到 HTTP/1.1 200 OK 响应.
向健康检查端点发送请求:
curl "http://127.0.0.1:9090/v1/healthcheck"
你应看到类似如下响应:
[
{
"name": "/apisix/routes/example-hc-route",
"nodes": [
{
"counter": {
"timeout_failure": 0,
"http_failure": 2,
"success": 0,
"tcp_failure": 0
},
"port": 80,
"ip": "172.25.0.5",
"status": "unhealthy"
},
{
"counter": {
"timeout_failure": 0,
"http_failure": 2,
"success": 0,
"tcp_failure": 0
},
"port": 80,
"ip": "172.25.0.4",
"status": "unhealthy"
}
],
"type": "http"
}
]
向路由发送请求,确认网关是否仍会转发请求:
curl -i "http://127.0.0.1:9080/"
你应收到 HTTP/1.1 200 OK 响应。这说明即使两个服务都被标记为不健康,网关仍会将客户端请求转发到上游服务。
配置被动健康检查
如需使用被动健康检查,也必须配置主动健康检查。当上游服务变为不健康时,主动健康检查会定期检查该上游服务是否已恢复。
网关目前存在一个已知问题:Control API 显示的被动健康检查数据无法准确反映实际健康状态,因此你的测试结果可能与示例不同。该问题正在处理中。不过,被动健康检查机制本身可以正常工作,并会按预期继续路由请求。
示例:上游服务状态变化
创建指向两个服务的路由,并同时配置主动和被动健康检查:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: aic
name: nginx1
spec:
targetRefs:
- name: nginx1
kind: Service
group: ""
healthCheck:
active:
type: http
httpPath: /
healthy:
interval: 99999s
successes: 1
unhealthy:
interval: 30s
passive:
healthy:
httpCodes: [200, 201, 202, 300, 301, 302]
successes: 1
unhealthy:
httpCodes: [429, 404, 500, 501, 502, 503, 504, 505]
httpFailures: 3
---
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: aic
name: nginx2
spec:
targetRefs:
- name: nginx2
kind: Service
group: ""
healthCheck:
active:
type: http
httpPath: /
healthy:
interval: 99999s
successes: 1
unhealthy:
interval: 30s
passive:
healthy:
httpCodes: [200, 201, 202, 300, 301, 302]
successes: 1
unhealthy:
httpCodes: [429, 404, 500, 501, 502, 503, 504, 505]
httpFailures: 3
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: example-hc-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /404
backendRefs:
- name: nginx1
port: 8080
weight: 1
- name: nginx2
port: 8081
weight: 1
将配置应用到集群:
kubectl apply -f passive-health-checks.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: nginx
spec:
ingressClassName: apisix
externalNodes:
- type: Service
name: nginx1
port: 8080
- type: Service
name: nginx2
port: 8081
healthCheck:
active:
type: http
httpPath: /
healthy:
interval: 99999s
successes: 1
unhealthy:
interval: 30s
passive:
healthy:
httpCodes: [200,201,202,300,301,302]
successes: 1
unhealthy:
httpCodes: [429,404,500,501,502,503,504,505]
httpFailures: 3
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: example-hc-route
spec:
ingressClassName: apisix
http:
- name: nginx-hc
match:
paths:
- /404
upstreams:
- name: nginx
❶ active.healthy.interval:定期检查健康节点的时间间隔,单位为秒。
❷ active.unhealthy.interval:定期检查不健康节点的时间间隔,单位为秒。
❸ passive.healthy.httpCodes:被认为健康的响应 HTTP 状态码。