导言
istio中部署东西向网关实际上有两种方式,一种是通过东西向网关的deployment走istio的注入流程实现,另一种则是通过IstioOperator自定义资源中中添加东西向网关组件配置,并由IstioOperator组件负责管理创建流程。本文主要讨论前一种情况。
1、官方的EastWestGateway Deployment入手
通过查看istio的官方代码,在manifests/charts/gateway/templates/deployment.yaml中
可以看到东西向网关的deployment模板中会打上istio注入sidecar所需的标签,说明其必须经过istio webhook的注入流程。同时,所用的镜像地址为auto,对于值为auto的镜像,istio的注入流程中会将其识别,并用sidecar proxy的镜像地址替换。
因为,如果用deployment方式部署东西向网关时没有经过sidecar注入流程,则镜像会拉取失败
2、查看istio webhook的注入流程
接下来需要了解istio的pod注入流程,从而明白东西向网关的sidecar容器是如何注入进去的,其中最关键的就是RunTemplate方法以及reapplyOverwrittenContainers方法。RunTemplate方法目的在于根据注入pod的类型找到合适的注入模板,而reapplyOverwrittenContainers则是重写容器启动所需的配置。
2.1 选择模板
1)从istio-sidecar-injector这个configmap中读取名叫gateway的模板
首先,RunTemplate方法中主要流程在于selecTemplates方法,该方法主要是读取pod的注解中是否存在某个key,这个key就是的值就是注入模板的名称
回到东西向网关的deployment..yaml文件,可以看到template.metadata.annotation中确实存在这样一个key,而且他的值为gateway类型,因此注入流程会从istio-sidecar-injecto这个configmap中找到key叫gateway的模板。
下面这里即为istio-sidecae-injector confgimap的模板部分,它包含着多个注入模板,分别有不同的key,比如sidecar、gateway、grpc-simple等等,而上面的代码则会从中选择gateway的部分,可以看到这个模板的内容实际上就是gateway-injection-template.yaml这个文件的内容。
这个template的内容位于manifests/charts/istio-control/istio-discovery/files/gateway-injection-template.yaml,可以看到这个文件里面包含具体的镜像、启动参数等配置
2.2 重写container配置,reapplyOverwrittenContainers
这个函数逻辑比较复杂,简单看看注释说说的
// reapplyOverwrittenContainers enables users to provide container level overrides for settings in the injection template
// * originalPod: the pod before injection. If needed, we will apply some configurations from this pod on top of the final pod
// * templatePod: the rendered injection template. This is needed only to see what containers we injected
// * finalPod: the current result of injection, roughly equivalent to the merging of originalPod and templatePod
// There are essentially three cases we cover here:
// 1. There is no overlap in containers in original and template pod. We will do nothing.
// 2. There is an overlap (ie, both define istio-proxy), but that is because the pod is being re-injected.
// In this case we do nothing, since we want to apply the new settings
// 3. There is an overlap. We will re-apply the original container.
//
// Where "overlap" is a container defined in both the original and template pod. Typically, this would mean
// the user has defined an `istio-proxy` container in their own pod spec.
这段代码注释描述了一个函数 reapplyOverwrittenContainers 的功能,该函数允许用户为注入模板中的容器级设置提供覆盖。
在这段注释中,涉及到以下几个关键点:
1、originalPod:表示注入之前的原始 Pod。如果需要,在最终生成的 Pod 上应用一些来自原始 Pod 的配置。
2、templatePod:表示渲染后的注入模板。这个信息仅用于查看我们注入的容器(istio-proxy)。
3、finalPod:表示当前注入结果,大致相当于原始 Pod 和模板 Pod 的合并结果。
根据注释所述,这个函数主要处理以下三种情况:
1、没有重叠的容器:原始 Pod 和模板 Pod 中不存在相同的容器时,不做任何操作。
2、存在重叠的容器(且都是istio-proxy):这意味着用户在他们自己的 Pod 规范中定义了一个 istio-proxy 容器,但这是因为 Pod 正在重新注入。在这种情况下,也不做任何操作,因为我们希望应用新的设置。
3、存在重叠的容器(其他容器):将重新应用原始容器,这个函数的作用是确保在注入过程中正确处理容器级别的设置,以避免意外覆盖用户自定义的容器设置。
对于东西向网关来说,container的名称即为istio-proxy,所以会被完全覆盖
3、对比经过注入处理的eastwestgateway的container定义以及原始的eastwestgateway的container定义
发现经过注入后的东西向网关会新增一些启动参数以及环境变量
如果运行没有经过注入的eastwestgateway,会由于istio-proxy缺乏相关的启动参数运行异常
4、结语
通过上述流程的分析,可以知道istio是如何为pod注入sidecar的,而不仅仅是网关类型的sidecar,其他类型的sidecar也同样是这样的流程。此外,我们还可以思考如果是否可以不通过注入流程进行东西向网关的部署(比如IstioOperator的方式),如果可以,在原始模板上应该需要做哪些工作呢?