2.1 istio的工作机制
istio架构分为控制面和数据面两部分。
控制面:包括pilot、mixer、citadel等组件
数据面:由伴随每个应用程序部署的代理程序envoy组成,执行针对应用程序的治理逻辑
从fronted服务访问forecast服务来看istio内部的组件都做了什么
如图
:
1)sidecar自动创建与注入:创建应用程序时自动注入sidecar代理。在k8s场景下创建Pod时,在创建业务容器的同时会创建sideCar容器,然后kube-apiserver调用管理面组件的sidecar-injector服务,自动修改应用程序的描述信息并注入sidecar。
2)流量拦截:pod初始化时设置iptables规则,有流量到来时,基于iptables规则拦截业务容器的Inbound流量和outBound流量到sidecar上,该过程应用程序无感知,应用程序间的访问方式不变。
上图中:流出fronted服务的流量会被fronted侧的envoy拦截;流量到达froecast容器前,inbound流量会被frecast服务测的envoy拦截。
3)服务发现:服务发起方的envoy调用管理面组件pilot的服务发现接口获取目标服务的实例列表。
上图中:fronted侧的envoy调用pilot的服务发现接口得到forecast服务各个实例的地址
4)负载均衡:服务发起方的envoy根据pilot中配置的负载均衡策略选择服务实例。
上图中:数据面的各个envoy从pilot中获取forcecast服务的负载均衡配置,并执行负载均衡动作
5)流量治理:envoy从pilot中获取配置的流量规则,在拦截到inbound和outbound流量时执行治理逻辑。
上图中:fronted服务侧的envoy从pilot中获取流量治理规则,并根据流量治理规则将不同特征的流量分发到forecats的v1和v2版本。
6)访问安全:在服务间访问时通过双方的envoy进行双向认证和通道加密,并基于服务的身份进行授权管理
上图中:pilot下发安全相关配置,在fronted和forecast服务上的envoy上自动加载证书和秘钥来实现双向认证。证书和秘钥由citadel来维护。
7)服务遥测:服务间通信时,通信双方的envoy都会连接管理面组件mixer上报访问数据,并通过mixer将数据转发给对应的监控后端。
如上图:fronted服务队forecast服务的访问监控指标、日志和调用链都通过该方式手机到对应的监控后端。
8)策略执行:进行服务访问时,通过mixer连接后端服务来控制服务间的访问,判断对服务放行还是拒绝。
上图中:mixer可以对接一个限流服务对fronted服务到forecast服务的访问进行速率控制。
9)外部访问:网格的入口有一个envoy扮演入口网关的角色。
上图中:外部服务通过gateway访问入口服务fronted,对fronted服务的负载均衡、治理策略都在该gateway上执行。
每个过程都可以进行如下抽象:服务调用双方的envoy代理拦截流量,并根据管理面的相关配置执行对应的治理动作。
2.2 istio的服务模型
istio支持将由服务、服务版本和服务实例构造的抽象模型映射到不同的平台上。
istio的几个约束:
1)端口命名:istio的服务端口必须命名,名称只能是
如: name:http2-forecast或name:http是合法端口名。name:httpsforecast是非法的端口名。
2)服务关联:Pod需要关联到服务,如果一个pod属于多个k8s服务,则要求服务不能在同一个端口上使用不同的协议
3)Deployment使用app和version标签。
2.2.1 istio的服务
逻辑上:istio的资源对象,包括域名和端口列表;每个端口包含端口名称、端口号和端口的协议。不同协议有不同的内容,在istio中也有不同的治理规则。
物理层面:存在形式就是k8s的service,只要满足了上述约束条件,就可以转换为istio的service并配置规则进行流量治理。
k8s中:service通过虚拟ip和port保证了服务地址是不变的,也无需暴露k8s中pod的端口和地址。
k8s中service的定义
apiVersion: v1
kind: Service
metadata:
name: forecast
spec:
ports:
- port: 8081 #指定service的虚拟端口号
targetPort: 8080 #对应到Pod容器的8080端口
selector:
app: forecast #对应到拥有label(app=webapp)的Pod
istio的service与k8s的区别在于:要满足istio的服务约束,如在端口名称上指定协议。如下(唯一区别是指定了协议为http):
apiVersion: v1
kind: Service
metadata:
name: forecast
spec:
ports:
- port: 8081 #指定service的虚拟端口号
targetPort: 8080 #对应到Pod容器的8080端口
name: http
selector:
app: forecast #对应到拥有label(app=webapp)的Pod
在istio中:service是治理的对象,是提供了对外访问能力的执行体,是istio服务的元数据。
2.2.2 istio的服务版本
istio应用场景中,灰度发布是一个重要的场景,即要求一个service有多个不同版本的实现。k8s语法上并不支持一个deployment中定义多个版本,在istio中多个版本的定义是将一个service关联到多个deployment。
如下图:
说明:
1)两个deployment都有相同的app:forecast标签,该标签和service的标签选择器一致,所以service能关联到这两个deployment对应的Pod。
2)两个deployment有不同的镜像版本,各自创建的Pod也不相同。version标签不同,分别是v1和v2
假设两个deployment分别创建3个和2个Pod,5个Pod都运行在不同的Node上,对service访问,根据配置的流量规则,可以将不同的流量转发到不同版本的Pod上,如下图:
2.2.3 istio的服务实例
服务实例:真正处理服务请求的后端,由代理根据负载均衡策略将流量转发发到其中一个后端处理。
属性:endpoints service labels avalibilityZone serviceAccount
istio的service对应k8s的service;
istio的服务实例对应k8s的endpoints
k8s的endpoints对象名称和service对应名称相同,是
2.3 Istio的组件功能和机制
2.3.1 istio-pilot
和传统的微服务架构对比,pilot至少涵盖服务注册中心和configServer的功能。
1)服务发现:pilot直接从运行平台提取数据,并将其构造成istio的服务发现模型。
2)规则转化与下发:负责将各种规则转换成envoy可识别的格式,通过xDs协议发送给envoy。
规则包括:virtualService、destinationRule、Gateway、ServiceEntry等流量治理规则,也包括认证授权等安全规则。
pilot将virtualService表达的路由规则分发到envoy如下图:
2.3.2 istio-telemetry
收集遥测数据的mixer服务组件。
调用时机:
与pilot不同,因为pilot管理的是配置数据,在配置改变时和数据面交互即可。
服务间每次交互,envoy都会对mixer进行一次调用,因此是一种实时管理。但是通过缓存机制,也可以不用每次都访问mixer。
如图:当网格中的两个服务发生了调用,服务的代理envoy就会上报遥测数据给istio-telemetry,istio-telemetry组件则根据配置将数据分发给后端的遥测服务。
图图
2.3.3 istio-policy
另一个mixer服务,和istio相同的机制。数据面在转发服务的请求前调用istio-policy的check接口检查是否允许访问,mixer根据配置将请求转发到对应的adapter做对应检查,返回允许或拒绝。如下图:
2.3.4 istio-citadel
istio的核心安全组件,提供了自动生成、分发、转化与车市秘钥和证书的功能。
实现:一直监听kube-apiserver,为每个服务生成证书和秘钥,并在pod创建时挂载到Pod上,代理容器使用这些文件做服务身份认证,进而代理两端服务实现双向TLS认证、通道加密等安全功能。
2.3.5 istio-galley
负责配置的管理组件,如验证配置纤细格式和内容的正确性,并将这些配置信息提供给pilot和mixer。
2.3.6 istio-sidecar-injector
负责自动注入,只要开启了自动注入,就会在pod创建时自动调用istio-sidecar-injector向pod中注入sidecar容器。
实现:kube-apiserver在拦截到Pod的创建请求时,会调用自动注入服务istio-sidecar-injector生成sidcar容器的描述并插入原pod的定义中。所以最终创建的容器包括业务和sidecar容器。且注入过程对用户透明。
2.3.7 isito-proxy
istio-proxy中除了有envoy,还有一个pilot-agent。 有时envoy、proxy、sidecar会混用。
envoy是c++开发的非常有影响力的服务代理,提供了动态服务发现、负载均衡、TLS、熔断、健康检查、流量拆分、灰度等功能。
2.3.8 istio-ingressgateway
入口处的gateway,即网格外访问网格内的服务就是通过这个gateway进行的。
ingressgateway的复杂和网格内的死的car是同样的执行体,都是从pilot处接收流量并执行。
如图:
特点:
1)开放了一组端口,是网格内服务的外部访问接口。
2)入口处的流量都走该服务,会有并发和流量峰值,所以需要评估流量来规划规格和实例数。
k8s和abtest再梳理
k8s的ingress 和 isito的gateway(ingress)有什么关系?
独立的两个东西,但都是集群外部客户端可访问集群内服务的实现方式。
k8s的ingress:
1)k8s可以通过type为loadbalancer类型service将服务发布出去,原理是k8s调用CloudProvider 在公有云上创建一个负载均衡服务,并且把被代理的 Pod 的 IP 地址配置给负载均衡服务做后端。
2)每个LoadBalancer类别的Service 都要有一个负载均衡服务,所以这个做法实际上浪费成本,更希望看到 Kubernetes 为我内置一个全局的负载均衡器。
3)所以实际的使用中,会创建kind为ingress的对象,该对应通过rules对应到具体的service,从社区里选择一个具体的 Ingress Controller,把它部署在 Kubernetes 集群里。
isito的gateway
将网格内的服务发布成外部可访问的服务,同时通过gateway配置外部访问的端口、协议及与内部服务的映射关系。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: abtest-gateway #gateway名称
namespace: peiyou-xiaohoucode
spec:
selector:
istio: ingressgateway # 获取对应的pod,实际干活的容器
servers:
- hosts: #针对所有域名
- '*'
port: #发布80端口
name: http
number: 80
protocol: HTTP
- hosts: #针对所有域名
- '*'
port:
name: https #发布443接口
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
privateKey: /etc/istio/ingressgateway-certs/tls.key
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
ingressgateway对应的pod定义:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: istio-ingressgateway
asm-system: 'true'
istio: ingressgateway #这里和gateway里面的对应
provider: asm
name: istio-ingressgateway
namespace: istio-system
spec:
progressDeadlineSeconds: 600
replicas: 10
revisionHistoryLimit: 10
selector:
matchLabels:
app: istio-ingressgateway
asm-system: 'true'
istio: ingressgateway
provider: asm
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: istio-ingressgateway
asm-system: 'true'
istio: ingressgateway
provider: asm
spec:
image: 'registry-vpc.cn-zhangjiakou.aliyuncs.com/acs/proxyv2:1.8.6'
......
volumes:
......
status:
.....
gateway在vs中使用:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: api.xiaohoucode.com
namespace: peiyou-xiaohoucode
spec:
gateways:
- abtest-gateway #使用上面的gateway
hosts:
- api.xiaohoucode.com
http:
.....
isito数据面 和 控制面之间是什么关系?怎么理解?
数据面:主要是指代理程序envoy的相关功能,即针对应用程序的治理逻辑
控制面:服务发现的pilot 服务遥测和策略执行的mixer 访问安全的citadel等
istio工作机制:
自动注入:sidecar的自动创建与注入
流量拦截
服务发现 服务发起方的envoy获取目标服务的实例列表
负载均衡
流量治理 主要包括vs、dr
访问安全:双向认证 通道加密 授权管理
服务监控(遥测):服务间调用时,双方的envoy都会调用控制面的mixer上报访问数据
策略执行:进行服务访问时,通过mixer连接策略执行后端服务来控制服务间的访问,判断对服务放行还是拒绝。如白名单
外部访问
isito相关的服务治理:
vs 服务路由(灰度等) 重定向 重写 重试 流量镜像 故障注入 跨域资源共享
描述的是满足什么条件的流量被那个后端处理。类似于根据路径去匹配方法,是更开放的martch条件。
dr 负载均衡 连接池 异常点检查 tls
描述的是这个请求到达某个后端后怎么去处理,是方法内的处理逻辑。所以负载均衡、熔断策略在这里
se 外部服务管理
gateway 外部服务访问
跨域资源共享:通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。
serviceEntry:网格内外的服务也像网格内的服务一样管理。
istio的组件和功能
istio-sidecar-injector:修改pod定义,pod中自动创建sidecar容器
isito-proxy:包括envoy和pilot-agent。envoy提供了动态服务发现、负载均衡、熔断、健康检查、灰度等功能
isito-galley:负责配置的管理组件,将配置信息提供给pilot和mixer
istio-pilot:服务发现,vs\dr\se规则转化并下发给envoy。配置有修改才会下发 这里的服务发现怎么理解?所有的vs、dr、se?
istio-citadel:为每个服务生成证书和秘钥,通道机密与双向TLS认证等
istio-telementry:收集遥测数据的mixer组件,每次服务间有交互,就会调用。
istio-policy:也是mixer组件,数据面在转发服务的请求前调用istio-policy的check接口检查目标服务是否允许访问
isito-ingressgateway:外部想要访问isito的内容服务都要经过该gateway
流程和对应组件的功能对应
自动注入 sidecar-injector
流量拦截 proxy
服务发现 pilot galley
负载均衡 proxy
流量治理 proxy
访问安全 citadel
服务遥测 telementry
策略执行 policy
外部访问 ingressgateway