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

Istio 服务网格

安装之前先读懂会装进什么——配置档与网格设置

在 TT Lab 中继续学习

目标

用 istioctl manifest generate 在没有集群的情况下渲染四种安装 profile,把组件差异整理成表,并确认通过 --set meshConfig.… 写入的网格全局配置真的出现在渲染出的 ConfigMap istio 中。最后把只覆盖一个命名空间的 ProxyConfig 应用到真实的 API 服务器上,观察 schema 强制校验了什么。

为什么重要

引入网格时,回退代价最高的两个决定就是 profile 和网格全局配置。profile 决定启动什么(要不要网关,是否采用 Ambient),网格全局配置则会成为所有代理的默认值。只要把 outboundTrafficPolicy.mode 一个值改成 REGISTRY_ONLY,代理就会拒绝发往未注册外部目标的流量。这与管控所有通信路径的安全边界不同,但会立即影响服务。所以这些值必须在安装之前读一遍。好在 istioctl 即使没有集群,也能把安装结果整体渲染出来——清单本身就是可以阅读的文档,不断更换 profile 渲染并比较,增加了什么、减少了什么一目了然。值写错的话,在到达集群之前就会被拒绝,这一点也会在这里确认。

步骤

  1. 创建 /root/ist-profiles,把 istioctl manifest generate --set profile=default 的输出保存到 /root/ist-profiles/default.yaml。然后按类型统计该文件中的对象数量,按类型名称升序写入 /root/ist-profiles/default-kinds.tsv,格式为 <kind>\t<개수>(占位符依次为类型名和数量)。
  2. 把 --set profile=minimal 的渲染结果保存到 /root/ist-profiles/minimal.yaml。然后把 default 中有而 minimal 中没有的对象,排序后每行一个写入 /root/ist-profiles/minimal-missing.tsv,格式为 <kind>|<이름>(占位符依次为类型名和对象名)。
  3. 把 --set profile=demo 的渲染结果保存到 /root/ist-profiles/demo.yaml,并把只在 demo 中有而 default 中没有的对象,以 <kind>|<이름>(占位符依次为类型名和对象名)的格式排序后写入 /root/ist-profiles/demo-extra.tsv。
  4. 保持 default profile 不变,加上 --set values.gateways.istio-ingressgateway.autoscaleMin=3 进行渲染,把结果保存到 /root/ist-profiles/gw-scaled.yaml。然后把覆盖前后 HorizontalPodAutoscaler istio-ingressgateway 的 spec.minReplicas 值,分两行写入 /root/ist-profiles/hpa-before-after.tsv:before\t<값> 和 after\t<값>(占位符为该值)。
  5. 给 minimal profile 加上四项网格配置后渲染——meshConfig.outboundTrafficPolicy.mode 为 REGISTRY_ONLY,meshConfig.accessLogFile 为 /dev/stdout,meshConfig.trustDomain 为 lab.internal,meshConfig.defaultConfig.holdApplicationUntilProxyStarts 为 true。从渲染结果中只取出名称为 istio 的 ConfigMap 对象,保存到 /root/ist-profiles/mesh-cm.yaml,并把该 ConfigMap 的 data.mesh 字符串单独保存到 /root/ist-profiles/mesh.yaml。
  6. 故意出错三次,把报错的句子按顺序收集到 /root/ist-profiles/rejected.txt——(1)给 minimal profile 的 meshConfig.outboundTrafficPolicy.mode 设为 BLOCK_ALL;(2)用 --set profile=sidecarless 调用不存在的 profile;(3)像 --profile=minimal 这样以标志的形式给出 profile。标准错误也要一并写入。
  7. 创建命名空间 profile-lab,并在其中实际应用 ProxyConfig ns-default——spec.concurrency 为 2,在 spec.environmentVariables 中设置 ISTIO_META_LAB_TIER: "gold"。清单放在 /root/ist-profiles/proxyconfig.yaml 中。然后在 /root/ist-profiles/proxyconfig-negative.yaml 中把 ns-negative 写成 concurrency: -1,通过服务端试运行应用让它被拒绝,并把该拒绝的句子保存到 /root/ist-profiles/proxyconfig-reject.txt。
  8. 在 /root/ist-profiles/profile-matrix.tsv 中写入 <프로파일>\t<kind>|<이름>\t<yes|no>(占位符依次为 profile 名称、类型与名称、是否存在)——profile 必须包含 default、demo、minimal、ambient 四种,组件必须包含 Deployment|istiod、Deployment|istio-ingressgateway、Deployment|istio-egressgateway、DaemonSet|ztunnel、DaemonSet|istio-cni-node 五种(共二十行)。/root/ist-profiles/check-profiles.sh 读取这张表并重新渲染 profile,匹配时只向标准输出打印 OK …,不匹配时只向标准输出打印 MISMATCH …,只要有一行不匹配就必须以非 0 退出码结束。把它的输出保存到 /root/ist-profiles/matrix-result.txt。

参考

先数一数默认 profile 会生成什么

创建 /root/ist-profiles,把 istioctl manifest generate --set profile=default 的输出保存到 /root/ist-profiles/default.yaml。然后按类型统计该文件中的对象数量,按类型名称升序写入 /root/ist-profiles/default-kinds.tsv,格式为 <kind>\t<개수>(占位符依次为类型名和数量)。

渲染结果是由多个文档连接在一起的 YAML。可以用 yq -N e '.kind' 파일(占位符为文件名)提取每个文档的 kind,再接上 sort 和 uniq -c 就能得到数量。列之间用制表符分隔。

降为 minimal 后,究竟少了什么

把 --set profile=minimal 的渲染结果保存到 /root/ist-profiles/minimal.yaml。然后把 default 中有而 minimal 中没有的对象,排序后每行一个写入 /root/ist-profiles/minimal-missing.tsv,格式为 <kind>|<이름>(占位符依次为类型名和对象名)。

分别从两个文件中提取 [.kind, .metadata.name] | join("|"),各自用 sort -u 整理后再用 comm 比较,就能得到只在一侧存在的行。消失的是附属于某个组件的一组对象。

demo 在 default 之上多加了什么

把 --set profile=demo 的渲染结果保存到 /root/ist-profiles/demo.yaml,并把只在 demo 中有而 default 中没有的对象,以 <kind>|<이름>(占位符依次为类型名和对象名)的格式排序后写入 /root/ist-profiles/demo-extra.tsv。

方法与第 2 步相同,只是方向相反。comm 的 -23 和 -13 保留的是相反的一侧。demo 多加的是把出站流量集中到一处的组件。

选择 profile 与覆盖某一个值,是不同的旋钮

保持 default profile 不变,加上 --set values.gateways.istio-ingressgateway.autoscaleMin=3 进行渲染,把结果保存到 /root/ist-profiles/gw-scaled.yaml。然后把覆盖前后 HorizontalPodAutoscaler istio-ingressgateway 的 spec.minReplicas 值,分两行写入 /root/ist-profiles/hpa-before-after.tsv:before\t<값> 和 after\t<값>(占位符为该值)。

--set profile= 选择组合,--set values.… 修改该组合中的某一个值。渲染出的 HPA 可以用 yq -N e 'select(.kind=="HorizontalPodAutoscaler")' 파일(占位符为文件名)取出来查看。before 只要从第 1 步已经提取好的文件中读取即可。

网格全局配置会被渲染成一个 ConfigMap

给 minimal profile 加上四项网格配置后渲染——meshConfig.outboundTrafficPolicy.mode 为 REGISTRY_ONLY,meshConfig.accessLogFile 为 /dev/stdout,meshConfig.trustDomain 为 lab.internal,meshConfig.defaultConfig.holdApplicationUntilProxyStarts 为 true。从渲染结果中只取出名称为 istio 的 ConfigMap 对象,保存到 /root/ist-profiles/mesh-cm.yaml,并把该 ConfigMap 的 data.mesh 字符串单独保存到 /root/ist-profiles/mesh.yaml。

MeshConfig 不是单独的 CRD,而是存放在 istio-system 的 ConfigMap istio 中 mesh 键里的一块 YAML。用 yq -N e 'select(.kind=="ConfigMap" and .metadata.name=="istio")' - 取出对象,用 .data.mesh 取出字符串。

在渲染阶段被拒绝的三种情况

故意出错三次,把报错的句子按顺序收集到 /root/ist-profiles/rejected.txt——(1)给 minimal profile 的 meshConfig.outboundTrafficPolicy.mode 设为 BLOCK_ALL;(2)用 --set profile=sidecarless 调用不存在的 profile;(3)像 --profile=minimal 这样以标志的形式给出 profile。标准错误也要一并写入。

三次都会以非 0 退出码结束。像 명령 >> rejected.txt 2>&1(占位符为要执行的命令)这样,把标准输出和标准错误追加到同一个文件即可。三者在不同的层被拦下——值的枚举、文件名和命令行语法。

只在一个命名空间中覆盖网格全局配置

创建命名空间 profile-lab,并在其中实际应用 ProxyConfig ns-default——spec.concurrency 为 2,在 spec.environmentVariables 中设置 ISTIO_META_LAB_TIER: "gold"。清单放在 /root/ist-profiles/proxyconfig.yaml 中。然后在 /root/ist-profiles/proxyconfig-negative.yaml 中把 ns-negative 写成 concurrency: -1,通过服务端试运行应用让它被拒绝,并把该拒绝的句子保存到 /root/ist-profiles/proxyconfig-reject.txt。

ProxyConfig 是 networking.istio.io/v1beta1 的 CRD,以命名空间或工作负载为单位覆盖 MeshConfig 的 defaultConfig。如果只想询问 API 服务器而不实际应用,使用 kubectl apply --dry-run=server。负数检查不是由 istioctl,而是由 CRD schema 完成的。

制作四种 profile 的组件对照表,并让它能自行验证

在 /root/ist-profiles/profile-matrix.tsv 中写入 <프로파일>\t<kind>|<이름>\t<yes|no>(占位符依次为 profile 名称、类型与名称、是否存在)——profile 必须包含 default、demo、minimal、ambient 四种,组件必须包含 Deployment|istiod、Deployment|istio-ingressgateway、Deployment|istio-egressgateway、DaemonSet|ztunnel、DaemonSet|istio-cni-node 五种(共二十行)。/root/ist-profiles/check-profiles.sh 读取这张表并重新渲染 profile,匹配时只向标准输出打印 OK …,不匹配时只向标准输出打印 MISMATCH …,只要有一行不匹配就必须以非 0 退出码结束。把它的输出保存到 /root/ist-profiles/matrix-result.txt。

同一个 profile 渲染多次会变慢——每个 profile 只渲染一次并放进临时文件,再重复使用。如果脚本直接修改学员的产出文件,评分器再次运行时数值会不同,所以只通过标准输出输出。