一、前语
什么是 Istio ?
Istio 是一个完全开源的服务网格,经过在 POD 中注入 sidecar 代理为服务添加 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
我们手意向指定环境发送恳求
下图为正常衔接恳求,能够看到能够主动拼接到正确的域名
下面我看下方赤色为反常的恳求,黄色为正常恳求,能够看到反常恳求的域名值为”-” 并没有匹配到指定的环境,该流量会依据service机制进行随机负载。
导致这个问题的原因:恳求中短少带有服务称号的恳求头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
- 一个命名为
gw1
的Gateway
目标,其主机名是service1.test.com
,selector
定义为istio: ingressgateway
,运用网关加载的证书来进行 TLS 认证
- 一个命名为
gw2
的Gateway
目标,其主机名是service2.test.com
,selector
定义为istio: ingressgateway
,运用网关加载的证书来进行 TLS 认证
- 名为
vs1
的VirtaulService
目标,主机名为service1.test.com
,网关设置为gw1
- 名为
vs2
的VirtaulService
目标,主机名为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
目标,而不是别离装备两个 gw1
和 gw2
。例如下面的装备:
- 创建一个名为
gw
的Gateway
,对应主机为*.test.com
,selector 仍然是istio: ingressgateway
,TLS 仍是运用网关加载的证书。
VirtualService
目标vs1
装备主机名为service1.test.com
,网关设置为gw
VirtualService
目标vs2
装备主机名为service2.test.com
,网关设置为gw