TT Lab
开始
学习 学习路径 课程

Istio 服务网格

如何让网格外的服务器成为成员

在 TT Lab 中继续学习

一句话总结

网格扩展,就是给 Kubernetes 之外的服务器赋予身份,并把它列入网格的服务地图;它用 WorkloadGroup(一组服务器的模板)、WorkloadEntry(一台服务器)和 ServiceEntry(供调用的名称)三个对象来表达。

为什么这个问题依然存在

在引入了网格的组织里,最后留下的是迁移不了的服务器。需要重新认证的支付系统、许可证绑定在硬件上的软件、没人知道怎么构建的老旧服务。把它们放在网格之外,表面上看不出任何问题——调用正常,界面也完好。问题在于,从那里开始,网格提供的东西就断了。这一段没有 mTLS,基于调用方身份的授权无法生效,网格的服务地图和指标中也不会出现它。一旦出事,就成了“从这里开始我们看不到”。

这和登记对外发出的调用(用 ServiceEntry 写明外部 API)是两回事。前者是把客人领到门口,后者则是把这台服务器列入成员名册。

三个对象分担的工作

对象 对应的 Kubernetes 概念 写什么
WorkloadGroup Deployment 的 Pod 模板 这一组共用的标签、ServiceAccount、网络、端口、健康检查
WorkloadEntry 一个 Pod 该服务器的地址、网络、身份、地域(locality)、端口
ServiceEntry Service 在网格内调用的主机名,以及选择排在该名称之后的工作负载的选择器

其中最常被漏掉的是 ServiceEntry。只创建了 WorkloadEntry 的话,虽然完成了登记,但没有可供调用的名称。ServiceEntry 的 workloadSelector 通过标签选出 WorkloadEntry,把它们放在那个名称之后。此时选择器看的是 WorkloadEntry 的 metadata.labels——如果把标签写在 spec 里,什么都选不到。

location 的含义也很重要。取 MESH_INTERNAL 时,它被视为网格成员,成为 mTLS 和策略的作用对象;取 MESH_EXTERNAL 时,则被视为外部服务。同样是 ServiceEntry,仅这一个值就决定了安全模型。

resolution 决定如何找到目标,每个值的 endpoint 规则不同,而这些规则由 CRD schema 强制执行。NONE 直接使用原始目标地址,所以写了 endpoint 就会被拒绝。DNS_ROUND_ROBIN 是把一个名称解析一次并复用结果的方式,所以 endpoint 必须是 0 个或 1 个。STATIC 使用写明的 endpoint,或选择器选中的 WorkloadEntry。

身份如何送达那台服务器

在 Kubernetes 内,kubelet 会把令牌放进 Pod,代理用它来证明自己。VM 上没有 kubelet,所以必须由人放进去。这台服务器需要三样东西。

istioctl x workload entry configure 会把这三样收集起来,生成一个目录。打开结果中的 cluster.env,可以看到 SERVICE_ACCOUNT、ISTIO_META_NETWORK、ISTIO_INBOUND_PORTS 之类的值原样来自 WorkloadGroup。也就是说,WorkloadGroup 不只是声明,而是实际启动配置的源头。

network 的值也是在这里才有意义。网格会判断:network 名称相同的工作负载之间可直接互通,不同的则必须经过网关。值写错了,不是连不上,而是走到了意想不到的路径。

在现场相遇的样子

最常见的报告是“登记了,但哪里都看不到”。原因大多是标签不一致。如果 WorkloadEntry 的标签与 ServiceEntry 的选择器差一个字符,不会报错,只是什么都选不到。所以很多团队会在登记流程中附上一个脚本,统计选择器实际选中了几个。

第二种是地址写错。WorkloadEntry 的 address 既可以是 IP,也可以是 FQDN,所以 CRD schema 不强制格式。因此混有空格的值也会照样创建。能抓到这种问题的不是 API 服务器,而是 istioctl analyze——schema 检查和配置分析是两张不同的网,两张都有,漏洞才能补上。

本实验环境的局限

在实验 Pod 中,无法真正启动 VM。因此,看不到把生成的配置包放到服务器上、启动代理并接入网格的场景,也无法确认自动注册(VM 自己创建 WorkloadEntry)。不过,三个对象的 schema 强制校验、选择器实际选中的内容,以及配置包是如何由 WorkloadGroup 生成的,都可以针对真正的 API 服务器确认。

下一项实验要做什么

先写出服务器将要收到的身份字符串,再依次创建 WorkloadGroup、WorkloadEntry 和 ServiceEntry。亲自体验 schema 会拒绝的值(同时写两种 probe、去掉 template、按 resolution 区分的 endpoint 规则),最后实际生成 VM 要取走的配置包,并留下统计选择器选中多少台的报告。