一、前语

什么是 Istio ?

Istio 是一个完全开源的服务网格,经过在 POD 中注入 sidecar 代理为服务添加 Istio 的支撑,而代理会拦截微服务之间的所有网络通信,然后运用其操控平面的战略进行流量管理。

效能平台-研发篇(四)—— Istio故障排查技巧

动态环境用到的 KtEnv 便是基于 Istio 实现的,本文将列出动态环境的一系列排错方法。

排错说明

以下示例中,假定虚拟环境实例所在的Namespace现已存在环境变量$NS

在排查各类问题前,请依照效能平台-研发篇(二)—— 基于KtEnv的路由染色方案 证KtEnv的CRD和Webhook组件已正确安装到集群中。

二、路由规矩不符合预期问题排查

基础组件查看

1、查看方针Namespace中是否正确创建了VirtualEnvironment实例:

kubectl -n $NS get VirtualEnvironment

2、查看是否生成了预期的Istio资源。

对于每一个选中包含路由标签Pod的Service实例,应该生成一个同名的VirtualService实例和一个同名的DestinationRule实例。

# 假定路由标签名是virtual-env(这个称号是在创建VirtualEnvironment实例时候候装备的)
kubectl -n $NS get Pod -l virtual-env

3、列举参加路由隔离的Service与virtualservice资源进行比较:

# 这两种资源的数目应该相同,且与参加路由隔离的Service逐个同名对应
kubectl -n $NS get VirtualService
kubectl -n $NS get DestinationRule

若数目不正确,请查看方针Service目标的端口命名:

端口称号有必要依据Istio文档要求选用<协议>[-<后缀>]结构。由于当时Istio仅支撑对HTTP协议的消息进行精细路由操控,因此KtEnv仅会处理称号以http开头的端口。

kubectl -n $NS get Service <要路由的方针服务名> -o jsonpath='{.spec.ports}'

流量恳求头格局查看

敞开 Envoy 日志

主张运用 Telemetry 资源敞开日志,装备如下。 更多方法请参阅获取Envoy拜访日志。

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-default
  namespace: istio-system
spec:
  accessLogging:
    - providers:
      - name: envoy

我们手意向指定环境发送恳求

效能平台-研发篇(四)—— Istio故障排查技巧

下图为正常衔接恳求,能够看到能够主动拼接到正确的域名

效能平台-研发篇(四)—— Istio故障排查技巧

下面我看下方赤色为反常的恳求,黄色为正常恳求,能够看到反常恳求的域名值为”-” 并没有匹配到指定的环境,该流量会依据service机制进行随机负载。

效能平台-研发篇(四)—— Istio故障排查技巧

导致这个问题的原因:恳求中短少带有服务称号的恳求头Host:Host:格局不对,这会导致流量绕过 Istio 的路由规矩。

参阅:alibaba.github.io/virtual-env…

以下是其他几种比较常见的过错原因:

  • 同一个Pod被多个Service选中。当时Istio不支撑一个Pod一起属于多个Service的状况
  • Istio规矩收效有推迟(参阅 Istio文档 )

三、Istio virtualservice 装备问题排查

1、corsPolicy.allowOrigin 跨域规矩不收效

问题描绘:

参照官方扩展路由规矩你可能会遇到corsPolicy.allowOrigins跨域特点不收效。

解决方法:

这是由于 KtEnv 选用了 v1alpha3 而不是 v1beta1 ,应该运用corsPolicy.allowOrigin,完好的跨域装备经参阅下方代码。

{
        "Match": [{
                "Uri": {
                        "Prefix": "/"
                }
        }],
        "corsPolicy": {
                "allowOrigin": ["*"],
                "allowCredentials": true,
                "allowHeaders": ["demo-key", "ali-env-mark"],
                "allowMethods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
        }
}

2、更新 annotations 路由规矩后 virtualservice 装备未更新

问题描绘:

KtEnv 不会监听 annotations 状态变化去主动更新 virtualservice 需求手动更新。

解决方法:

参阅下方指令

kubectl delete  virtualservice.networking.istio.io some-services -n $NS

3、多个网关共用同一个 TLS 证书时引起浏览器404问题

参阅来历: github.com/istio/istio…

问题描绘:

多个网关共用一个 TLS 证书时,假如运用支撑 HTTP/2 衔接复用的浏览器(大都浏览器都支撑这一才能)来进行拜访,在和第一个主机名建立衔接之后,假如持续拜访另一个主机名,就会呈现 404 过错。

举个比如,假定有两个主机用这种方法来共享相同的 TLS 证书:

  • 安装在 istio-ingressgateway 上的通配符证书:*.test.com
  • 一个命名为 gw1Gateway 目标,其主机名是 service1.test.comselector 定义为 istio: ingressgateway,运用网关加载的证书来进行 TLS 认证
  • 一个命名为 gw2Gateway 目标,其主机名是 service2.test.comselector 定义为 istio: ingressgateway,运用网关加载的证书来进行 TLS 认证
  • 名为 vs1VirtaulService 目标,主机名为 service1.test.com,网关设置为 gw1
  • 名为 vs2VirtaulService 目标,主机名为 service2.test.com,网关设置为 gw2

两个网关目标运用的是一组作业负载(istio: ingressgateway),用相同的 IP 为两个服务提供网关支撑。假如首先拜访了 service1.test.com,会返回通配符证书 *.test.com,这一证书是能够用于衔接 service2.test.com 的。Chrome 或许 Firefox 这样的浏览器会复用这现已存在的衔接,来发起对 service2.test.com 的拜访,但是 gw1 没有到 service2.test.com 的路由,所以就会返回 404 过错。

解决方法:

要解决这一问题,能够装备一个通用的 Gateway 目标,而不是别离装备两个 gw1gw2。例如下面的装备:

  • 创建一个名为 gwGateway,对应主机为 *.test.com,selector 仍然是 istio: ingressgateway,TLS 仍是运用网关加载的证书。
  • VirtualService 目标 vs1 装备主机名为 service1.test.com,网关设置为 gw
  • VirtualService 目标 vs2 装备主机名为 service2.test.com,网关设置为 gw

四、参阅文档

KtEnv 适配 spring-cloud
KtEnv 扩展路由规矩
Istio 获取Envoy拜访日志
Istio 路由规矩下发推迟
Istio 协议挑选
spring-cloud-kubernetes-with-istio
404 NR when using browser on multiple ingress gateways