如何让网格外的服务器成为成员
一句话总结
网格扩展,就是给 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,所以必须由人放进去。这台服务器需要三样东西。
- 网格配置——要连接到哪里(
discoveryAddress),默认使用什么 - 根证书——信任谁。来自命名空间的 ConfigMap
istio-ca-root-cert - 令牌——自己是谁。用 WorkloadGroup 中写明的 ServiceAccount 签发
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 要取走的配置包,并留下统计选择器选中多少台的报告。