k8s进阶:Istio概述
ServiceMesh
服务网格
概念,不是产品,针对微服务,解决网络层面的问题
实现
- Linkerd:
- 1.x基于节点(物理机,虚拟机)
- 2.x基于kubernetes
- Istio
- google+IBM+Lyft发起的开源项目
- 多平台支持
- 相同点
- 都基于sidecar
- 每个服务都会被分配到一个单独的代理
- 代理负责服务间通讯与转发,将请求的数据路由到目标服务的代理
- 该代理再将请求转发到其管理的微服务
- 都分为数据层和控制层
- 都基于sidecar
Istio
架构
高纬架构: data plane + control plane
核心组件: (Envoy proxy) + (Envoy + Istiod)
数据层: 一系列的代理,以sidecar方式运行,负责所有的网络通讯以及策略
- proxy: Envoy Istio的具体工作基本都由其完成.内置很多功能:
- 动态服务发现
- 负载均衡
- TLS终端
- HTTP/2与gRPC代理
- 熔断器
- 健康检查
- 基于百分比流量分割的分阶段发布
- 故障注入
- 丰富的指标
控制层: Istiod,提供服务发现,配置和证书管理
- Pilot: 好比是envoy的直接领导或者上司,指导envoy工作,为其提供信息.客户端为Pilot配置,Pilot将其转成envoy可以读取的格式.
- Galley: 控制层的配置管理中心
- Citadel: 安全相关,可以将http服务无感知升级成https;服务授权;RBAC访问控制;访问授权等等
解决的问题
部署
istioctl
照着官方文档(比如v1.13.4)做就行了,有几个注意点:
helm安装部署从v1.11就开始废弃了,推荐使用istioctl安装部署
istio的版本对k8s的版本有对应要求,先查清楚是否支持
基本上部署就是下载release包,解压,进到里面执行istioctl命令
部署的版本受两个因素影响
环境变量: ISTIO_VERSION
istioctl的版本=istio的版本,这是最高优先级
部署示例应用的时候,可以把istio-ingressgateway svc的type从默认的LoadBalance改成NodePort,这样就可以直接访问示例应用,或者按官方文档的做法获取LoadBanlance监听的NodePort和NodeIP去访问也行.
同样,部署dashboard kiali时候,svc默认是clusterIP,端口只监听localhost,改成NodePort就能在集群外访问,其实包括prometheus/grafana等addon都可以这么搞(测试环境),或者搞了ingress暴露出来?U can try.
列出profiles,istio支持多种不同的profile,不同profile包含不同的组件,demo包含所有组件,适合用来测试,default适合用于生产环境
1
istioctl profile list
预检查
1
istioctl x precheck
GetMesh
istio是最受欢迎和发展迅速的开源项目之一,这意味着它的发布和变更有时候会十分激进.GetMesh工具可以帮助我们管理不同版本istio,类似anaconda管理不同版本的python.
它可以通过针对不同的kubernetes分发版测试所有的istio版本以确保功能的完整性,另外GetMesh的istio版本再安全补丁和其他错误更新方面得到积极的支持.
对于一些安全性要求更高的客户,GetMesh提供两种istio发行版来解决合规性问题:
tetrate发行版,跟踪上有istio并可能应用额外的补丁
tetratefips发行版,符合FIPS标准的terate发行版
tetrate应该是istio的一个发行版,没有仔细研究.官网
1 |
|
istioctl + operator
这方式基于1.10.3,tetrate教程,估计其他版本也差不多.
初始化operator
1 |
|
指定profile
要安装istio,我们需要创建istioOperator资源,并指定我们要使用的配置文件:
1 |
|
1 |
|
启用sidecar注入
往任意一个namespace中添加istio-injection=enable
标签,就能在该命名空间上启用sidecar注入,这个namespace中每个一pod都被isitio自动注入envoy proxy sidecar.默认下default已被注入.
也可以使用istioctl kube-inject -h
命令
部署一个deploy测试一下,可以看到里面的直接就有了两个容器,里面会跑一个名为istio-init的init pod和一个名为istio-proxy的sidecar
1 |
|
概念
istio本身会在内部维护一个服务发现表,里面记录所有基于平台的服务注册信息,例如k8s的services或consul services.也支持手动添加服务入口(ServiceEntry)来添加一个入口到istio内部维护的服务注册中心.
虚拟服务(virtual service)和目标规则(destination rule)
基于istio与平台(k8s)提供的基本连通性(CNI)和服务发现能力(service),让你配置如何将服务网格内将请求路由到服务,.每个虚拟服务包含一组路由规则,istio按顺序评估他们,将每个给定的请求匹配到虚拟服务指定的实际目标地址
下面是istio的virtual service + destination rule 示例:
默认情况下路由所有http流量到打了”version:v1”reviews pod
另外匹配/wpcatalog和/consumercatalog两个uri,重写为/newcatalog并路由到打了”version:v2”reviews pod
1 |
|
virtual service
可以看到,virtual service本质上就是一个istio开发的CRD资源.
有点类似ingress,与service绑定,可以指定uri转发规则.
但是与ingress不一样的在于,它还可以根据subset和destination rule转发到指定版本的后端,以及配置一些istio更高级的功能.
hosts:
列举虚拟服务的主机,即用户指定的目标或路由规则设定的目标.可以是IP,DNS,或者依赖于平台的短名称,官方建议在kuberbnetes中最好使用FQDN.
也可以使用通配符”*”前缀
不必是istio服务注册表中的实际内容,可以是虚拟的目标地址,帮助你”虚空建模”
http: 包含虚拟服务的路由规则,用来描述匹配条件和路由行为,把http/1.1,http2和gRPC流量发送到hosts指定的目标
match: 匹配条件,举个例子:
1
2
3
4- match: #此路由匹配headers中含有end-user=json的流量
- headers:
end-user:
exact: jason.rule.destination: 指定实际的目标地址,于hosts不同,这里指定定的host必须真实存在于istio服务注册表中.可以是一个由代理的服务网格,或是一个通过服务入口添加进来的非网格服务,比如kubernetes的SVC.
路由优先级:
默认从上到下
官方建议配置一个”无条件”或基于权重的规则作为最后一条规则,此规则也将成为默认规则
destination rule
1 |
|
虚拟服务定义如何将流量路由给指定目标地址,目标规则配置该目标的流量.
也可以指定命名的服务子集(subsets),例如按版本给实例分组,然后在虚拟服务中使用match控制到不同实例的流量
还可以定制envoy流量策略,比如LB模型,TLS安全模式或熔断器等.
网关
由两部份组成:
网关代理,也叫gateway controller
- 比如istio-ingressgateway和istio-egressgateway
实际上是运行在网格边界的独立的Envoy代理,可以配置4-6层的LB属性(如端口,TLS设置等),也可以替代7层(应用层)的流量路由功能(ingress-controller).
绑定一个virtual service到网关,就可以像管理其他数据层面的流量一样去管理网关流量.
一般而言,主要用入口网关来管理进入的流量,当然出口网关也同样支持配置.通过”入门”文档部署的istio,会自动部署好两个预配置好的网关代理(istio-ingressgateway和istio-egressgateway),本质上是svc+pod(Envoy).
- 网关配置:
这个例子指定让https流量从ext-host.example.com通过443端口流入网格,但没有指定任何路由规则.
1 |
|
要指定路由规则,必须要在virtual service上绑定网关
1 |
|
更多
istio的流量配置还支持更多高级功能,例如根据header转发,字符串匹配,重试,百分比转发等
- 更多请阅Istio / 流量管理
官方示例
实验架构
TBD
流量管理
应用部署
可以看到,和一般的deployment并没有太大区别,但要注意看deployment和pod都定义了label: version=v1/v2/v3,这个在后面配置中有用.
网关配置
根据入门教程在部署istio的时候,部署了一些预先配置好的网关(istio-ingressgateway和istio-egressgateway),默认使用ClusterIP类型的SVC.为了方便,把istio-ingressgateway的SVC类型改成了NodePort.
与 Kubernetes Ingress API 这种控制进入系统流量的其他机制不同,Istio 网关让您充分利用流量路由的强大能力和灵活性。您可以这么做的原因是 Istio 的网关资源可以配置 4-6 层的负载均衡属性,如对外暴露的端口、TLS 设置等。也可以把应用层流量路由(L7)到相同的 API 资源.如果您绑定了一个常规的 Istio 虚拟服务到网关。这让您可以像管理网格中其他数据平面的流量一样去管理网关流量。
里面定义了一个网关和一个virtual service,配置了uri和网关关联.
此时通过http://:/productpage访问,多次刷新,发现版本会不停变动(review显示的星星).
那是因为还没有定义具体的review的virtual service,默认会轮询.review由三个版本在跑,所以不停刷新就看到不停变动.
virtual service
这里面定义的virtual service: productpage其实和上面的bookinfo重复了,可以去掉的.
在bookinfo中加上subset: v1就可以指定版本
destination rule
验证
使用以下命令查看virtual service和destination rule:
1 |
|
通过浏览器访问http://:/productpage,多次刷新,发现版本已经固定,那是因为virtual-service-all-v1.yaml已经指定了使用的review版本,流量只会去到version: v1的pod.
把review的virtual service改一下,改成subnets: v2就能使用v2版本.实际上不同的版本一直在跑,只是流量的路由被istio控制.