istio多集群
跨地域流量管理需要解决的问题
- dns cache问题,导致流量扔向坏的数据中心推送
- 新增集群,如果使用dns直接解析到,可能上下游服务未就绪,导致不可用,使用istio可以一点点导流
- 99%流量本地消化,1%的本地服务出错流量分发到其他中心
多集群部署方案
- k8s集群联邦
- 集群联邦apiServer作为用户访问的入口
- 所有k8s集群注册至集群联邦
- 可用区
- 数据中心具备独立的供电制冷设备的故障与
- 同一可用区网络延迟小
- 统一可用区可能部署了多个k8s集群
- 多集群部署
- 同一可用区设定一个网关集群
- 网关集群中部署istio primary(完整的istiod工鞥)
- 统一可用区其他集群部署istio remote(无自动发现功能的istiod)
- 所有集群采用相同的rootca
- 相同环境trustDomain相同
- 东西南北流量统一管控
- 同一可用区服务调用基于sidecar
- 跨可用区的服务调用基于istio gateway
入站流量经过l4+l7负载均衡
- 返回客户端的流量,不经过l4
-
4层负载均衡通过ipip协议实现
- istio支持选择某些ns来进行服务发现,可以在一个k8s集群中部署多个功能隔离的istio,来实现不同的功能
高可用接入方案
接入流程
为引用发布服务
- 定义loadBalancer Type Service,提供集群外部可访问的lb ip
- 其他集群通过定义workloadEntry指向lb ip,实现故障转移
- 即为实现图中istio ingress gateway执行ipvs的线
创建workloadEntry
- 创建workloadEntry指向其他数据中心LB IP
apiVersion: networking.istio.io/v1beta1
kind: WorkloadEntry
metadata:
name: foo
spec:
address: foo.bar.svc.cluster2
labels:
run: foo
locality: region1/zone1 # 永安里定义cluster2 所在的region和az
定义serviceEntry
- 同时选择workloadEntry和本地pod
- serviceEntry对象可以将本地pod和具有相同label的workloadEntry定义成相同的envoy cluster
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: foo
spec:
hosts:
- foo.com
ports:
- name: http-defaule
number: 80
protocol: HTTP
targetPort: 80
resolution: STATIC
workloadSelector: # 会同时选择有这个标签的workloadEntry和pod
labels:
run: foo
创建VirtualService和gateway
- 实现流量内部和外部转发到serviceEntry
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: foo
spec:
gateways:
- foo
hosts:
- foo.com
http:
- match:
- port: 80
route:
- destination:
host: foo.com
port:
number: 80
---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: foo
spec:
selector:
istio: ingressgateway
services:
- hosts:
- foo.com
port:
name: http-default
number: 80
protocol: HTTP
为workload增加locality(地域)信息
- istio从下列配置中读取,基于这些配置,为istio的workload增加地域信息
- k8s Node中的地域信息,pod会继承node的信息
- region:topology.kubernetes.io/region
- zone: topology.kubernetes.io/zone
- subzone: topology.istio.io/subzone
- k8s pod的istio locality标签
- istio-locality: "region/zone/subzone"
- workloadEntry的locality属性
- locality: region/zone/subzone
基于Locality的流量转发
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: foo
spec:
host: foo.com
trafficPolicy:
loadBalancer:
localityLbSetting:
distribute:
- from: "*/*"
to:
region1/zone1/*: 99 # 99的流量在cluster1
region2/zone2/*: 1 # 1的流量去cluster2
enabled: true
outlierDetection:
baseEjectionTime: 10s
consecutive5xxErrors: 100
interval: 10s
tls:
mode: ISTION_MUTUAL
---
# 出错流量的转发
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: foo
spec:
host: foo.com
trafficPolicy:
loadBalancer:
locailityLbSetting:
enabled: true
failover:
- from: region1/zone1 # region1 zone1的出错流量到region2、zone2
to: region2/zone2
outlierDetection:
baseEjectionTime: 10s
consecutive5xxErrors: 100
interval: 10s
tls:
mode: ISTION_MUTUAL
集群过大的istio优化措施
- istio默认发现集群中所有的配置和服务状态
- 1w个service就会发现1w个envoy cluster
- 如果开启多集群,istio还会为每个cluster创建符合域名规范的集群
- istio还需要发现remot cluster中的service、endpoint、pod,频繁变更,会导致带宽和控制面的压力
- meshConfig中控制可见性
- defaultServiceExportTo: ["."] #改成.只会对当先ns可见
- defaultVirtualServiceExportTo
- defaultDestinationRuleExportTo
- 通过istio对象中spec.exportTo可以覆盖默认属性。在里面填写可见ns即可
istio自身规模控制
- 可以使用discoverySelector,允许istiod只发现添加特定label的namespace下的istio和k8s对象
- 同一集群安装多个istio,分而治之