用户您好!请先登录!

Istio学习笔记

Istio学习笔记

服务网格是什么

术语服务网格(Service Mesh)用于描述微服务之间的网络,以及通过此网络进行的服务之间的交互。随着服务数量和复杂度的增加,服务网格将变的难以理解和管理。

对服务网格的需求包括:服务发现、负载均衡、故障恢复、指标和监控,以及A/B测试、金丝雀发布、限速、访问控制、端对端身份验证等。

Istio是什么

使用云平台给DevOps团队带来了额外的约束,为了Portability开发人员通常需要使用微服务架构,运维人员则需要管理非常多数量的服务。Istio能够连接、保护、控制、观察这些微服务。

Istio是运行于分布式应用程序之上的透明(无代码入侵)服务网格,它同时也是一个平台,提供集成到其它日志、监控、策略系统的接口。

Istio的实现原理是,为每个微服务部署一个Sidecar,代理微服务之间的所有网络通信。在此基础上你可以通过Istio的控制平面实现:

  1. 针对HTTP、gRPC、WebSocket、TCP流量的负载均衡
  2. 细粒度的流量控制行为,包括路由、重试、故障转移、故障注入(fault injection)
  3. 可拔插的策略层+配置API,实现访问控制、限速、配额
  4. 自动收集指标、日志,跟踪集群内所有流量,包括Ingress/Egress
  5. 基于强身份认证和授权来保护服务之间的通信

Istio核心特性

流量管理

使用Istio你可以很容易的通过配置,对流量和API调用进行控制。服务级别的可配置属性包括断路器(circuit breakers)、超时、重试。

Istio支持基于流量百分比切分的A/B测试、金丝雀滚动发布、分阶段滚动发布。

安全性

可以提供安全信道,管理身份验证和授权,加密通信流量。

联用K8S的网络策略可以获得更多益处,例如保护Pod-to-Pod之间的通信。

可观察性

Istio强大的跟踪、监控、日志能力,让服务网格内部结构更容易观察 —— 一个服务的性能对上下游的影响可以直观的展现在仪表盘上。

Istio的Mixer组件——通用的策略和监控(Telemetry)中心(Hub)——负责策略控制、指标收集。Mixer提供后端基础设施(例如K8S)的隔离层,Istio的其它部分不需要关注后端细节。

后端支持

Istio当前支持:

  1. Kubernetes上的Service
  2. 通过Consul注册的服务
  3. 在独立虚拟机上运行的服务

架构

从整体上看,Istio的服务网格由数据平面、控制平面两部分组成:

  1. 数据平面由一系列作为Sidecar部署的智能代理(Envoy)构成。这些代理联合Mixer,中继、控制所有微服务之间的网络通信。需要注意,还有一些Envoy是独立部署(而非Sidecar)的,用来实现K8S Ingress控制器、Istio的Ingress/Egress网关
  2. 控制平面负责管理、配置智能代理,实现流量路由;配置Citadel实现TLS证书管理;配置Mixers来应用策略、收集指标

架构图:

istio-arch

 

Envoy

Istio使用一个扩展过的Envoy版本。Envoy是基于C++开发的高性能代理,Istio使用它的以下特性:

  1. 动态服务发现
  2. 负载均衡
  3. TLS termination —— 可将后端的HTTP服务包装为HTTPS
  4. HTTP/2和gRPC代理
  5. 断路器
  6. 健康检查
  7. 分阶段(基于流量百分比)发布
  8. 故障注入
  9. 丰富的监控指标

一般情况下Envoy在和目标服务的相同Pod中,以Sidecar形式部署。少量的Istio组件的主进程就是Envoy,包括Ingress控制器清单、Ingress/Egress网关。

Mixer

一个平台无关的组件:

  1. 为服务网格应用访问控制策略
  2. 从Envoy和其它服务中收集指标
  3. Envoy收集的请求级别的属性,被发送到Mixer进行分析

Mixer提供了一个灵活的插件模型,让Istio能够灵活的和多种宿主机环境、基础设施后端进行对接。

Pilot

该组件是Istio的控制器,它会监控各种规则、策略(通常存储在K8S中),一旦配置文件发生变化,就会提取、处理,并同步给Envoy:

  1. 为Envoy提供服务发现
  2. 为智能路由(AB测试、金丝雀部署……)提供流量管理能力
  3. 提供弹性(Resiliency)——超时、重试、断路器等
  4. 分发身份验证策略给Envoy

Pilot将高级别的路由规则转换为Envoy理解的配置信息,并在运行时将这些配置传播到Sidecars。

Pilot将平台相关的服务发现机制抽象为标准的(Envoy data plane API,xDS)格式,这让Istio可以在K8S、Consul、Nomad等多种环境下运行。

Citadel

负责证书、密钥的管理。提供服务-服务之间、或者针对终端用户的身份验证功能,可以加密服务网格中的流量。

Istio的性能

部署服务网格带来了额外的性能损耗,下面是Istio组件的推荐资源配置:

  1. 对于启用了访问日志(默认启用)的Sidecar,每1000请求/s可以配备1个vCPU,如果没有启用访问日志则配备0.5个vCPU
  2. 节点上的Fluentd是资源消耗大户,它会捕获并上报日志,如果不关心可以排除Sidecar日志不上报
  3. 在大部分情况下,Mixer Check有超过80%的缓存命中率,在此前提下,可以为Mixer的Pod每1000请求/s配备0.5个vCPU
  4. 由于在通信两端都引入了Sidecar代理、并且需要上报Mixer,大概会引入10ms的延迟

Istio的HA

任何控制平面组件都支持多实例部署,在K8S中可以考虑配置HPA。

考虑将Mixer的check、report功能分开部署。当前官方Chart已经分开,分别对应istio-policy、istio-telemetry两个Deployment。

术语列表
术语 说明
Service 一个应用程序“行为单元”,它对应服务注册表(例如K8S的集群服务DNS)中的唯一的名称

服务具有0-N个网络端点(Endpoint),这些端点可以是Pod、容器、虚拟机

Service versions 也叫subsets,这是持续部署(CD)中的概念

在持续部署时,网格中可能运行着某个微服务的多种变体,这些变体的二进制代码不同,但是API版本不一定不同。这些变体代表了对某个服务的迭代性的改变,部署在不同的环境中

Source 访问当前服务的下游(downstream)客户端
Host 客户端连接到服务器时所使用的DNS名称
Destination 表示一个可寻址的服务,请求/连接在经过路由处理后,将发送到Destination

新特性

1.5版本

单体化:

1.5版本的最大变化是,控制平面的大部分组件(pilot、citadel、sidecar-injector)合并到名为istiod的单体应用中,现在istiod负责:

  1. 配置处理和推送
  2. 证书分发
  3. Sidecar注入

以下组件被移除:

  1. SDS的node-agent(合并到Pilot Agent)

废弃Mixer:

Mixer被废弃,但是仍然可以使用。新版本HTTP遥测基于Envoy过滤器Stats filter实现,可以节省50%的CPU用量。

流量管理:
  1. 提升了 ServiceEntry 的性能。
  2. 修复了 readiness 探针不一致问题
  3. 通过定向局部更新的方式改善了配置更新的性能
  4. 添加了为 host 设置所在负载均衡器设置的选项
  5. 修复了 Pod 崩溃会触发过度配置推送的问题
  6. 添加了使用 Istio CNI 时对 iptables 的探测
  7. 添加了 consecutive_5xx 和 gateway_errors 作为离群值探测选项。
  8. 提升了 EnvoyFilter 匹配性能
  9. 添加了对 HTTP_PROXY 协议的支持
  10. 改进了 iptables 设置,默认使用 iptables-restore
  11. 默认开启自动协议探测
安全:
  1. 添加 Beta 认证 API。新 API 分为 PeerAuthentication 和 RequestAuthenticaiton,面向工作负载
  2. 添加认证策略,支持 deny 操作和语义排除
  3. Beta 版本默认开启自动 mTLS
  4. 稳定版添加 SDS
  5. Node agent 和 Pilot agent 合并,移除了 Pod 安全策略的需要,提升了安全性
  6. 合并 Citadel 证书发放功能到 Pilot
  7. 支持 Kubernetes first-party-jwt 作为集群中 CSR 认证的备用 token
  8. 通过 Istio Agent 向 Prometheus 提供密钥和证书
  9. 支持 Citadel 提供证书给控制平面
遥测:
  1. 为 v2 版本的遥测添加 TCP 协议支持
  2. 在指标和日志中支持添加 gRPC 响应状态码
  3. 改进 v2 遥测流程的稳定性
  4. 为 v2 遥测的可配置性提供 alpha 级别的支持
  5. 支持在 Envoy 节点的元数据中添加 AWS 平台的元数据
  6. 更新了 Mixer 的 Stackdriver 适配器,以支持可配置的刷新间隔来跟踪数据
  7. 支持对 Jaeger 插件的 headless 收集服务
  8. 修复了 kubernetesenv 适配器以提供对名字中有.的 Pod 的支持
  9. 改进了 Fluentd 适配器,在导出的时间戳中提供毫秒级输出

1.4版本

仍然以用户体验改进为主,简化配置难度。

无Mixer遥测

可以简化安装、Mesh的操控,并很大程度上改善性能。

istio-proxy内部生成HTTP指标的特性,从试验升级为Alpha。

istio-proxy内部生成TCP指标(试验)

自动mTLS

不需要配置DestinationRule即可自动启用。

1.3版本

该版本主要专注于用户体验的改善。

智能协议检测(试验)

为了使用Istio的路由特性,服务端口名必须遵循特定的命名约定,来声明其使用的协议。

从1.3开始,出站流量的协议可以自动识别为TCP或HTTP,这意味着服务端口命名协定不再必须

无Mixer遥测(试验)

现在大部分的安全策略(例如RBAC)已经直接在Envoy里面实现了。

istio-proxy现在可以直接向Prometheus发送数据,而不需要istio-telemetry来丰富、完善信息。

对生成的Envoy配置的定制能力

对于Envoy中的高级特性,Istio可能尚未提供对应API。你现在可以基于EnvoyFilter API来定制:

  1. LDS返回的HTTP/TCP监听器,及其过滤器链
  2. RDS返回的Envoy HTTP路由配置
  3. CDS返回的上游集群

1.2版本

一般特性
  1. 添加注解 traffic.sidecar.istio.io/includeInboundPorts,不再强制要求服务在deployment的YAML中声明contrainerPort
  2. 添加IPv6的试验性支持
流量管理
  1. 在多集群环境下,优化了基于位置的路由
  2. 优化了ALLOW_ANY模式(即允许任何未知的出站流量,配置位于configmap istio中)下的出站流量策略。针对未知HTTP/HTTPS主机+已知端口的流量,会原样的转发
  3. 支持设置针对上游服务的idle超时
  4. 改进了NONE模式(不用iptables,不进行流量捕获)的Sidecar支持
  5. 可以配置Sidecar的Envoy的DNS刷新率,防止DNS服务器过载
安全方面
  1. 扩展自签名Citadel根证书有效期为10年
  2. 可以为Deployment添加PodSpec注解 sidecar.istio.io/rewriteAppHTTPProbers: “true”,来重写健康探针
遥感方面
  1. 对Envoy统计信息生成的完全控制,基于注解控制
  2. Prometheus生成的不包含在指标中

1.1版本

性能方面

控制平面性能:Pilot的CPU、内存消耗受网格的配置变化情况、工作负载变化情况、连接到Pilot的代理数量的影响。增加Pilot的实例数来可以减少配置分发处理的时间,提高性能。网格中包含1000服务、2000工作负载、1000QPS的情况下,单个Pilot实例消耗1个vCPU和1.5GB内存。

数据平面性能:

  1. CPU,代理在1000QPS下大概消耗0.6个vCPU
  2. 内存,代理的内存消耗取决于它需要处理的配置数量,大量的Listener、Cluster、Route会增加内存使用。此外,代理在1000QPS下需要消耗50MB内存
  3. 延迟,请求需要同时经过客户端/服务器的sidecar,在1000QPS下P99大概是10ms级别。启用策略检查(Check)会额外增加延迟。L4过滤器的逻辑比较简单,因此TCP流量不会引入显著延迟
安装部署方面
  1. CRD从Istio的Chart中独立出来,放入istio-init这个Chart。这避免了升级Istio而丢失CR数据
  2. 添加几个安装配置Profile,这些配置提供了常用的安装模式,简化了Istio的安装过程
  3. 增强了多集群集成
流量管理方面
  1. 新的资源类型Sidecar。用于对工作负载的边车代理进行细粒度的控制,特别是可以限制边车能够向哪些服务发送流量。此资源可以减少需要计算和传输给边车代理的配置信息,提升启动速度,减少资源消耗,提升控制平面可扩容性。在大型集群中,建议为每个命名空间提供一个Sidecar资源
  2. 支持限制服务(ServiceEntry、VirtualService)的可见范围。exportTo可用于限制哪些命名空间能够访问本服务。除了在Istio CR上指定exportTo以外,你还可以在K8S的Service上使用networking.istio.io/exportTo注解
  3. Gateway引用VirtualService时,可能存在歧义,因为不同命名空间可能定义具有相同hostname的VirtualService。在1.1版本中,你可以用namespace/hostname-match的形式来来设置hosts字段,以避免歧义。类似的在Sidecar中你也可以为egress配置为这种形式
  4. 支持设置ServiceEntry的Locality,以及关联的SAN(用于mTLS)。现在使用HTTPS端口的ServiceEntry不再需要配套的VirtualService来工作
  5. 位置感知路由(Locality-Aware Routing),优先路由到位于当前地理位置(Locality)的服务端点
  6. 简化了多集群模式的安装、支持额外的部署模式。现在可以用Ingress网关连接多个集群,而不需要Pod级别的VPN。为了HA可以在各集群中部署控制平面,这种部署方式下位置感知路由自动开启。可以将命名空间扩展到多个集群,以创建全局命名空间
  7. Istio的Ingress组件被废弃
  8. 性能和可扩容性得到提升
  9. 默认关闭访问日志
安全方面
  1. 健康检查探针,当启用mTLS的情况下,支持Kubernetes的Readiness/Liveness探针。当启用mTLS后,进入Envoy的HTTP探针请求会被拒绝,1.1能够自动进行HTTP探针的重写,将探针请求转发给pilot-agent,并由后者直接转发给工作负载,绕开Envoy的TLS认证
  2. 集群RBAC配置,将RbacConfig资源替换为ClusterRbacConfig资源
  3. 基于SDS的身份配置(Identity Provisioning ),不需要重启Envoy即可实现动态证书轮换,实现on-node的密钥生成增强了安全性
  4. 在HTTP/gRPC的基础上,支持TCP服务的授权
  5. 支持基于终端用户组的授权
  6. Ingress网关控制器支持外部证书管理,新的控制器用于支持动态的加载、轮换外部证书
  7. 定制PKI集成,支持Vault PKI,基于Vault CA签发证书
策略和遥感方面
  1. 策略检查默认关闭,主要是出于性能方面的考虑
  2. 性能的增强:
    1. 极大的减少了Envoy默认生成的统计信息的收集
    2. 为Mixer工作负载添加了负载限制的功能
    3. 改善了Mixer和Envoy之间的交互协议
  3. 适配器现在能够影响入站请求的头和路由
  4. 进程外适配器,生产级可用,进程内适配器被废弃
  5. 添加了默认的用于跟踪TCP连接的指标

多集群支持

在1.0版本Istio只提供了一种基于扁平网络的多集群方案:Istio控制平面部署在其中单个Kubernetes集群中。这种方案要求各集群的 Pod 地址范围不能重叠,且所有的 Kubernetes 控制平面API Server 互通。看上去就是物理上把多个Kubernetes并到一个Istio控制面下,在Istio看来是同一个网格。这种方案的网络要求苛刻,实际应用并不多。

1.1版本对多集群上做了非常多的增强,除了保留1.0扁平网络作为一种单控制面的方案外,还提出了另外两种方案供用户根据实际环境和需求灵活选择,这两种方案都不要求是扁平网络:

  1. 多控制平面方案:在每个集群中安装完整的Istio控制平面,可以看成是一种松散的联邦,集群间服务在Gateway处联通即可。通过一个全局的DNS将跨集群的请求路由到另外一个集群里去。这种集群的访问是基于Istio的ServiceEntry和Gateway来实现的,配置较多且复杂,需用户自己维护
  2. 一种集群感知(Split Horizon EDS)的单控制平面方案:Istio控制平面只在一个Kubernetes集群中安装,Istio控制平面仍然需要连接所有Kubernetes集群的K8S API Server。每个集群都有集群标识和网络标识。在服务间访问时,如果目标是本集群的负载,则类似单集群的方式直接转发;如果是其他集群的实例,则将流量转发到集群的入口网关上,再经过网关转发给实际负载

exportTo字段

在1.1版本中添加了一个重要字段exportTo。用于控制VirtualService、DestinationRule和 ServiceEntry 跨Namespace的可见性。这样就可以控制一个Namespace下定义的资源是否可以被其他Namespace下的Envoy访问。

如果不设置exportTo则默认全局可见。目前exportTo仅仅支持两个取值:

  • “.”,表示仅仅当前命名空间可以使用当前资源
  • “*”,表示任何命名空间都可以使用当前资源

如果服务对Pod不可见,则Istio不会为该Pod的Envoy生成Listener、Cluster等信息,因而可以减少内存消耗。

sidecar资源

Sidecar是具有命名空间的资源。每个Sidecar应用到命名空间的一个和多个工作负载,工作负载的选择通过workloadSelector进行,如果不指定workloadSelector(每个命名空间只能有一个这样的Sidecar)则Sidecar应用到命名空间的所有(没有被其它带有workloadSelector的Sidecar匹配的)工作负载。

如果命名空间包含多个没有workloadSelector的Sidecar,或者多个Sidecar的workloadSelector匹配同一工作负载,则网格的行为是未定义的。

配置示例一,允许prod-us1命名空间的Pod发起针对prod-us1, prod-apis, istio-system命名空间的公共服务的egress流量:YAML

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: prod-us1
spec:
  # 需要通信的服务白名单,可以很大程度上减少Envoy内存消耗
  # 经过测试,创建此资源后,istioctl proxy-config listener PODNAME 输出立刻变得非常少
  # 但是并没有禁止对外访问,可能和ALLOW_ANY有关?
  egress:
  – hosts:
    # 支持namespace/hostname-match形式的host规则
    – “prod-us1/*”
    – “prod-apis/*”
    – “istio-system/*”
    # 当前命名空间
    – “./ratings.default.svc.cluster.local”

配置示例二:YAML

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: prod-us1
spec:
  # 入站流量规则
  ingress:
  # 对于从9080端口入站的HTTP流量,将其转发给Sidecar关联的工作负载监听的UDS
  – port:
      number: 9080
      protocol: HTTP
      name: somename
    defaultEndpoint: unix:///var/run/someuds.sock
  # 出站流量规则
  egress:
  # 允许针对istio-system命名空间的出站流量
  – hosts:
    – “istio-system/*”
  # 允许针对prod-us1命名空间的9080端口的HTTP流量
  – port:
      number: 9080
      protocol: HTTP
      name: egresshttp
    hosts:
    – “prod-us1/*”

 

配置示例三,如果工作负载没有启用基于Iptables的流量劫持,则Sidecar资源是唯一的配置工作负载边车端口的途径:YAML

取值 说明
DEFAULT 由环境定义的默认捕获模式
IPTABLES 基于Iptables重定向进行捕获
NONE 不进行流量捕获,当用在:

  1. egress监听器中时,应用程序被期望明确的和监听的端口/UDS进行直接通信
  2. ingress监听器中时,必须保证工作负载的其它进程不会占用目标监听端口
位置感知路由

Istio支持使用三元组:Region、Zone、Sub-zone来描述网格的地理位置,地理位置通常精确到某个数据中心。Istio能够使用此地理位置信息来对负载均衡池进行优先级控制。

在1.1版本中,基于地理位置的负载均衡仍然是试验特性,且默认关闭。设置环境变量PILOT_ENABLE_LOCALITY_LOAD_BALANCING到所有Pilot实例以开启此特性。

服务发现平台负责自动产生地理位置信息,在K8S中,Pod的地理位置基于它所在Node的知名标签来获取。在云环境下,Node的这些标签会自动设置,否则你需要手工设置Node标签。这些标签包括:

failure-domain.beta.kubernetes.io/region

failure-domain.beta.kubernetes.io/zone

注意,K8S没有sub-zone的概念。

基于地理位置的负载均衡,其默认模式是地理位置优先负载均衡(locality-prioritized load balancing )。Istio会提示Envoy,尽可能将流量转发给和当前Enovy更近的目标工作负载实例。

另一种模式是地理位置权重负载均衡(Locality-weighted load balancing),直接指定不同地理位置负责提供服务的权重。

CLI 及其它分享

https://blog.gmem.cc/istio-study-note

相关问题

Issue:https://github.com/istio/istio/issues/16387

行走的code

要发表评论,您必须先登录