Istio Pilot 源码分析(一)

本文深入分析Istio Pilot的源码,包括启动流程、接口设计和核心组件,帮助读者理解Istio的控制面组件运行机制。内容涵盖宏观架构、初始化流程和接口设计,适合对Istio基础概念熟悉的读者,旨在消除对Istio的陌生感,增强开发中的问题定位能力。
摘要由CSDN通过智能技术生成

张海东, ‍多点生活(成都)云原生开发工程师。

Istio 作为目前 Servic Mesh 方案中的翘楚,吸引着越来越多的企业及开发者。越来越多的团队想将其应用于微服务的治理,但在实际落地时却因为不了解 Istio 黑盒中的运行机制而左右为难,本文将基于 1.7 的源码讲解 Istio 的核心组件 Pilot 的结构及运行流程,希望对读者应用 Istio 有所助益。

注:本文基于 istio release-1.7 分支分析,其他版本的代码结构会有所不同。

背景

随着 Istio 1.7 的发布,内部组件精简后的 istiod 日趋稳定,越来越多的公司将其应用到自身微服务的流量治理、安全通信及监测中。多点也不例外,应用 Istio 来落地业务系统所有 Dubbo 服务的网格化,下沉 SDK 逻辑,解决基础中间件与业务系统过于耦合等痛点。目前,我们是通过自己开发的 Controller 组件对接 Zookeeper 等注册中心,将注册到 Zookeeper 的节点实时转化为 ServiceEntry 及 WorkloadEntry 等 Istio 配置类型写入 kube-apiserver,再由 Pilot 转化为 xDS 协议下发至数据面,同时对集群、虚拟机中的服务进行治理。随着公司服务网格化的逐步落地,对 Istio 及数据面组件源码级掌握的诉求越来越高,没有足够的深度及广度很难解决开发过程中遇到的难题,让我们一起揭开 Istio 神秘的面纱,看看黑箱内部是如何运作的。

本文作为 Istio 控制面组件 Pilot 的源码分析系列,主要面向刚接触 Istio 或仅停留在使用 Istio 基本配置类型(如 VirtualServiceDestinationRule 等)的同学,需要熟悉 Istio 的一些 基础概念及名词[1] 。文章会涉及较多的代码细节,我们会以不同的篇幅分别介绍以下内容:

1.pilot-discovery 宏观架构及启动流程梳理2.pilot-discovery 接口设计及关键接口分析3.pilot-discovery xDS 生成及下发流程梳理4.pilot-agent 流程梳理5.pilot 中的身份认证及安全通信解析

相信通过源码一步一步分析,能消除读者对 Pilot 的陌生感,在基于 Pilot 做适配开发时会更加清楚的了解其底层运行逻辑,碰到问题时也能更好的定位。

Pilot 的代码主要分为两部分:

pilot-discoverypilot-agent

其中 pilot-agent 负责数据面 Sidecar 实例的生命周期管理,而 pilot-discovery 负责控制面流量管理配置及路由规则的生成和下发。

宏观架构

pilot-discovery 的核心组件如图:

pilot-discovery-struct

其中 Server 为 pilot-discovery 的主服务,包含了三个比较重要的组件:

Config Controller:从不同来源接收流量控制和路由规则等 Istio 的配置,并响应各类事件。•Service Controller:从不同注册中心同步服务及实例,并响应各类事件。•EnvoyXdsServer:核心的 xDS 协议推送服务,根据上面组件的数据生成 xDS 协议并下发。

Config Controller 比较核心的就是对接 Kubernetes,从 kube-apiserver 中 Watch 集群中的 VirtualServiceServiceEntryDestinationRules 等配置信息,有变化则生成 PushRequest 推送至 EnvoyXdsServer 中的推送队列。除此之外,还支持对接 MCP(Mesh Configuration Protocol) 协议的 gRPC Server,如 Nacos 的 MCP 服务等,只需要在 meshconfig 中配置 configSources 即可。最后一种是基于内存的 Config Controller 实现,通过 Watch 一个文件目录,加载目录中的 yaml 文件生成配置数据,主要用来测试。

Service Controller 目前原生支持 Kubernetes 和 Consul,注册在这些注册中心中的服务可以无痛接入 Mesh,另外一种比较特殊,就是 ServiceEntryStore,它本质是储存在 Config Controller 中的 Istio 配置数据,但它描述的却是集群外部的服务信息,详情可阅读文档 ServiceEntry[2]Istio 通过它将集群外部,如部署在虚拟机中的服务、非 Kubernetes 的原生服务同步到 Istio 中,纳入网格统一进行流量控制和路由,所以 ServiceEntryStore 也可以视为一种注册中心。还有一种就是 Mock Service Registry,主要用来测试。

ServiceEntryStore 从 Config Controller 到 Service Controller 的转化流程大致如图(后续会做详细的代码分析,这里简单了解一下即可):

pilot-discovery-serviceentrystore

ConfigStores 是一个列表,里面存储了各类 Istio 配置文件,包括 ServiceEntry 、WorkloadEntry 等服务数据,也包括 VirtualServiceDestinationRulesSidecar 等流量控制、路由规则的配置数据,pilot-discovery 将这些 ConfigStores 聚合成一个 configController 统一进行管理,之后再从其中衍生出 IstioConfigStore,将其作为 serviceEntryStore 的配置源。serviceEntryStore 其实就是 ServiceEntry Controller,响应 ServiceEntry 和 WorkloadEntry 这类服务信息的变化。

EnvoyXdsServer 比较核心,一切与 xDS 协议相关的接收、转换、下发操作都由它完成。EnvoyXdsServer 对接所有集群中的边车代理,如 EnvoyMOSN 等,当配置或服务发生变化时主动推送,也会响应代理发送的请求,依据请求的信息下发相应的 xDS 配置。

理解了这三个核心组件的定义,就能比较好的理解下面分析的各类流程了。

pilot-discovery 的整个业务流程梳理如下,可以先大概浏览一遍,之后我们逐一进行分析:

pilot-discovery-sequence-all

启动流程梳理

首先详细看一下 pilot-discovery 的启动流程。pilot-discovery 组件的入口代码在 istio/pilot/cmd/pilot-discovery 中。该目录中包含两个文件: main.go 和 request.gomain.go 中定义了 pilot-discovery 根命令及 discovery 命令,是启动服务发现及配置下发的主流程; 另一个文件 request.go 中定义了 request 命令,用来请求 Pilot 中的 metrics/debug 接口,多用来调试。

main.go 中 discoveryCmd的 RunE 函数定义了启动过程,代码如下:

// 创建一个接收空结构的 stop channel 用来停止所有 servers
stop := make(chan struct{})
// 创建服务发现的 Server
discoveryServer, err := bootstrap.NewServer(serverArgs)
if err != nil {
  return fmt.Errorf("faile
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值