给不是容器的机器同样的身份
一句话总结
Kubernetes 之外的机器,装上 sidecar 也可以加入网格。WorkloadGroup 是这类机器的模板(标签、服务账号、端口),WorkloadEntry 是一台机器(地址),而 Kubernetes Service 的选择器也会选中 WorkloadEntry,所以可以把 VM 放在已有的服务名称后面。机器上的 sidecar 以与 Pod 相同的方式从 istiod 获取证书和配置。
为什么需要它
并不是所有东西都会迁移到容器中。老旧的支付系统、受许可证约束的数据库前端、连着特殊硬件的服务器都会留下来。如果这些机器在网格之外,会有两处崩塌——网格内的服务访问这些机器时,mTLS 和授权中断;这些机器访问网格内部时,因为没有身份而被 STRICT 策略拦下。最终就会出现例外规则(PERMISSIVE、宽泛放行),而例外会变成安全漏洞。
VM 纳入就是在那台机器上装同样的 sidecar,把它放进同一套身份体系的方法。
工作原理
1. 模板——WorkloadGroup。像 Pod 模板一样写明“这样的机器拥有这些标签、服务账号和端口”。istioctl x workload entry configure 会读取它,生成要交给机器的五个文件。
| 文件 | 在机器上的位置 | 用途 |
|---|---|---|
| cluster.env | /var/lib/istio/envoy/ | 命名空间、服务账号、标签、要拦截的端口 |
| istio-token | /var/run/secrets/tokens/ | 首次获取证书时出示的服务账号令牌 |
| mesh.yaml | /etc/istio/config/mesh | 网格配置(istiod 地址等) |
| root-cert.pem | /etc/certs/ | 要信任的根 |
| hosts | 追加到 /etc/hosts | 用来查找 istiod 名称的地址 |
2. sidecar——istio-sidecar 软件包。官方 deb 包会安装 pilot-agent、envoy 和 istio-start.sh。istio-start.sh 会用 iptables 植入把进出流量转给 sidecar 的规则,并以 istio-proxy 用户启动 pilot-agent。pilot-agent 用令牌向 istiod 请求证书,此后就像 Pod 的 sidecar 一样接收 xDS。
3. 一台机器——WorkloadEntry。写明地址、标签和服务账号。标签与服务选择器匹配时,istiod 会把这个地址作为该服务的端点下发给所有 sidecar。如果 istiod 开启了自动注册,sidecar 接入时会自动创建 WorkloadEntry,但这个功能需要在安装时开启。
到达 istiod 的路径。在跨多个网络的安装中,机器要经由东西向网关到达 istiod。如果机器所在的网络可以直接访问集群服务地址,也可以直接给出 istiod 的地址。
本实验环境中的“网格之外的机器”
每个会话只有一台 VM,而且 VM 之间无法通信。所以把同一台 VM 里的网络命名空间当作第二台机器。网络命名空间是内核中完整持有地址、路由表和 iptables 的隔离单元,所以 sidecar 的拦截规则只会进入它的内部。实际测量会发现,规则进入的是命名空间内的 iptables-legacy 一侧,而主机(有 k3s 的 kube-proxy 规则的那一侧)上不会出现任何 ISTIO 规则——两者互不冲突。与真正的 VM 唯一的区别,只是与主机共用文件系统。
在现场相遇的样子
“VM 上的 sidecar 能启动,却连不上 istiod”——大多是名称解析的问题。hosts 那一行漏了,或者 DNS 不认识集群内的名称。/var/log/istio/istio.log 中会留下连接错误。
“一小时后新的 VM 接入不了”——istio-token 默认只有一小时有效。首次获取证书之后会用证书续期,但如果在首次接入之前令牌就过期了,就要重新生成。
“把 VM 放到服务后面,偶尔会断连”——只要 WorkloadEntry 还在,端点就会一直保留。机器挂了也不会被摘除,所以要同时配合使用 WorkloadGroup 的 probe 自动注册,或者异常值检测。
官方文档:Virtual Machine Installation、Virtual Machine Architecture、WorkloadEntry、WorkloadGroup
下一项实验要做什么
先从外部访问在同一台 VM 的网络命名空间中运行的“网格之外的机器”,再创建 WorkloadGroup 和服务,生成要交给机器的文件。把文件放到位,在命名空间内启动 sidecar 并连接 istiod,然后统计 iptables 规则不会与主机冲突,并用 WorkloadEntry 把它放到服务后面。通过日志确认两个方向都建立了 mTLS,并进一步设置 STRICT 和授权策略。