istio问题定位分析
服务调用异常
一、定位到异常服务
多服务调用链的问题定位。单服务的调用出现问题可直接查看网关或服务的日志确定具体问题。
- 获取链路ID或traceId
- 通过ID查询到发生异常调用的服务
二、分析响应状态或日志
1、查看服务状态(运行状态、可读探针、存活探针)
2. 查看该请求的response_code(状态码)和response_flags(响应标识)
1. response_flags为"-":常表现为TCP请求或程序异常
2. response_flags为特定标识:可对照响应标识表获取具体原因
2. 服务本身异常:如果为服务异常,查看服务详细日志
3. 其他因素:
响应标识表
- 常用
响应标识 | 协议 | 解释 | 备注 |
DC | HTTP | 下游主动中断连接 | |
UC | HTTP | 上游连接终止 | |
DI | HTTP | 通过故障注入延迟处理请求 | |
FI | HTTP | 通过故障注入指定了响应代码 | |
NR | HTTP和TCP | 没有配置路由或过滤器链 | 如VirtualService和DestinationRule中的subset.name不匹配 |
UH | HTTP和TCP | 上游没有健康主机 | 在服务配置了可读探针的情况下,常发生在熔断驱逐时 |
UO | HTTP和TCP | 上游溢出(电路断开) | 配置的最大连接数等限制导致部分请求失败 |
URX | HTTP和TCP | 达到上游最大重试限制 |
- 不常用
响应标识 | 解释 |
UF | 上游连接失败,常发生在TLS认证 |
LH | 503响应代码,本地服务运行状况检查请求失败。 |
UT | 上游请求超时以及504响应代码。 |
LR | 连接本地重置,除了503响应代码。 |
UR | 503响应代码,还可以进行上游远程复位。 |
RL | 429个响应代码,该请求还受HTTP速率限制过滤器本地限制。 |
UAEX | 外部授权服务拒绝了该请求。 |
RLSE | 请求被拒绝,因为速率限制服务中存在错误。 |
IH | 请求被拒绝,因为除了400个响应代码外,它还为严格检查的标头设置了无效的值 。 |
SI | 408响应码,流空闲超时。 |
DPE | 下游请求具有HTTP协议错误。 |
UMSDR | 上游请求达到最大流持续时间。 |
路由规则异常
比如路由规则不生效等问题。未特别说明是网格外服务的,均表示网格内服务
- 定位到具体哪2个服务之间的路由规则异常
- 网关与服务
- 服务与服务
- 网格外服务与服务
2、在1、2、情况下,查看创建的vs规则是否正常应用到服务上
模拟问题
1.6.2版本
1. deploy副本数为1,启动数为0
连接istio控制平面失败,需查看istiod服务的健康状态
Warning FailedCreate 15s (x14 over 64s) replicaset-controller Error creating: Internal error occurred: failed calling webhook "sidecar-injector.istio.io": Post https://istiod.istio-system.svc:443/inject?timeout=30s: dial tcp 10.96.129.113:443: connect: connection refused
[root@pass1 city]# kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
grafana-74dc798895-zjqrc 1/1 Running 3 5d
istio-egressgateway-667578dd9b-5bmgw 1/1 Running 3 5d
istio-ingressgateway-579b8f7dd4-mh96s 1/1 Running 0 36m
istio-tracing-8584b4d7f9-m7qdp 1/1 Running 3 5d
istiod-d9875bd5d-j6tnf 0/1 CrashLoopBackOff 4 2m
kiali-6f457f5964-hp2jv 1/1 Running 3 5d
prometheus-7c9ddc484d-rzv8t 2/2 Running 6 5d
2. 配置的vs未生效
- 判断是集群内部调用还是通过网关调用
- 网关调用:查看绑定了网关的virtualservices配置是否正常
- 集群内部调用:
- 服务网格外服务————>服务网格内服务:路由规则不会生效
- 服务网格内服务————>服务网格内服务:正常情况下路由规则将会生效
- 查看服务的路由规则是否配置成功
istioctl x describe svc -n namespace service_name
- 查看容器的服务路由规则是否配置成功
istioctl x describe pod -n namespace pod_name
3. 链路跟踪数据没有形成串联
istio的其他功能对于代码无侵入性,但是链路需要对代码进行一定程度的侵入,需要将一些请求标头在发送请求时进行传递
- 基于OpenTracing
x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context
- 基于OpenCensus
x-cloud-trace-context
traceparent
grpc-trace-bin
4. match的匹配规则未生效
创建的VirtualService路由规则将会按照配置顺序加载到evnoy上,当请求路由到evnoy后,系那个会按照加载的顺序进行匹配,所以match的匹配规则需要优先进行匹配,同时一个VirtualService的匹配规则中,前面的匹配规则不能是后面规则的子集。相当于if判断句,逐步判断条件是否满足
例如,将请求头end-user=demo的流量路由到v1,将请求头end-user=demo和message=agree的流量路由到v2。
spec:
hosts:
- nginx-svc
http:
- match:
- headers:
end-user:
exact: demo
message:
exact: agree
route:
- destination:
host: nginx-svc
subset: v2
- match:
- headers:
end-user:
exact: demo
route:
- destination:
host: nginx-svc
subset: v1
{
"name": "nginx-svc.default.svc.cluster.local:80",
"domains": [
"nginx-svc.default.svc.cluster.local",
"nginx-svc.default.svc.cluster.local:80",
"nginx-svc",
"nginx-svc:80",
"nginx-svc.default.svc.cluster",
"nginx-svc.default.svc.cluster:80",
"nginx-svc.default.svc",
"nginx-svc.default.svc:80",
"nginx-svc.default",
"nginx-svc.default:80",
"10.96.130.229",
"10.96.130.229:80"
],
"routes": [
{
"match": {
"prefix": "/",
"caseSensitive": true,
"headers": [
{
"name": "end-user",
"prefixMatch": "jason"
},
{
"name": "message",
"exactMatch": "agree"
}
]
},
"route": {
"cluster": "outbound|80|v2|nginx-svc.default.svc.cluster.local",
"timeout": "0s",
"retryPolicy": {
... ...
},
"maxGrpcTimeout": "0s"
}
},
{
"match": {
"prefix": "/",
"caseSensitive": true,
"headers": [
{
"name": "end-user",
"exactMatch": "jason"
}
]
},
"route": {
"cluster": "outbound|80|v1|nginx-svc.default.svc.cluster.local",
"timeout": "0s",
"retryPolicy": {
... ...
}
"maxGrpcTimeout": "0s"
}
}
],
"includeRequestAttemptCount": true
}
5. sidecar与业务容器启动顺序
sidecar先于业务容器启动的情况下,在业务容器启动之前拦截的流量将会请求失败。后于业务容器启动的情况下,sidecar将不会拦截流量。可通过istio或k8s两方面进行控制
- istio方面
istio-1.8版本新增holdApplicationUntilProxyStarts配置,将阻止其他容器的启动,知道sidecar启动为止。
values.global.proxy.holdApplicationUntilProxyStarts: true
- k8s方面
k8s 1.18版本可以通过将container指定为sidecar类型,sidecar类型的container将会优先启动
- name: istio-proxy
image: docker.io/istio/proxyv2:1.6.2
lifecycle:
type: Sidecar
6. 业务容器进程启动慢
部分业务容器进程启动慢,在启动成功之前对于该服务的访问均处于请求失败状态
7. envoy在高负载下崩溃(官网问题统计)
检查ulimit -a,查看文件描述符限制。使用ulimit -n NUM修改
[critical][assert] assert failure: fd_ != -1: external/envoy/source/common/network/connection_impl.cc:58
8. 不自动注入sidecar的容器
- namespace未开启自动注入
- kube-system、kube-public忽略自动注入
- hostNetwork:true。忽略自动注入
9. vs绑定的资源不存在:gw、dr
该错误状态的检查是通过galley组件进行的,1.5版本之后该组件并入了istiod,默认istiod未开启检查功能,需要手动开启。设置istiod的环境变量PILOT_ENABLE_ANALYSIS为true,或者在安装时指定enableAnalysis=true
status:
validationMessages:
- code: IST0101
documentation_url: https://istio.io/docs/reference/config/analysis/IST0101?ref=status-controller
level: Error
message: 'Referenced host+subset in destinationrule not found: "city+v1"'
10. 网关偶发探针失败(待解决)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Unhealthy 14m (x868 over 8d) kubelet, slave3 Readiness probe failed: Get http://10.244.3.7:15021/healthz/ready: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
warn Envoy proxy is NOT ready: failed to get readiness stats: Get "http://127.0.0.1:15000/stats?usedonly&filter=^(server.state|listener_manager.workers_started)": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
info Envoy proxy is ready
1.8.0版本
11.创建80网关绑定失败
在1.7版本之后(包含1.7版本),istio-ingressgateway的启动方式默认变为了非root用户,无法绑定1024以下的端口,需要对网关进行调整。
方式一:使用targetPort将1024以下的端口绑定到有效端口
方式二:istio-ingressgateway改为root用户
gRPC config for type.googleapis.com/envoy.config.listener.v3.Listener rejected: Error adding/updating listener(s) 0.0.0.0_80: cannot bind '0.0.0.0:80': Permission denied
12.执行istioctl命令报错
一般是istioctl客户端与控制平面和数据平面版本不一致导致
Error: mismatched message type: got "envoy.config.route.v3.RouteConfiguration" want "envoy.api.v2.RouteConfiguration"
[root@pass1 ~]# istioctl version
client version: 1.6.2
control plane version: 1.8.0
data plane version: 1.8.0 (3 proxies)