istio流量管理问题

80 阅读11分钟

流量管理问题

1.1 请求被 Envoy 拒绝

问题描述
请求被 Envoy 代理拒绝通常表现为 503 错误。Istio 的访问日志中可能出现 NR、UO、UF 等响应标志。

解决方法:

    1. 检查 Envoy 访问日志: 默认输出到容器标准输出,运行以下命令查看日志:

    • • kubectl logs PODNAME -c istio-proxy -n NAMESPACE
    1. 分析响应标志:

    • NR: 无路由配置,因 DestinationRule 或 VirtualService 配置错误。
    • UO: 上游溢出熔断,检查 DestinationRule 的熔断器配置。
    • UF: 无法连接上游,可能与双向 TLS 配置冲突有关。

1.2 路由规则未生效

问题描述
已配置路由规则,但流量未按预期路由。

可能原因:

    1. 加权版本分发生效慢,需至少 100 个请求才能生效。
    1. Kubernetes Service 配置不正确,导致 Istio 七层路由特性无法工作。
    1. 配置传播延迟,几秒内看不到配置变更效果。

解决方法:

    1. 确保 Kubernetes Service 符合 Istio 路由要求。
    1. 留出足够时间让配置生效,大型集群尤甚。
    1. 使用 istioctl proxy-status 检查 Sidecar 代理状态和配置。

1.3 DestinationRule 导致 503 错误

问题描述
应用 DestinationRule 后,服务返回 HTTP 503 错误,直至移除或回滚 DestinationRule。

可能原因
与 TLS 配置冲突,集群全局双向 TLS 启用,但 DestinationRule 未相应配置,致客户端 Sidecar 发送明文 HTTP 请求,而服务端代理期望加密请求。

解决方法:

    1. 确保 DestinationRule 包含正确 trafficPolicy:

    • • trafficPolicy:

tls:
mode: ISTIO_MUTUAL

    1. 与全局配置保持一致,使 DestinationRule 的 TLS 模式与集群全局配置一致。

1.4 Ingress Gateway 请求路由问题

问题描述
使用 Ingress Gateway 和 VirtualService 访问内部服务,路由规则未按预期工作。

可能原因
Ingress 请求通过网关主机路由,网关主机激活特定 VirtualService 规则,但这些规则可能未正确配置子集路由。

解决方法:

    1. 在 VirtualService 中包含子集规则:

    • • apiVersion: networking.istio.io/v1

kind: VirtualService
metadata:
name: myapp
spec:
hosts:

  • • "myapp.com"
    gateways:

  • • myapp-gateway
    http:

  • • match:

    • • uri:
      prefix: /hello
      route:
    • • destination:
      host: helloworld.default.svc.cluster.local
      subset: v1
    1. 合并配置,将两个 VirtualService 配置合并成一个,明确指定路由规则。

1.5 Envoy 在负载压力下崩溃

问题描述
高负载时,Envoy 代理崩溃并抛出断言失败错误。

可能原因
默认文件描述符限制(如 1024)不足以处理高负载并发连接。

解决方法:

    1. 增大 ulimit 设置:ulimit -n 16384
    1. 配置 Envoy 资源限制,确保能处理预期负载。

1.6 Envoy 不能连接到 HTTP/1.0 服务

问题描述
Envoy 无法连接到使用 HTTP/1.0 协议的上游服务。

可能原因
Envoy 要求上游服务使用 HTTP/1.1 或 HTTP/2 协议。

解决方法:

    1. 更新上游服务,使其支持 HTTP/1.1 或 HTTP/2。
    1. 配置代理服务器,若 Envoy 后使用如 NGINX 的代理服务器,确保配置中将 proxy_http_version 设置为 "1.1":

    • • location /http/ {

    
    
    
  proxy_pass http://http_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";

}

1.7 访问 Headless Service 时 503 错误

问题描述
访问 Headless Service 时,出现 503 UC 错误。

可能原因
mTLS 模式为 STRICT 的网格中,Sidecar 代理无法找到前往 Headless Service 的路由入口。

解决方法:

    1. 指定正确的 Host 头:

    • • kubectl exec -it $SOURCE_POD -c curl -- curl -H "Host: nginx.default" 10.1.1.171 -s -o /dev/null -w "%{http_code}"
    1. 使用域名代替 Pod IP:

    • • kubectl exec -it $SOURCE_POD -c curl -- curl web-0.nginx.default -s -o /dev/null -w "%{http_code}"
    1. 修改端口名称,设为 tcp、tcp-web 或 tcp-,避免使用 HTTP 连接管理器。

1.8 TLS 配置错误

1.8.1 将 HTTPS 流量发送到 HTTP 端口

问题描述
向声明为 HTTP 的服务发送 HTTPS 请求,致请求解析失败。

解决方法:

    1. 修改 ServiceEntry 配置:

    • • apiVersion: networking.istio.io/v1

kind: ServiceEntry
metadata:
name: httpbin
spec:
hosts:

  • • httpbin.org
    ports:
  • • number: 443
    name: https
    protocol: HTTPS
    1. 确保应用程序使用与服务声明协议一致的方式发送请求。

1.8.2 网关到 VirtualService 的 TLS 不匹配

问题描述
网关配置与 VirtualService 的 TLS 配置不匹配,致请求路由失败。如网关终止 TLS,而 VirtualService 配置了 TLS 路由;或网关启用 TLS 透传,而 VirtualService 配置了 HTTP 路由。

解决方法:

    1. 统一 TLS 配置:

    • • 若网关终止 TLS,VirtualService 应配置 HTTP 路由:

      • • apiVersion: networking.istio.io/v1

kind: VirtualService
metadata:
name: httpbin
spec:
hosts:

  • • "*.example.com"
    gateways:

  • • istio-system/gateway
    http:

  • • match:

    • • headers:
      ":authority":
      regex: "*.example.com"

    route:

    • • destination:
      host: httpbin.org
    • • 若需网关透传 TLS,VirtualService 应配置 TLS 路由:

      • • apiVersion: networking.istio.io/v1

kind: VirtualService
metadata:
name: virtual-service
spec:
gateways:

  • • gateway
    hosts:

  • • httpbin.example.com
    tls:

  • • match:

    • • sniHosts:

      • • "httpbin.example.com"
        route:
    • • destination:
      host: httpbin.org

1.8.3 双 TLS(TLS 源发起 TLS 连接)

问题描述
Istio 配置为执行 TLS 源发起时,应用程序向 Sidecar 发送纯文本请求,但 Sidecar 却发起 TLS 连接。

解决方法:

    1. 确保 ServiceEntry 中的端口协议正确:

    • • apiVersion: networking.istio.io/v1

kind: ServiceEntry
metadata:
name: httpbin
spec:
hosts:

  • • httpbin.org
    ports:
  • • number: 443
    name: http
    protocol: HTTP
    1. 将 HTTP 端口暴露给应用程序,并设置 targetPort 用于发起 TLS:

    • • apiVersion: networking.istio.io/v1

kind: ServiceEntry
metadata:
name: httpbin
spec:
hosts:

  • • httpbin.org
    ports:
  • • number: 80
    name: http
    protocol: HTTP
    targetPort: 443

1.8.4 为多个 Gateway 配置相同 TLS 证书

问题描述
多个网关配置同一 TLS 证书,致浏览器访问第二个主机时利用 HTTP/2 连接复用,出现 404 异常。

解决方法:

    1. 配置单独通用 Gateway,而非多个独立网关:

    • • apiVersion: networking.istio.io/v1

kind: Gateway
metadata:
name: gw
spec:
selector:
istio: ingressgateway
servers:

  • • port:
    number: 443
    name: https
    protocol: HTTPS
    hosts:

    • • "*.test.com"
      tls:
      mode: SIMPLE
      credentialName: sds-credential
    1. 绑定所有 VirtualService 到此通用 Gateway:

    • • apiVersion: networking.istio.io/v1

kind: VirtualService
metadata:
name: vs1
spec:
hosts:

  • • service1.test.com
    gateways:
  • • gw

其他配置

1.8.5 不发送 SNI 时配置 SNI 路由

问题描述
指定 hosts 字段的 HTTPS Gateway 对传入请求执行 SNI 匹配,但某些请求可能未设置 SNI。如直接设主机标头却未设 DNS,或 Istio 前面的负载均衡器不转发 SNI。

解决方法:

    1. 设置 DNS 或用 --resolve 标志:

    • • curl 1.2.3.4 --resolve app.example.com:443:1.2.3.4 -H "Host: app.example.com"
    1. 配置云负载均衡器为 TLS 连接方式。
    1. 禁用 Gateway 中的 SNI 匹配:

    • • servers:
  • • port:
    number: 443
    name: https
    protocol: HTTPS
    hosts:

    • • "*"
    1. 配置 Istio 网关在终止 TLS 时考虑 SNI。

1.9 Envoy 过滤器配置问题

问题描述
未改动 Envoy 过滤器配置却突然停止工作。

可能原因
EnvoyFilter 配置指定相对于另一过滤器的插入位置,此方式很脆弱,因默认评估顺序基于过滤器创建时间。

解决方法:

    1. 修改操作为不依赖其他过滤器存在的操作,如 INSERT_FIRST。
    1. 设显式优先级覆盖默认排序:priority: 10
    1. 升级 Istio 后监控过滤器状态。

1.10 配备故障注入和重试 / 超时策略的虚拟服务未按预期工作

问题描述
配置了故障注入和重试 / 超时策略的虚拟服务未按预期工作。

可能原因
Istio 不支持在同一个 VirtualService 上同时配置故障注入和重试或超时策略。

解决方法:

    1. 从 VirtualService 移除故障配置,用 EnvoyFilter 将故障注入上游 Envoy 代理:

    • • apiVersion: networking.istio.io/v1alpha3

kind: EnvoyFilter
metadata:
name: hello-world-filter
spec:
workloadSelector:
labels:
app: helloworld
configPatches:

  • • applyTo: HTTP_FILTER
    match:
    context: SIDECAR_INBOUND
    patch:
    operation: INSERT_BEFORE
    value:
    name: envoy.fault
    typed_config:
    "@type": "type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault"
    abort:
    http_status: 500
    percentage:
    numerator: 50
    denominator: HUNDRED
    1. 分离配置,将故障注入和重试策略置于不同资源中。

安全问题

2.1 终端用户认证失败

问题描述
使用 Istio 的请求认证策略启用终端用户认证失败。

可能原因
Istio 仅支持通过请求认证策略启用终端用户 JWT 认证,但配置有误。

解决方法:

    1. 确保请求认证策略正确配置:

    • • apiVersion: security.istio.io/v1

kind: RequestAuthentication
metadata:
name: example-com-auth
spec:
selector:
matchLabels:
app: myapp
jwt:
issuer: "example.com/oauth2/v4/d…"
jwksUri: "example.com/oauth2/v4/c…"

    1. 检查请求是否含有效 JWT 令牌。
    1. 验证 Istiod 是否接受并分发认证策略。

2.2 授权策略过于限制或宽松

问题描述
配置的授权策略致意外的访问拒绝或允许。

可能原因
授权策略定义不明确或过于宽泛。

解决方法:

    1. 明确指定授权条件,避免宽泛匹配规则。
    1. 用 "AND" 和 "OR" 操作符组合条件,构建精确授权规则。
    1. 测试策略,确保其按预期工作。

2.3 确保 Istiod 接受策略

问题描述
配置的安全策略未被 Istiod 接受。

可能原因
策略格式或内容有误。

解决方法:

    1. 查看 Istiod 日志,确认是否报告策略验证错误:

    • • kubectl logs -n istio-system $(kubectl get pod -n istio-system -l app=istiod -o jsonpath='{.items[0].metadata.name}') -c istiod
    1. 验证策略格式,确保符合 Istio 安全策略规范。
    1. 用 istioctl analyze 检查配置:

    • • istioctl analyze -k

2.4 确保 Istiod 分发策略给代理

问题描述
Istiod 未将安全策略分发给代理。

可能原因
Istiod 与代理通信问题,或策略未正确配置。

解决方法:

    1. 查看 Istiod 状态:

    • • kubectl -n istio-system get pods -l app=istiod
    1. 检查代理配置,确认是否收到策略:

    • • istioctl proxy-config authz -n -p
    1. 检查 Istiod 配置,确保允许策略传播。

可观测性问题

3.1 时间同步问题

问题描述
Kubernetes 集群时间不同步,致认证失败和日志不一致。

解决方法:

    1. 验证时间同步服务在集群内正常运行。
    1. 确保所有节点和 Pod 时间同步:

    • • kubectl exec -it -- date

3.2 Prometheus 监控问题

问题描述
无法通过 Prometheus 监控 Istio 服务。

可能原因
监控配置错误,或服务未暴露监控端点。

解决方法:

    1. 确保所有 Istio 组件启用 Prometheus 监控。
    1. 检查 ServiceMonitor 配置,确保覆盖所有 Istio 服务。
    1. 验证 Prometheus 是否抓取 Istio 指标:

    • • kubectl get --raw /apis/prometheus.monitoring.coreos.com/v1/namespaces/istio-monitoring/prometheuses/istio-prometheus/query?query=istio_mesh_health

配置验证的问题

4.1 配置验证失败

问题描述
Istio 配置验证失败,无法应用配置。

可能原因
配置文件格式错误,或违反 Istio 配置规则。

解决方法:

    1. 用 istioctl analyze 验证配置:

    • • istioctl analyze
    1. 检查错误信息,修正配置文件错误。
    1. 确保 istioctl CLI 版本与控制面匹配。
    1. 检查 YAML 文件的空格缩进和数组符号。

诊断工具

5.1 使用 istioctl 命令行工具

istioctl analyze

  • 用途: 分析 Istio 配置的潜在问题。
  • 命令: istioctl analyze --all-namespaces
  • 输出: 报告配置问题,含错误和警告。

istioctl describe

  • 用途: 检查网格中的 Pod 和服务配置。
  • 命令: istioctl describe pod -n
  • 输出: 显示 Pod 的 Istio 配置,包括服务端口、策略和路由。

istioctl check-inject

  • 用途: 验证 Sidecar 注入配置。
  • 命令: istioctl check-inject -n -p
  • 输出: 报告注入状态和问题。

5.2 调试 Envoy 和 Istiod

查看 Envoy 访问日志

  • 命令: kubectl logs -n -c istio-proxy
  • 注意: 确保日志格式含响应标志(%RESPONSE_FLAGS%)。

检查 Istiod 状态

  • 命令:

    • • kubectl -n istio-system get pods -l app=istiod
    • • kubectl logs -n istio-system -c istiod
  • 注意: 检查是否有策略验证或分发错误。

多集群下的故障排除

6.1 跨集群流量问题

问题描述
多集群环境中,跨集群流量路由不正常。

可能原因
配置错误或网络连接问题。

解决方法:

    1. 确保所有集群的 Istio 版本兼容。
    1. 检查跨集群网络连接,确保无防火墙或路由问题。
    1. 验证全局服务注册,确保服务在所有集群中都能被发现。

6.2 跨集群的安全策略问题

问题描述
跨集群的安全策略未按预期应用。

可能原因
策略未正确分发或配置。

解决方法:

    1. 确保安全策略标记了所有相关集群。
    1. 检查 Istiod 配置,确保能跨集群分发策略。
    1. 验证策略在所有集群中生效。

容器运行时与基础设施问题

7.1 no port available 错误

  • 错误: 表示系统无可用计算节点,需等待自动调度。
  • 解决方案: 用户可通过任务列表 → 节点列表 → 查看详情检查具体节点运行状态。

7.2 显示 whoami 页面

  • 说明: 平台已连接节点但容器未启动(可能崩溃),短暂显示后转为 no port available。需检查容器配置或镜像完整性。

7.3 proxy request failed(data) 错误

  • 错误: 此错误很少发生。通常表示 Docker 容器未能成功启动。可能的原因包括:

    • • 镜像内部程序启动失败
    • • 容器配置参数不正确
  • 解决方案:

      1. 检查镜像是否能在本地正常运行。
      1. 查看任务日志获取详细错误信息。

7.4 快捷访问点开后域名链接报错

  • 错误: upstream connect error or disconnect/reset before headers. retried and the latest reset reason: remote connection failure, transport failure reason: delayed connect error: Connection refused
  • 说明: 当前域名解析可能尚未生效。请等待数秒后,刷新页面并再次尝试。
  • 解决方案(若为预制镜像): 可参考帮助文档:www.gongjiyun.com/docs/y/NnNk…
  • 检查: 是否端口上有冲突或其他问题。

7.5 点击快捷访问端口后出现 no healthy upstream

  • 错误: 表明 API 网关或负载均衡器无法找到可用的健康后端服务实例来处理请求。

  • 解决方案:

      1. 检查后端服务状态:

      • • 确认服务是否运行。
      • • 查看服务日志:通过日志定位崩溃原因。
      1. 验证健康检查配置:

      • • 检查健康检查接口。
      • • 调整健康检查参数:在网关配置中增加健康检查的超时时间或重试次数(避免因短暂延迟误判)。