- 请求被 Envoy 拒绝
- 路线规则似乎不会影响交通流量
- 设置目标规则后出现 503 错误
- 路由规则对入口网关请求没有影响
- 无头 TCP 服务失去连接
- Envoy 在负载下崩溃
- Envoy 无法连接到我的 HTTP/1.0 服务
本节介绍常见问题以及解决与流量管理相关问题的工具和技术。
请求被 Envoy 拒绝
请求可能会因各种原因被拒绝。了解请求被拒绝原因的最佳方法是检查 Envoy 的访问日志。默认情况下,访问日志输出到容器的标准输出。运行以下命令查看日志:
$ kubectl logs PODNAME -c istio-proxy -n NAMESPACE
在默认访问日志格式中,Envoy 响应标志和 Mixer 策略状态位于响应代码之后,如果您使用自定义日志格式,请确保包含%RESPONSE_FLAGS%和%DYNAMIC_METADATA(istio.mixer:status)%。
有关响应标志的详细信息,请参阅Envoy 响应标志 。
常见的响应标志有:
NR:未配置路由,请检查您的DestinationRule或VirtualService。UO:上游溢出并断路,请检查 中的断路器配置DestinationRule。UF:无法连接到上游,如果您使用 Istio 身份验证,请检查 相互 TLS 配置冲突。
UAEX如果响应标志为且 Mixer 策略状态不是 ,则请求将被 Mixer 拒绝-。
常见的 Mixer 策略状态有:
UNAVAILABLE:Envoy 无法连接到 Mixer,并且策略配置为失败关闭。UNAUTHENTICATED:Mixer 身份验证拒绝请求。PERMISSION_DENIED:请求被 Mixer 授权拒绝。RESOURCE_EXHAUSTED:请求被 Mixer 配额拒绝。INTERNAL:由于 Mixer 内部错误,请求被拒绝。
路线规则似乎不会影响交通流量
在当前的 Envoy sidecar 实现中,可能需要最多 100 个请求才能观察到加权版本分布。
如果路由规则对于Bookinfo示例运行良好,但类似版本的路由规则对您自己的应用程序没有影响,则可能是您的 Kubernetes 服务需要稍作更改。Kubernetes 服务必须遵守某些限制才能利用 Istio 的 L7 路由功能。有关详细信息,请参阅Pod 和服务的要求 。
另一个潜在的问题是,路线规则的生效速度可能很慢。Kubernetes 上的 Istio 实现利用最终一致的算法来确保所有 Envoy sidecar 都具有正确的配置,包括所有路由规则。配置更改需要一些时间才能传播到所有 sidecar。对于大型部署,传播将需要更长的时间,并且可能会有秒级的延迟时间。
设置目标规则后出现 503 错误
如果在您应用 a 之后,对服务的请求立即开始生成 HTTP 503 错误,DestinationRule 并且错误一直持续到您删除或恢复 a 为止DestinationRule,则DestinationRule可能会导致该服务发生 TLS 冲突。
例如,如果您在集群中全局配置相互 TLS,则DestinationRule必须包括以下内容trafficPolicy:
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
否则,该模式默认DISABLE导致客户端代理 sidecar 发出纯 HTTP 请求,而不是 TLS 加密请求。因此,请求与服务器代理冲突,因为服务器代理期望加密的请求。
要确认是否存在冲突,请检查命令STATUS输出中的字段是否istioctl authn tls-check设置CONFLICT为适合您的服务。例如:
$ istioctl authn tls-check httpbin.default.svc.cluster.local
HOST:PORT STATUS SERVER CLIENT AUTHN POLICY DESTINATION RULE
httpbin.default.svc.cluster.local:8000 CONFLICT mTLS HTTP default/ httpbin/default
每当您应用 时DestinationRule,请确保trafficPolicyTLS 模式与全局服务器配置匹配。
路由规则对入口网关请求没有影响
假设您正在使用入口Gateway并对应VirtualService访问内部服务。例如,你的VirtualService看起来像这样:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- "myapp.com" # or maybe "*" if you are testing without DNS using the ingress-gateway IP (e.g., http://1.2.3.4/hello)
gateways:
- myapp-gateway
http:
- match:
- uri:
prefix: /hello
route:
- destination:
host: helloworld.default.svc.cluster.local
- match:
...
您还可以将VirtualServicehelloworld 服务的流量路由到特定子集:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- helloworld.default.svc.cluster.local
http:
- route:
- destination:
host: helloworld.default.svc.cluster.local
subset: v1
在这种情况下,您会注意到通过入口网关对 helloworld 服务的请求将不会定向到子集 v1,而是将继续使用默认的循环路由。
入口请求使用网关主机(例如),它将激活 myapp 中路由到 helloworld 服务的任何端点的myapp.com规则。VirtualService只有主机的内部请求helloworld.default.svc.cluster.local 才会使用 helloworld VirtualService,它将流量专门定向到子集 v1。
要控制来自网关的流量,您还需要在 myapp 中包含子集规则VirtualService:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- "myapp.com" # or maybe "*" if you are testing without DNS using the ingress-gateway IP (e.g., http://1.2.3.4/hello)
gateways:
- myapp-gateway
http:
- match:
- uri:
prefix: /hello
route:
- destination:
host: helloworld.default.svc.cluster.local
subset: v1
- match:
...
或者,如果可能的话,您可以将两者合并VirtualServices为一个单元:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.com # cannot use "*" here since this is being combined with the mesh services
- helloworld.default.svc.cluster.local
gateways:
- mesh # applies internally as well as externally
- myapp-gateway
http:
- match:
- uri:
prefix: /hello
gateways:
- myapp-gateway #restricts this rule to apply only to ingress gateway
route:
- destination:
host: helloworld.default.svc.cluster.local
subset: v1
- match:
- gateways:
- mesh # applies to all services inside the mesh
route:
- destination:
host: helloworld.default.svc.cluster.local
subset: v1
无头 TCP 服务失去连接
如果istio-citadel部署,Envoy 每 45 天重新启动一次以刷新证书。这会导致 TCP 流断开或服务之间长时间运行的连接。
您应该在应用程序中针对此类断开连接建立弹性,但如果您仍然想防止发生断开连接,则需要禁用相互 TLS 和部署istio-citadel。
首先,编辑您的istio配置以禁用相互 TLS:
$ kubectl edit configmap -n istio-system istio
$ kubectl delete pods -n istio-system -l istio=pilot
接下来,缩小istio-citadel部署规模以禁用 Envoy 重新启动:
$ kubectl scale --replicas=0 deploy/istio-citadel -n istio-system
这应该会阻止 Istio 重新启动 Envoy 并断开 TCP 连接。
Envoy 在负载下崩溃
检查你的ulimit -a. 许多系统默认有 1024 个打开文件描述符限制,这将导致 Envoy 断言并崩溃:
[2017-05-17 03:00:52.735][14236][critical][assert] assert failure: fd_ != -1: external/envoy/source/common/network/connection_impl.cc:58
确保提高您的 ulimit。例子:ulimit -n 16384
Envoy 无法连接到我的 HTTP/1.0 服务
Envoy 需要上游服务的流量HTTP/1.1。HTTP/2例如,当使用NGINX为 Envoy 后面的流量提供服务时,您需要将NGINX 配置中的proxy_http_version指令设置为“1.1”,因为 NGINX 默认值为 1.0。
配置示例:
upstream http_backend {
server 127.0.0.1:8080;
keepalive 16;
}
server {
...
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
...
}
}