NC(没有上游集群)--Istio访问日志ResponseFlag重现与解析07


KubeCon 2023在上海做的一个关于Istio访问日志的演讲《Detailed Parse and Reproduce Response Flags of Istio Access Log Based on Production Use Case》。解析和重现了在当时解决客户问题时碰到的各种应答日志。

第七个关注的Response Flag是NC,全称是NoClusterFound,官方定义表示Upstream cluster not found"

含义:

NC表示没有上游集群,即在网格流量路由中定义的目标服务后端不存在。Istio中比较典型的场景如分流策略中流量发送给V2标识的服务子集,但是DestinationRule中并没有定义该版本标识的服务子集。

NC服务访问

重现环境:

  • 客户端Pod,注入了Sidecar。
  • 目标服务,一个Cluster类型的Kubernetes服务,多个服务实例。服务端Pod可以注入Siecar,也可以不用注入。

重现步骤:

第一步: 从注入了网格代理的客户端Pod中通过目标名和服务端口访问目标服务,观察代理的访问日志,得到正常的200响应码。从服务端和客户端的访问日志上都可以看到服务在目标服务的多个实例上负载均衡。正常访问参照本系列的环境部分描述

第二步: 在原有正常访问的环境上,给目标服务配置VirtualService 和DestinationRule,在VirtualService中定义服务的流量发给v2的服务子集,而在DestinationRule中只定义v1的服务子集。

 1apiVersion: networking.istio.io/v1beta1
 2kind: VirtualService
 3metadata:
 4  name: nginx-80
 5  namespace: accesslog
 6spec:
 7  hosts:
 8  - nginx
 9  http:
10  - route:
11    - destination:
12        host: nginx.accesslog.svc.cluster.local
13        subset: v2  # subset NOT exists
 1apiVersion: networking.istio.io/v1beta1
 2kind: DestinationRule
 3metadata:
 4  name: nginx
 5  namespace: accesslog
 6spec:
 7  host: nginx
 8  subsets:
 9  - labels:
10      version: v1
11    name: v1  # Only v1 

第三步: .在客户端的容器中curl目标服务,得到503错误。

NC客户端访问结果

第四步: 观察源服务的outbound日志,可以看到提示503NC,表示请求的上游服务不存在。

1[2023-08-19T10:09:13.864Z] "GET / HTTP/1.1" 503 NC cluster_not_found - "-" 0 0 0 - "-" "curl/7.52.1" "1f8f95a5-5139-4790-9d7e-80d28fda24b7" "nginx.accesslog" "-" - - 10.246.91.131:80 10.66.0.24:51674 - -

第五步: 观察服务端日志。因为客户端代理没有找到路由的上游服务,因此请求不会正常发出去,服务端代理上也不会有流量,对本次请求也不会有日志记录。

第六步: 通过config_dump观察配置在数据面的配置,会看到目标服务的RDS定义,路由的后端是如图v2的一个上游服务;而通过CDS中目标服务存有2个上游集群定义,分别是带v1的一个分组,另一个是不带v1分组,没有v2的服务分组。

应对建议

NC在生产中出现的频率还是比较高的,但比起那些运行期的错误,这种配置类的错误还是比较好处理的。一般要保证VirtualService中引用的后端在网格中正确注册,比如重现的这个场景中VirtualService的后端是一个服务子集时,要检查和确保通过DestinationRule正确定义了引用的服务子集。