首页
/ Istio CNI Helm Chart 深度指南:istio-cni 的安装、配置、Profile 机制与 Ambient/GKE 适配

Istio CNI Helm Chart 深度指南:istio-cni 的安装、配置、Profile 机制与 Ambient/GKE 适配

2026-09-05 15:26:38作者:霍妲思

本文基于 Istio 仓库中的 istio-cni Chart README 及其配套模板、values 与源码展开,介绍如何用 Helm 安装 Istio CNI 插件、如何理解 Chart 的 profile 分层配置机制,以及如何为 Ambient 模式、GKE 等平台完成正确配置。读完本文,你将能够独立完成 istio/cni Chart 的安装与调参,并能对照源码理解 DaemonSet 的权限模型、ConfigMap 环境变量映射和修复控制器(repair)的三种工作模式。

一、这个 Chart 到底安装什么

istio-cni Chart 位于 manifests/charts/istio-cniChart.yaml 中定义其名称为 cni,描述为 "Helm chart for istio-cni components"。CNI(Container Network Interface)插件的作用是:在 Pod 创建时接管网络配置,直接改写节点的 iptables 规则,将 Pod 流量重定向到 sidecar/ztunnel,从而摆脱传统 Istio 依赖 iptables 在 init 容器(istio-init)里执行的方案,缩短 Pod 启动时间并规避 init 容器需要高权限的问题。

Chart 的 templates 目录渲染出以下资源:

资源 模板文件 说明
DaemonSet daemonset.yaml 每节点一个 install-cni 容器,负责向节点下发 CNI 二进制与配置文件
ConfigMap configmap-cni.yaml 把 values 中的 CNI 配置渲染为环境变量供 DaemonSet 消费
ClusterRole / Binding clusterrole.yamlclusterrolebinding.yaml 基础角色 + repair 角色 + ambient 角色,随功能开关裁剪
ServiceAccount serviceaccount.yaml DaemonSet 使用的服务账号
NetworkPolicy(可选) networkpolicy.yaml global.networkPolicy.enabled: true 时创建
ResourceQuota(可选) resourcequota.yaml resourceQuotas.enabled: true 时创建,GKE profile 默认开启
NetworkAttachmentDefinition(可选) network-attachment-definition.yaml 仅在 provider: multus 时创建

Chart 内所有默认值统一收敛在 values.yaml 中,后续各节会逐项讲解关键参数。

二、安装 Chart

2.1 添加 Helm 仓库

按照 README 的 Setup Repo Info:

helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update

2.2 执行安装

以发布名 istio-cni 安装:

helm install istio-cni istio/cni -n kube-system

为什么强烈建议安装在 kube-system:DaemonSet 模板中固定设置了 priorityClassName: system-node-critical(见 daemonset.yaml 第 88 行),该优先级类只对 kube-system 命名空间中的 Pod 生效——这也是 CNI 作为节点级关键组件(每个 Pod 启动都依赖它)能被优先调度的保障。如果集群策略允许在 kube-system 之外使用 system-node-critical,也可以安装到其他命名空间,但默认不推荐。

此外,模板开头有 resourceScope 门控(daemonset.yaml 第 1 行):只有 global.resourceScopeallnamespace 时才渲染 DaemonSet,ClusterRole 则要求 allcluster。这是为"集群管理员与网格管理员分权"场景准备的:把值设为 namespace 时,集群级资源需由管理员另行创建。

安装完成后,NOTES.txt 会提示用以下命令查看状态:

helm status istio-cni -n kube-system
helm get all istio-cni -n kube-system

2.3 查看支持的配置项

helm show values istio/istio-cni

三、核心配置参数详解(对照 values.yaml)

values.yaml 有一个特殊结构:所有默认值都嵌套在 _internal_defaults_do_not_set 之下,并附带醒目注释——这是为 Helm 无法在"内置默认值"与"用户输入"之间插入 profile 层所做的规避方案(详见第四节)。对用户而言,配置时直接写顶层字段即可,绝不能带 _internal_defaults_do_not_set 前缀,例如应传 --set chained=true 而不是 --set _internal_defaults_do_not_set.chained=true

3.1 CNI 路径与配置文件

参数 默认值 说明
cniBinDir /opt/cni/bin 放置 install-cni/插件二进制的节点目录,会作为 DaemonSet 的 hostPath 挂载点
cniConfDir /etc/cni/net.d CNI 配置文件目录
cniConfFileName "" 要写入的 CNI 配置文件名;默认取 conf 目录中找到的第一个文件,示例:10-calico.conflist
cniNetnsDir /var/run/netns 节点 netns 目录,Ambient 模式下以 HostToContainer 传播挂载
istioOwnedCNIConfig false 启用后由 Istio 托管 CNI 配置文件,文件名为 istioOwnedCNIConfigFileName(默认 02-istio-cni.conflist
excludeNamespaces ["kube-system"] 跳过注入/重定向的命名空间列表,会经 ConfigMap 以 EXCLUDE_NAMESPACES(逗号分隔)下发
chained true 以插件链(chained)方式写入配置,还是作为独立文件;部分发行版(如 OpenShift)不支持链式,需设为 false
provider default CNI 提供方,可选 defaultmultus;multus 会额外创建 NetworkAttachmentDefinition

这些值最终都被 configmap-cni.yaml 渲染为环境变量:CHAINED_CNI_PLUGINEXCLUDE_NAMESPACESCNI_CONF_NAMEISTIO_OWNED_CNI_CONFIG 等,DaemonSet 通过 envFrom.configMapRef 引入(daemonset.yaml 第 167-169 行)。值得注意的是,模板对 CNI_CONF_NAME 有条件渲染——"K8S < 1.24 doesn't like empty values"(第 23 行),即旧版 API Server 不接受空值,所以只在显式设置时输出。

3.2 Ambient 相关开关

ambient:
  enabled: false            # 是否启用 ambient 流量重定向
  enablementSelectors:      # 判定"ambient 生效"的 Pod/命名空间选择器
  - podSelector:
      matchLabels: {istio.io/dataplane-mode: ambient}
  - podSelector:
      matchExpressions:
      - { key: istio.io/dataplane-mode, operator: NotIn, values: [none] }
    namespaceSelector:
      matchLabels: {istio.io/dataplane-mode: ambient}
  configDir: ""             # ambient 配置目录,默认 /etc/ambient-config
  dnsCapture: true          # ambient 下的 DNS 重定向
  ipv6: true                # ambient 下的 IPv6 支持
  reconcileIptablesOnStartup: true   # 启动时调和节点上残留的冲突 iptables 规则
  shareHostNetworkNamespace: false   # 是否与宿主节点共享网络命名空间
  enableAmbientDetectionRetry: false # 检测 ambient Pod 出错时是否重试

这些值同样经 ConfigMap 映射为 AMBIENT_ENABLEDAMBIENT_DNS_CAPTUREAMBIENT_IPV6 等环境变量(configmap-cni.yaml 第 17-22 行)。

3.3 Repair(修复控制器)

repair:
  enabled: true
  # 三种互斥模式(只能选一种):
  labelPods: false    # 给坏 Pod 打 cni.istio.io/uninitialized=true 标签,由用户手动处理
  deletePods: false   # 直接删除坏 Pod,让其重新调度(授予 DaemonSet 删除任意 Pod 的权限)
  repairPods: true    # 默认:动态重放网络配置修复已启动的坏 Pod,无需额外 RBAC,
                      # 但依赖 securityContext 中的 SYS_ADMIN 等能力
  initContainerName: "istio-validation"
  brokenPodLabelKey: "cni.istio.io/uninitialized"
  brokenPodLabelValue: "true"

三模式的权限差异在 RBAC 模板中精确体现(clusterrole.yaml 第 26-57 行):repairPods 模式不申请任何额外权限(模板内注释 "No privileges needed");deletePods 增加 pods: deletelabelPods 使用更低权限的 pods/status: patch,update。DaemonSet 侧则通过 REPAIR_NODE_NAMEREPAIR_RUN_AS_DAEMON 等环境变量(daemonset.yaml 第 171-178 行)把修复控制器以守护方式拉起。修复能力本身由 cni/repair 包实现,二进制入口为 cni/cmd/install-cni/main.go(调用 cni/pkg/cmd 的 root command)。

3.4 安全与运行参数

参数 默认值 说明
seccompProfile {} 可设为 type: RuntimeDefault
seLinuxOptions {} 部分平台需要 type: spc_t
useAppArmorAnnotation true K8s 1.29 及更早版本需经 annotation 设置 AppArmor;1.30+ 可关闭,改由 securityContext.appArmorProfile 设置
resources cpu 100m / mem 100Mi install-cni 容器资源
tolerations NoSchedule/NoExecute/CriticalAddonsOnly 保证 DaemonSet 调度到所有节点
updateStrategy RollingUpdate, maxUnavailable: 1 DaemonSet 滚动更新策略
terminationGracePeriodSeconds 30 值调大可给 CNI 清理留更多时间,避免滚动更新时出现 "failed to find plugin istio-cni"
logging.level / global.logging.level info 控制 istio-cni-node 日志级别,映射为 --log_output_level 启动参数
logAsJson false 追加 --log_as_json 启动参数
global.nativeNftables false 启用 nftables 替代 iptables 规则(对应 tools/istio-nftables 组件)
global.networkPolicy.enabled false 是否创建默认 NetworkPolicy
resourceQuotas 关闭,pods: 5000 GKE 上启用,限制 system-node-critical Pod 数量
env {} 额外注入 Pod 的环境变量(也会写入 ConfigMap)

关于安全上下文的取舍,DaemonSet 模板中有完整的注释说明(daemonset.yaml 第 113-148 行):privileged 被显式置为 false,先 drop: [ALL],再按功能最小化添加 NET_ADMIN(ipset/路由表访问)、NET_RAW(修改 nat 表)、SYS_PTRACE(repair/ambient 需要描述 Pod 网络命名空间)、SYS_ADMIN(打开 /proc 下的网络命名空间以进入 Pod netns)、DAC_OVERRIDE(root 丢弃所有能力后仍能读写宿主目录)。

四、Profile:Istio Chart 的分层配置机制

README 对 profile 的定义是:一组打包好的值预设,通过 --set profile=<profile> 启用,例如 demo profile 提供面向测试环境的预设(更多功能开启、资源要求降低)。所有 Istio Chart 使用同一套 profile 名称,即使某个 profile 对某个 Chart 没有实际影响,以保证跨 Chart 的一致性。优先级从高到低:

  1. 用户显式设置的值(-f / --set
  2. profile 预设
  3. Chart 内置默认值

这套机制的实现就藏在 zzz_profile.yaml 中(文件名前缀 zzz_ 使其最后渲染、直接改写 .Values)。模板头部注释解释了动机:Helm 把"内置默认值"和"用户输入"合并成了同一个 .Values,无法在中间插入 profile 层。变通方案是把默认值全部塞进 _internal_defaults_do_not_set,然后按 默认值 ← profile ← 用户输入 的顺序做 mustMergeOverwrite 合并后写回 .Values第 24-56 行)。

两个实用细节:

  • 防护性报错:如果你误写了 --set defaults.xxx=... 这类前缀,模板会直接 fail 并打印你设置的所有默认值(第 18-23 行),而不是静默失效。
  • profile 文件的查找位置:模板按 files/profile-<name>.yaml 读取,不存在则报 "unknown profile"。该 chart 内置的 profile 可见于 manifests/charts/istio-cni/filesprofile-ambient.yamlprofile-demo.yamlprofile-preview.yamlprofile-stable.yamlprofile-remote.yaml、各 profile-compatibility-version-1.2x.yaml,以及 profile-platform-gke.yamlprofile-platform-openshift.yaml 等平台预设。此外模板还支持独立的 platformcompatibilityVersion 两个维度,与 profile 依次合并。

五、启用 Ambient 模式

5.1 使用 ambient profile

helm install istio-cni istio/cni -n kube-system --set profile=ambient

对应的 profile-ambient.yaml 对 CNI chart 的直接效果是 cni.ambient.enabled: true(同时它还会为 pilot 注入 PILOT_ENABLE_AMBIENT: "true"、设置 HBONE 元数据等,说明 ambient 需要 Pilot、CNI、ztunnel 三件套协同部署;顶层定义可见 manifests/profiles/ambient.yaml)。

启用后,DaemonSet 行为发生实质变化(均可在 daemonset.yaml 中逐条验证):

  • 额外挂载宿主的 /var/run/netnsHostToContainer 传播)与 /var/run/ztunnel第 219-225 行),cni-netns-dir 卷用 DirectoryOrCreate 类型,注释解释了原因:CNI 可能在首个非 hostNetwork Pod 出现前不会 bind mount 该目录,不能因此阻塞 Agent Pod 创建;
  • repairPods 或 ambient 任一开启时都会只读挂载宿主 /proc第 237-242 行),用于进入 Pod 网络命名空间;
  • 若同时设置 ambient.shareHostNetworkNamespace: true,Pod 转为 hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet,且不再注入 ALLOW_SWITCH_TO_HOST_NS第 73-76 行第 179-182 行);
  • 额外渲染一个 ambient 专用 ClusterRole(clusterrole.yaml 第 60-82 行),只允许 pods/status 的 patch/update 及读取本 DaemonSet。

5.2 使用 Calico 时的额外要求

README 特别指出,Calico 场景必须允许源地址伪造(source spoofing),否则 ambient 的重定向流量会被 RPF 检查丢弃:

  • operator 部署的 Calico
kubectl patch felixconfigurations default --type='json' -p='[{"op": "add", "path": "/spec/workloadSourceSpoofing", "value": "Any"}]'
  • manifest 部署的 Calico:在 calico-node DaemonSet 的 spec.template.spec.containers.env 中添加环境变量 FELIX_WORKLOADSOURCESPOOFING=Any。其效果是:带指定 annotation 的 Pod 跳过 RPF 检查。

六、GKE 平台注意事项

README 的 GKE notes 只有两条,但每一条背后都有模板代码支撑:

  1. kube-system 命名空间在 GKE 上为强制要求(而非一般建议)。
  2. helm template 场景必须显式 --set cni.cniBinDir=/home/kubernetes/binhelm install 则可自动检测。

自动检测逻辑在 daemonset.yaml 第 6-14 行:模板检查 .Capabilities.KubeVersion.GitVersion 是否包含 -gke,是则 cniBinDir 默认取 /home/kubernetes/bin,否则取 /opt/cni/bin;若用户显式设置了 cniBinDir,以用户值为准。helm template 在本地渲染时拿不到集群版本信息,检测退化为默认值,因此需要手动指定。

配套的 profile-platform-gke.yaml 则刻意把 cniBinDir 置为空字符串(注释写明 "intentionally unset for gke to allow template-based autodetection to work"),并开启 resourceQuotas.enabled: true——即 GKE 上会渲染出限制 system-node-critical 优先级 Pod 数量的 ResourceQuota

七、DaemonSet 的运行时画像

综合模板与 ConfigMap,可以完整描述 istio-cni-node 在节点上的形态:

  • 容器:单一 install-cni 容器,镜像默认 {{ global.hub }}/install-cni:{{ tag }}(当前仓库中镜像构建入口见 cni/docker/ 下各 Dockerfile;更完整的 CNI 文档见 cni/README.md);
  • 探针readinessProbe 请求 8000 端口 /readyz,metrics 监听 15014 端口并打上 prometheus.io/scrape: 'true' 注解;
  • 关键 hostPath:CNI bin 目录、/etc/cni/net.d/var/run/istio-cni(UDS 日志/ambient 事件通道)、/proc/var/run/netns
  • 监控GOMEMLIMIT 通过 resourceFieldRef 与内存上限联动,让 Go 运行时按限额回收内存。

NetworkPolicy(networkpolicy.yaml)启用后,只放行 15014(Prometheus)与 8000(readiness)的入站流量,出站全放行(注释说明 API Server 地址因发行版而异,暂不收紧)。

八、小结与验证清单

围绕 istio-cni README 的核心操作链可以归纳为:

  1. helm install istio-cni istio/cni -n kube-system(需要 system-node-critical 调度保障);
  2. helm show values istio/istio-cni 查看参数,配置一律使用顶层字段(--set chained=false,而非 --set defaults.chained=false 或带 _internal_defaults_do_not_set 前缀);
  3. 平台/场景适配:GKE 用 --set profile=gke 或手动 cniBinDir=/home/kubernetes/binhelm template 下必须手动);Ambient 用 --set profile=ambient 并按需处理 Calico 的 source spoofing;OpenShift 等不支持插件链的发行版将 chained 设为 false
  4. 安装后用 helm status / helm get all 验证,观察 DaemonSet 就绪与节点上 CNI 二进制/配置文件是否正确落盘;
  5. 需要收紧安全面时,可开启 global.networkPolicy.enabled,并按平台调整 seLinuxOptionsseccompProfile 与 AppArmor 设置方式。

所有结论均可在仓库内直接溯源:Chart 模板位于 manifests/charts/istio-cni/templates,默认值与注释在 values.yaml,profile 合并逻辑在 zzz_profile.yaml,CNI 组件源码(含 repair 控制器、iptables/nftables 规则生成)位于 cni/pkg

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