Istio CNI Helm Chart 深度指南:istio-cni 的安装、配置、Profile 机制与 Ambient/GKE 适配
本文基于 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-cni,Chart.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.yaml、clusterrolebinding.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.resourceScope 为 all 或 namespace 时才渲染 DaemonSet,ClusterRole 则要求 all 或 cluster。这是为"集群管理员与网格管理员分权"场景准备的:把值设为 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 提供方,可选 default 或 multus;multus 会额外创建 NetworkAttachmentDefinition |
这些值最终都被 configmap-cni.yaml 渲染为环境变量:CHAINED_CNI_PLUGIN、EXCLUDE_NAMESPACES、CNI_CONF_NAME、ISTIO_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_ENABLED、AMBIENT_DNS_CAPTURE、AMBIENT_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: delete;labelPods 使用更低权限的 pods/status: patch,update。DaemonSet 侧则通过 REPAIR_NODE_NAME、REPAIR_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 的一致性。优先级从高到低:
- 用户显式设置的值(
-f/--set) - profile 预设
- 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/files:profile-ambient.yaml、profile-demo.yaml、profile-preview.yaml、profile-stable.yaml、profile-remote.yaml、各profile-compatibility-version-1.2x.yaml,以及profile-platform-gke.yaml、profile-platform-openshift.yaml等平台预设。此外模板还支持独立的platform与compatibilityVersion两个维度,与 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/netns(HostToContainer传播)与/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-nodeDaemonSet 的spec.template.spec.containers.env中添加环境变量FELIX_WORKLOADSOURCESPOOFING=Any。其效果是:带指定 annotation 的 Pod 跳过 RPF 检查。
六、GKE 平台注意事项
README 的 GKE notes 只有两条,但每一条背后都有模板代码支撑:
kube-system命名空间在 GKE 上为强制要求(而非一般建议)。helm template场景必须显式--set cni.cniBinDir=/home/kubernetes/bin;helm 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 的核心操作链可以归纳为:
helm install istio-cni istio/cni -n kube-system(需要system-node-critical调度保障);- 用
helm show values istio/istio-cni查看参数,配置一律使用顶层字段(--set chained=false,而非--set defaults.chained=false或带_internal_defaults_do_not_set前缀); - 平台/场景适配:GKE 用
--set profile=gke或手动cniBinDir=/home/kubernetes/bin(helm template下必须手动);Ambient 用--set profile=ambient并按需处理 Calico 的 source spoofing;OpenShift 等不支持插件链的发行版将chained设为false; - 安装后用
helm status/helm get all验证,观察 DaemonSet 就绪与节点上 CNI 二进制/配置文件是否正确落盘; - 需要收紧安全面时,可开启
global.networkPolicy.enabled,并按平台调整seLinuxOptions、seccompProfile与 AppArmor 设置方式。
所有结论均可在仓库内直接溯源:Chart 模板位于 manifests/charts/istio-cni/templates,默认值与注释在 values.yaml,profile 合并逻辑在 zzz_profile.yaml,CNI 组件源码(含 repair 控制器、iptables/nftables 规则生成)位于 cni/pkg。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00