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

Istio 服务网格

配置档与网格设置——两个撤销代价很高的决定

在 TT Lab 中继续学习

一句话总结

Istio 的安装分为两层:“选择一个称为 profile 的组合”和“把值写入网格全局配置”。两者在到达集群之前,都可以先用 istioctl manifest generate 完整读一遍。

为什么要提前阅读安装内容

第一次搭建网格时,人们最常做的事,就是把文档中的一行安装命令原样复制粘贴。这一行命令背后有将近 40 个对象,其中有几个拥有集群范围的权限。更重要的是这条命令同时埋下的默认值。网格全局配置是此后注入的所有代理都会读取的值,所以事后再修改,网格内的所有工作负载都要重新接收配置。回退的代价远大于部署的代价。

最典型的例子是 outboundTrafficPolicy.mode。默认值 ALLOW_ANY 会让代理放行发往未注册外部地址的调用。改为 REGISTRY_ONLY 后,代理会拒绝发往未注册目标的流量。如果启用当天没有人提前通知,发往支付代理商、内部 SMTP 和外部日志收集器的调用就会一下子全部中断。这样的值不应该是“装完再确认”,而应该是“装之前先达成一致”。 不过,仅凭这个设置并不能形成管控 Pod 所有对外通信的安全边界。要连代理不捕获的通信路径也一并阻断,还需要另外的网络管控。 Istio 安全最佳实践 也把用于找出服务注册遗漏的设置,与强制性的对外通信安全策略区分开来。

两个旋钮——profile 与取值

profile 是用来选择启动哪些组件的组合。以 1.24 为准,常用的四种区别如下。

profile 控制平面 网关 Ambient 组件
minimal istiod 无 无
default istiod 入口 无
demo istiod 入口 + 出口 无
ambient istiod 无 ztunnel + istio-cni-node

minimal 是整套网关(Deployment、Service、HPA、PDB、Role、RoleBinding、ServiceAccount)被整体去掉,而 demo 则是在此基础上再加一套出口网关。如果不想换整个组合,只想修改某一个值,就使用 --set values.…。例如 --set values.gateways.istio-ingressgateway.autoscaleMin=3 保持 profile 不变,只把渲染出的 HPA 的 minReplicas 从 1 改成 3。两个旋钮混着用,就会出现“以为换了 profile,其实只改了一个值”的状态。

网格全局配置是第三个位置。它通过 --set meshConfig.… 写入,在渲染结果中不是独立的 CRD,而是以 YAML 块的形式放在 istio-system 命名空间的 ConfigMap istio 中的 mesh 键里。

istioctl manifest generate --set profile=minimal \
  --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY \
  --set meshConfig.trustDomain=lab.internal

这里的 trustDomain 决定工作负载身份(SPIFFE ID)的前半部分,所以事后修改,所有以已签发身份为依据编写的授权策略都会失效。写在 defaultConfig 之下的内容,是每一个代理的默认行为——比如是否让应用容器等到代理准备就绪,以及终止时要等待多久。

如果值写错,在到达集群之前就会被拦下。给出不在枚举中的值,渲染会以 unknown value ... for enum istio.mesh.v1alpha1.MeshConfig.OutboundTrafficPolicy.Mode 结束;给出不存在的 profile 名称,则会提示找不到 profile 文件。还有一点——1.24 中根本没有 --profile 这个标志。正确的是 --set profile=,写错会以 unknown flag 结束。

在现场相遇的样子

第一种是“安装相同,但每个集群的行为不同”的报告。原因多半是每个人安装时加了各不相同的 --set,而且这条命令没有记录在任何地方。把渲染结果放进仓库并进行比较的习惯可以防止这种情况。清单无需集群就能生成,所以安装变更可以提交到代码评审中。

第二种是没有缩小范围的全局配置。某个团队要求增加代理的线程数,于是把网格全局的 defaultConfig.concurrency 调高,结果几千个 Pod 的内存用量也随之上升。这时要用的就是 ProxyConfig CRD——以命名空间或工作负载选择器为单位,覆盖全局默认值。值的检查不是由 istioctl,而是由 CRD schema 完成,所以负数之类的值会被 API 服务器拒绝。

本实验环境的局限

实验 Pod 中不会启动 istiod,也不会启动网关。因此,“改成 REGISTRY_ONLY 后调用中断了”这件事无法亲眼看到,代理实际读取这项设置的场景也无法确认。不过,决定安装的那份文档本身可以离线完整地生成,而且连着真正的 API 服务器,所以像 ProxyConfig 这样以 CRD 形式写入的设置,连 schema 的强制校验都可以实际确认。

下一项实验要做什么

依次渲染四个 profile,用文件比较哪些增加了、哪些减少了,再写入四项网格全局配置,并在渲染出的 ConfigMap istio 中找到它们。故意用错误的值、不存在的 profile 和不存在的标志被拒绝三次,最后制作 profile 与组件的对照表,并编写一个自行重新渲染来验证它的脚本。