首页
/ Istio Helm Profiles 机制详解:内置配置集、三级合并原理与 copy-templates 打包流程

Istio Helm Profiles 机制详解:内置配置集、三级合并原理与 copy-templates 打包流程

2026-09-05 14:34:35作者:秋泉律Samson

Istio 的 Helm Profile 是一组可复用的 values 配置集,让你用一行 --set profile=demo--set platform=gke 就能切换整套安装配置。本文以 manifests/helm-profiles/README.md 为核心,结合 manifests/zzz_profile.yaml 合并模板与 Makefile.core.mkcopy-templates 目标,讲清 profile 的完整生命周期:它如何被选中、按什么优先级合并、如何随 chart 分发,以及修改后应如何重新生成。

什么是 Helm Profile

manifests/helm-profiles/ 目录提供了一组用于 Helm 安装的 "profiles"(配置档案)。根据 README.md 的说明,围绕 profile 有两类使用方式:

  1. 显式传参:用户可以像传任意 values 一样,直接通过 --values/-f 把某个 profile 文件传给 helm install
  2. 随 chart 内置分发:Istio 提供了一项机制,把 manifests/helm-profiles/ 下的全部文件打包进各 chart 的 files/ 目录,这样即使从远程 chart(远程仓库 URL)安装,用户也能直接 --set profile=xxx 选用,而无需本地存在这些 YAML 文件。README 指出该机制对应 copy-templates Makefile 目标和 manifests/zzz_profile.yaml 模板。

当前仓库中内置的 profile 一览:

文件 用途
stable.yaml 启用 admission control,限制只使用稳定的资源与字段
demo.yaml 面向非生产环境的体验配置:降低资源占用、默认开启若干演示功能、ingress 开放更多端口
ambient.yaml 启用 ambient 模式
remote.yaml 支持 remote control plane(远程控制面)安装
preview.yaml 探索实验性新功能的"尝鲜"配置
compatibility-version-1.25.yamlcompatibility-version-1.30.yaml 按旧版本行为回滚 1.25~1.30 各版本的破坏性行为变更
platform-gke.yamlplatform-k3d.yamlplatform-k3s.yamlplatform-microk8s.yamlplatform-minikube.yamlplatform-openshift.yaml 针对特定 Kubernetes 发行版/平台的适配配置
warning-edit.txt 复制进 chart 时自动前置的"勿直接编辑"警告头

与 IstioOperator profile 的关键区别

README 中有一个必须牢记的警告:IstioOperator profiles 不同,这些 Helm profile 不能启用或禁用某些组件(components)。因此即使用户选择了某个 profile,仍需自行保证安装了与该 profile 配套的正确 chart。例如:

  • remote.yaml 的首行注释明确要求 "The base and istio-discovery charts must be deployed with this profile";
  • ambient.yaml 的首行注释要求 "The Istiod, CNI, and ztunnel charts must be deployed"。

README 指出这类约束已记录在每个 profile 文件的注释中,选 profile 时应先阅读其头部说明。

内置 Profile 逐项解读

以下 YAML 内容直接取自仓库,均可作为 helm install -f 的 values 文件,或理解为 --set profile=xxx 时的实际生效值。

stable:收紧到"仅稳定字段"

stable.yaml 全文如下:

# The stable profile deploys admission control to ensure that only stable resources and fields are used
# THIS IS CURRENTLY EXPERIMENTAL AND SUBJECT TO CHANGE
experimental:
  stableValidationPolicy: true

它通过 experimental.stableValidationPolicy: true 部署一个 admission 校验策略,拒绝使用非稳定的 Istio 资源类型或字段。注意文件头明确标注该能力"目前为实验性质,可能随时变化"。

demo:面向演示与文档教程的低占用配置

demo.yaml 的文件头注释说明其目标:降低资源占用、默认开启一些演示功能(尤其是 istio.io 文档任务用到的功能)、ingress 上开放更多端口。核心内容包括三块:

  1. 访问日志与遥测扩展。将 meshConfig.accessLogFile 指向 /dev/stdout,并声明四个 extensionProviders
meshConfig:
  accessLogFile: /dev/stdout
  extensionProviders:
    - name: otel
      envoyOtelAls:
        service: opentelemetry-collector.observability.svc.cluster.local
        port: 4317
    - name: skywalking
      skywalking:
        service: tracing.istio-system.svc.cluster.local
        port: 11800
    - name: otel-tracing
      opentelemetry:
        port: 4317
        service: opentelemetry-collector.observability.svc.cluster.local
    - name: jaeger
      opentelemetry:
        port: 4317
        service: jaeger-collector.istio-system.svc.cluster.local
  1. 全面调低资源请求。CNI、ztunnel、sidecar proxy、waypoint、pilot、两个 gateway 的 resources.requests 均压到 cpu: 10m / memory: 40Mi 左右(pilot 为 100Mi),并关闭 pilot 与 ingress/egress gateway 的 autoscaleEnabledpilot.traceSampling 设为 100:
cni:
  resources:
    requests:
      cpu: 10m
      memory: 40Mi
pilot:
  autoscaleEnabled: false
  traceSampling: 100
  resources:
    requests:
      cpu: 10m
      memory: 100Mi
  1. ingress 开放更多端口gateways.istio-ingressgateway.ports 显式列出 15021/status-port80(http2)443(https)31400(tcp)15443(tls,SNI 路由端口) 五个端口。文件内注释特别提醒:helm 对列表是"整体替换"而非合并,用户若要自定义端口,必须在 override 中包含 profile 里已有的全部端口;同时注释引用了 AWS ELB 会对该列表第一个端口做健康检查的背景(对应 issue #12503),因此把 15021 的 status-port 放在首位。

ambient:启用 ambient 模式

ambient.yaml 全文:

# The ambient profile enables ambient mode. The Istiod, CNI, and ztunnel charts must be deployed
meshConfig:
  defaultConfig:
    proxyMetadata:
      ISTIO_META_ENABLE_HBONE: "true"
  serviceScopeConfigs:
    - servicesSelector:
        matchExpressions:
          - key: istio.io/global
            operator: In
            values: ["true"]
      scope: GLOBAL
global:
  variant: distroless
pilot:
  env:
    PILOT_ENABLE_AMBIENT: "true"
cni:
  ambient:
    enabled: true

逐条看其作用:

  • ISTIO_META_ENABLE_HBONE: "true" 通过 proxy 元数据开启 HBONE(HTTP-based Overlay Network Encryption),即 ambient 模式的隧道基础;
  • serviceScopeConfigs 将带 istio.io/global=true 标签的服务设为 GLOBAL scope;
  • global.variant: distroless 选用 distroless 代理变体;
  • PILOT_ENABLE_AMBIENT 让 istiod 处理 ambient 相关资源;
  • cni.ambient.enabled: true 让 CNI 组件接管 ztunnel 的注入与网络配置。

再次注意:该 profile 只改配置,不会替你部署 istiod/CNI/ztunnel 这些 chart,这正是上一节警告的实例。

remote:远程控制面

remote.yaml 全文:

# The remote profile enables installing istio with a remote control plane. The `base` and `istio-discovery` charts must be deployed with this profile.
istiodRemote:
  enabled: true
configMap: false
telemetry:
  enabled: false
global:
  # TODO BML maybe a different profile for a configcluster/revisit this
  omitSidecarInjectorConfigMap: true

它把本地控制面关掉(configMap: falsetelemetry.enabled: false),通过 istiodRemote.enabled: true 指向远端 istiod,并用 global.omitSidecarInjectorConfigMap 省略本地 sidecar 注入配置。注释中的 TODO 表明"为 configcluster 单独出 profile"仍是作者留待重新设计的事项。

preview:实验特性入口

preview.yaml 声明"包含实验特性,不保证稳定性、安全性与性能,使用风险自负",当前内容为:

meshConfig:
  defaultConfig:
    proxyMetadata:
      # Enable Istio agent to handle DNS requests for known hosts
      # Unknown hosts will automatically be resolved using upstream dns servers in resolv.conf
      ISTIO_META_DNS_CAPTURE: "true"

即默认开启 istio-agent 对已知主机的 DNS 处理(未知主机自动回落到 resolv.conf 上游 DNS)。这是一个典型的"新特性先在 preview 落地、成熟后再进默认值"的演进通道。

compatibility-version-*:行为版本回滚

compatibility-version-1.30.yaml 展示了这类 profile 的形态——通过 pilot 环境变量把新版本的行为拉回旧版本:

pilot:
  env:
    # 1.31 behavioral changes
    PILOT_ENABLE_STRICT_GATEWAY_MERGING: "false"
    PILOT_SPAWN_UPSTREAM_SPAN_FOR_GATEWAY: "false"
    PILOT_AUTO_SEND_UNHEALTHY_ENDPOINTS: "false"

从 1.25 到 1.30 各文件结构相同:每升一个版本,就把该版本引入的行为变更环境变量置为旧值,从而让升级后的控制面保持旧版本行为。它与 profile 参数不是二选一的关系——在合并模板中,compatibilityVersion 是独立于 profile 的第二层叠加(见下一节),即"选一个功能 profile + 锁定一个行为版本"可以共存。

platform-*:平台适配

  • platform-openshift.yaml:开启 global.nativeNftables: true;CNI 使用 multus provider(cniBinDir: /var/lib/cni/bincniConfDir: /etc/cni/multus/net.dchained: falseprovider: "multus",pilot 侧 cni.provider 同步);seLinuxOptions.type: spc_t;注释说明 OpenShift 要求特权 pod 运行在 kube-system,因此 trustedZtunnelNamespace: "kube-system"
  • platform-gke.yamlcni.cniBinDir: "" 被有意留空,注释解释这是为了让 GKE 上"基于模板的自动检测"正常工作;同时开启 cni.resourceQuotas 与全局 resourceQuotas(GKE 要求资源配额相关设置)。
  • platform-k3s.yaml:仅两行,把 CNI 目录指到 k3s 的位置——cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.dcniBinDir: /bin

合并原理:zzz_profile.yaml 的三级优先级

用户执行 helm install --set profile=stable 时,真正生效的合并逻辑在各 chart 的 templates/zzz_profile.yaml(由 manifests/zzz_profile.yaml 生成)。该模板头注释把值来源归纳为三个集合,按"后者胜出"排序:

  1. chart 内置的 values.yaml 默认值;
  2. 用户选定的 profile;
  3. 用户的输入(-f--set)。

难点在于 Helm 把 (1) 和 (3) 合并后作为同一个 .Values 交给模板,profile (2) 无法直接插入中间。模板给出的绕法是:把所有内置默认值放在一个专用键 _internal_defaults_do_not_set 下(从 .Values 中剥离),依次执行 mustMergeOverwrite

defaults → 叠加 profile → 再叠加用户 Values

模板关键片段(摘自 manifests/zzz_profile.yaml):

{{- $defaults := $.Values._internal_defaults_do_not_set }}
{{- $_ := unset $.Values "_internal_defaults_do_not_set" }}
{{- $profile := dict }}
{{- with (coalesce ($.Values).profile ($.Values.global).profile) }}
{{- with $.Files.Get (printf "files/profile-%s.yaml" .)}}
{{- $profile = (. | fromYaml) }}
{{- else }}
{{- fail (cat "unknown profile" .) }}
{{- end }}
{{- end }}

从中可以看出三个机制细节:

  • profile 名即文件名--set profile=stable 会去读 files/profile-stable.yaml,找不到直接 fail "unknown profile"——这是错拼 profile 名时报错的来源;
  • profileglobal.profile 等价coalesce 先取顶层 profile,再回退到 global.profile(兼容旧写法);
  • compatibilityVersionplatform 是两条独立的叠加链,分别读 files/profile-compatibility-version-<ver>.yamlfiles/profile-platform-<platform>.yaml,均以 mustMergeOverwrite 叠加到 $profile 上,且各自的未知取值都会 fail。最终顺序可归纳为:内置默认值 < 功能 profile < compatibilityVersion < platform < 用户 -f/--set

模板还有一段防御逻辑:如果用户显式设置了 .Values.defaults.*,会直接 fail 并提示把 --set defaults.hub=foo 改成 --set hub=foo,防止业务键误用保留命名空间。对 ztunnel 与 gateway 两个 chart,生成时 FLATTEN_GLOBALS_REPLACEMENT 被替换为 true,会把 $profile.global 扁平化合并进全局值,以适配这两个 chart 不按 chart 级划分 global 的结构。

打包流程:make copy-templates

README.md 要求"对该目录的任何修改,之后都应执行 make copy-templates"。该目标定义在 Makefile.core.mk,其逻辑为:

  1. 定义 chart 清单CHARTS = gateway default ztunnel base "gateways/istio-ingress" "gateways/istio-egress" "istio-control/istio-discovery" istio-cni,即 profile 会被分发到全部七个 chart;
  2. 同步 egress gateway 模板:把 istio-ingress 的 templates 复制到 istio-egress 并用 sed 做 ingress→egress 的命名替换(这部分与 profile 无关,但同属该目标);
  3. 复制 profile:清空各 chart 的 files/profile-*.yaml 后,遍历 manifests/helm-profiles/*.yaml,每个文件头部插入 warning-edit.txt 的内容("WARNING: DO NOT EDIT, THIS FILE IS A COPY……run 'make gen'"),再写入 manifests/charts/$chart/files/profile-<basename>
  4. 生成合并模板:把 manifests/zzz_profile.yaml 按 chart 复制为 templates/zzz_profile.yaml,其中 FLATTEN_GLOBALS_REPLACEMENT 对 ztunnel/gateway chart 替换为 true,其余替换为 false

copy-templates 同时是 gen 目标的一部分(Makefile.core.mkgen: 依赖 copy-templates),因此完整的生成链路是 make gen(内部还会执行 rm manifests/charts/.../profile-*.yaml 再重建,保证删除旧 profile 后不残留)。这也解释了仓库中为什么每个 chart 的 files/ 目录里都有一整套 profile-*.yaml 副本:它们是构建期产物,只应修改 manifests/helm-profiles/ 下的原件

使用方法

基于上述机制,三类典型用法如下(均以从仓库/远程 chart 安装为前提):

# 1. 选用功能 profile:读 files/profile-demo.yaml 并叠加到默认值之上
istioctl install --set profile=demo

# 2. 叠加平台适配与行为版本(可与 profile 共存,顺序:profile < compatibilityVersion < platform < 显式 --set)
istioctl install --set profile=demo --set platform=gke --set compatibilityVersion=1.30

# 3. 不经过内置分发,直接把 profile 文件当 values 传给 helm
helm install istio base -f manifests/helm-profiles/stable.yaml

注意事项与适用前提:

  • profile 只能覆盖已有 values 键的取值,不能增删组件;remote 需 base + istio-discovery,ambient 需 istiod + CNI + ztunnel,见各文件头部注释;
  • stable profile 标注为实验特性;preview profile 明确不承诺稳定性;
  • 列表型值(如 demo 的 ingress ports)会被整体替换,自定义时须携带 profile 中的完整列表;
  • profile 内容随当前仓库版本演进,跨大版本升级时应重新核对所用 profile 的注释与默认行为(compatibility-version-* 正是为此提供的回退手段,且当前仓库只覆盖到 1.30)。

小结

Istio 的 Helm profile 机制由三部分构成:manifests/helm-profiles/ 下的可编辑原件(含 stable/demo/ambient/remote/preview、compatibility-version-1.25~1.30 与六个 platform-* 配置)、copy-templates 目标驱动的 chart 内分发(每个 chart 的 files/profile-*.yaml 副本加 warning-edit.txt 警告头)、以及 zzz_profile.yaml 生成的三级合并模板(内置默认值 < profile < compatibilityVersion < platform < 用户输入)。理解了这条链路,你就能安全地选用现成 profile、按平台/版本精确叠加配置,也知道修改 profile 后必须重新运行 make copy-templates(或 make gen)才能让 chart 内的副本保持同步。

登录后查看全文
热门项目推荐
相关项目推荐