istio流量管理问题
istio流量管理问题
1.1 请求被 Envoy 拒绝
问题描述
请求被 Envoy 代理拒绝通常表现为 503 错误。Istio 的访问日志中可能出现 NR、UO、UF 等响应标志。
解决方法:
- 1. 检查 Envoy 访问日志: 默认输出到容器标准输出,运行以下命令查看日志:
- • kubectl logs PODNAME -c istio-proxy -n NAMESPACE
- 2. 分析响应标志:
- • NR: 无路由配置,因 DestinationRule 或 VirtualService 配置错误。
- • UO: 上游溢出熔断,检查 DestinationRule 的熔断器配置。
- • UF: 无法连接上游,可能与双向 TLS 配置冲突有关。
1.2 路由规则未生效
问题描述
已配置路由规则,但流量未按预期路由。
可能原因:
- 1. 加权版本分发生效慢,需至少 100 个请求才能生效。
- 2. Kubernetes Service 配置不正确,导致 Istio 七层路由特性无法工作。
- 3. 配置传播延迟,几秒内看不到配置变更效果。
解决方法:
- 1. 确保 Kubernetes Service 符合 Istio 路由要求。
- 2. 留出足够时间让配置生效,大型集群尤甚。
- 3. 使用 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
- 2. 与全局配置保持一致,使 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
- • uri:
- 2. 合并配置,将两个 VirtualService 配置合并成一个,明确指定路由规则。
1.5 Envoy 在负载压力下崩溃
问题描述
高负载时,Envoy 代理崩溃并抛出断言失败错误。
可能原因
默认文件描述符限制(如 1024)不足以处理高负载并发连接。
解决方法:
- 1. 增大 ulimit 设置:ulimit -n 16384
- 2. 配置 Envoy 资源限制,确保能处理预期负载。
1.6 Envoy 不能连接到 HTTP/1.0 服务
问题描述
Envoy 无法连接到使用 HTTP/1.0 协议的上游服务。
可能原因
Envoy 要求上游服务使用 HTTP/1.1 或 HTTP/2 协议。
解决方法:
- 1. 更新上游服务,使其支持 HTTP/1.1 或 HTTP/2。
- 2. 配置代理服务器,若 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}"
- 2. 使用域名代替 Pod IP:
- • kubectl exec -it $SOURCE_POD -c curl -- curl web-0.nginx.default -s -o /dev/null -w "%{http_code}"
- 3. 修改端口名称,设为 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
- 2. 确保应用程序使用与服务声明协议一致的方式发送请求。
1.8.2 网关到 VirtualService 的 TLS 不匹配
问题描述
网关配置与 VirtualService 的 TLS 配置不匹配,致请求路由失败。如网关终止 TLS,而 VirtualService 配置了 TLS 路由;或网关启用 TLS 透传,而 VirtualService 配置了 HTTP 路由。
解决方法:
- 1. 统一 TLS 配置:
- • 若网关终止 TLS,VirtualService 应配置 HTTP 路由:
- • apiVersion: networking.istio.io/v1
- • 若网关终止 TLS,VirtualService 应配置 HTTP 路由:
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
- • headers:
kind: VirtualService
metadata:
name: virtual-service
spec:
gateways:
- • gateway
hosts: - • httpbin.example.com
tls: - • match:
- • sniHosts:
- • "httpbin.example.com"
route:
- • "httpbin.example.com"
- • destination:
host: httpbin.org
- • sniHosts:
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
- 2. 将 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
- • "*.test.com"
- 2. 绑定所有 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"
- 2. 配置云负载均衡器为 TLS 连接方式。
- 3. 禁用 Gateway 中的 SNI 匹配:
- • servers:
- • port:
number: 443
name: https
protocol: HTTPS
hosts:- • "*"
- 4. 配置 Istio 网关在终止 TLS 时考虑 SNI。
1.9 Envoy 过滤器配置问题
问题描述
未改动 Envoy 过滤器配置却突然停止工作。
可能原因
EnvoyFilter 配置指定相对于另一过滤器的插入位置,此方式很脆弱,因默认评估顺序基于过滤器创建时间。
解决方法:
- 1. 修改操作为不依赖其他过滤器存在的操作,如 INSERT_FIRST。
- 2. 设显式优先级覆盖默认排序:priority: 10
- 3. 升级 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
- 2. 分离配置,将故障注入和重试策略置于不同资源中。
安全问题
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: "https://example.com/oauth2/v4/discovery"
jwksUri: "https://example.com/oauth2/v4/certs"
- 2. 检查请求是否含有效 JWT 令牌。
- 3. 验证 Istiod 是否接受并分发认证策略。
2.2 授权策略过于限制或宽松
问题描述
配置的授权策略致意外的访问拒绝或允许。
可能原因
授权策略定义不明确或过于宽泛。
解决方法:
- 1. 明确指定授权条件,避免宽泛匹配规则。
- 2. 用 "AND" 和 "OR" 操作符组合条件,构建精确授权规则。
- 3. 测试策略,确保其按预期工作。
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
- 2. 验证策略格式,确保符合 Istio 安全策略规范。
- 3. 用 istioctl analyze 检查配置:
- • istioctl analyze -k
2.4 确保 Istiod 分发策略给代理
问题描述
Istiod 未将安全策略分发给代理。
可能原因
Istiod 与代理通信问题,或策略未正确配置。
解决方法:
- 1. 查看 Istiod 状态:
- • kubectl -n istio-system get pods -l app=istiod
- 2. 检查代理配置,确认是否收到策略:
- • istioctl proxy-config authz -n -p
- 3. 检查 Istiod 配置,确保允许策略传播。
可观测性问题
3.1 时间同步问题
问题描述
Kubernetes 集群时间不同步,致认证失败和日志不一致。
解决方法:
- 1. 验证时间同步服务在集群内正常运行。
- 2. 确保所有节点和 Pod 时间同步:
- • kubectl exec -it -- date
3.2 Prometheus 监控问题
问题描述
无法通过 Prometheus 监控 Istio 服务。
可能原因
监控配置错误,或服务未暴露监控端点。
解决方法:
- 1. 确保所有 Istio 组件启用 Prometheus 监控。
- 2. 检查 ServiceMonitor 配置,确保覆盖所有 Istio 服务。
- 3. 验证 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
- 2. 检查错误信息,修正配置文件错误。
- 3. 确保 istioctl CLI 版本与控制面匹配。
- 4. 检查 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 版本兼容。
- 2. 检查跨集群网络连接,确保无防火墙或路由问题。
- 3. 验证全局服务注册,确保服务在所有集群中都能被发现。
6.2 跨集群的安全策略问题
问题描述
跨集群的安全策略未按预期应用。
可能原因
策略未正确分发或配置。
解决方法:
- 1. 确保安全策略标记了所有相关集群。
- 2. 检查 Istiod 配置,确保能跨集群分发策略。
- 3. 验证策略在所有集群中生效。
容器运行时与基础设施问题
7.1 no port available 错误
- • 错误: 表示系统无可用计算节点,需等待自动调度。
- • 解决方案: 用户可通过任务列表 → 节点列表 → 查看详情检查具体节点运行状态。
7.2 显示 whoami 页面
- • 说明: 平台已连接节点但容器未启动(可能崩溃),短暂显示后转为 no port available。需检查容器配置或镜像完整性。
7.3 proxy request failed(data) 错误
- • 错误: 此错误很少发生。通常表示 Docker 容器未能成功启动。可能的原因包括:
- • 镜像内部程序启动失败
- • 容器配置参数不正确
- • 解决方案:
- 1. 检查镜像是否能在本地正常运行。
- 2. 查看任务日志获取详细错误信息。
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
- • 说明: 当前域名解析可能尚未生效。请等待数秒后,刷新页面并再次尝试。
- • 解决方案(若为预制镜像): 可参考帮助文档:https://www.gongjiyun.com/docs/y/NnNkwiWLkiD3m1kSgXDcRvsKnrJ/L3a6wgRPpity1qkoRxDcx6AQnvf.html
- • 检查: 是否端口上有冲突或其他问题。
7.5 点击快捷访问端口后出现 no healthy upstream
- • 错误: 表明 API 网关或负载均衡器无法找到可用的健康后端服务实例来处理请求。
- • 解决方案:
- 1. 检查后端服务状态:
- • 确认服务是否运行。
- • 查看服务日志:通过日志定位崩溃原因。
- 2. 验证健康检查配置:
- • 检查健康检查接口。
- • 调整健康检查参数:在网关配置中增加健康检查的超时时间或重试次数(避免因短暂延迟误判)。
- 1. 检查后端服务状态: