[Istio] 咦?我的 istio-proxy 去哪儿了?🧐 – Kubernetes 原生 Sidecar 全解析

大家好!今天,我们将深入探讨一个可能让使用 Kubernetes 和 Istio 环境的工程师们都遇到过的情况——“消失的 Sidecar 容器之谜”

如果你注入了 Istio,但在 YAML 文件中看不到代理容器,而 `kubectl` 命令却显示正常?这并非 Bug。这正是 Kubernetes 原生 Sidecar 功能在起作用。让我们来详细了解一下这个变化为何发生,以及它带来了哪些改进。🚀

image


1. 事件的开端:“容器数量不对劲” 🤔

在 Istio 环境中部署 Pod 时,通常会达到 2/2 的状态。

  1. 你自己创建的应用程序容器
  2. Istio 注入的代理容器 (istio-proxy)

然而,如果你查看最近版本(Istio 1.27+、K8s 1.29+)部署的 Pod 的 YAML,你会发现一个奇怪的现象。

$ kubectl get pod details-v1
NAME                            READY   STATUS    RESTARTS   AGE
details-v1-766844796b-zmr86     2/2     Running   0          5m

👉 `kubectl` 命令明确显示为 READY 2/2,这意味着有两个容器正在正常运行。

但是,如果你使用 `kubectl get pod details-v1 -o yaml` 查看其配置呢?

spec:
  containers:
  - name: details  # <--- 咦?只有一个容器?
    image: docker.io/istio/examples-bookinfo-details-v1:1.20.3
    ...

`spec.containers` 部分缺少了 `istio-proxy`! 它明明在运行,却不在 YAML 定义中,这神秘的情况究竟是怎么回事?


2. 罪魁祸首藏在 ‘initContainers’ 中!🕵️‍♂️

答案不在 `spec.containers` 中,而在于 `spec.initContainers` 部分。仔细查看你提供的 YAML 文件,秘密就会揭晓。

  initContainers:
  - name: istio-init
    image: docker.io/istio/proxyv2:1.28.1
    # ... (设置 iptables 的常规 init 容器) ...

  - name: istio-proxy  # <--- 它藏在这里!
    image: docker.io/istio/proxyv2:1.28.1
    restartPolicy: Always  # <--- ⭐ 关键点 ⭐

传统上,`initContainers` 应该在主应用程序启动前只执行“初始化”任务,然后退出(Completed)。但在这里,我们看到了 `istio-proxy`,而且它并没有退出,而是持续运行。

其秘诀就在于 `restartPolicy: Always` 这个设置。


3. 什么是 Kubernetes 原生 Sidecar?💡

这是自 Kubernetes v1.28 (Alpha) / v1.29 (Beta, 默认) 起引入的 SidecarContainers 功能。

旧方式 (Old Sidecar)

以前,`istio-proxy` 会被包含在常规的 `containers` 列表中。但这种方式存在致命缺点:

  • 无法保证启动顺序:应用程序可能比代理先启动,导致尝试网络通信时失败。
  • 终止顺序问题 (Job):批处理任务(Job)完成后,Sidecar `istio-proxy` 却不退出,导致 Pod 永远停留在 Running 状态。

当前方式 (Native Sidecar)

现在,Kubernetes 会将 `initContainers` 中设置了 `restartPolicy: Always` 的容器识别为“Sidecar 容器”

  1. 最先启动:保证比主应用容器更早启动。
  2. 持续运行:初始化后不会退出,而是与主应用的生命周期保持一致。
  3. 最后终止:当主应用终止时,Kubernetes 会自动关闭 Sidecar。(解决了 Job 的问题!)

4. 为什么突然改变了?(版本历史)📅

这个变化是随着 Istio 和 Kubernetes 版本升级而自然发生的。

  • Istio 1.27 之前:原生 Sidecar 功能存在,但需要手动开启。(需要设置 ENABLE_NATIVE_SIDECARS=true)
  • Istio 1.27 之后:此功能成为默认值 (Default)
  • Kubernetes 要求:集群版本必须是v1.29 或更高。(GKE、EKS 等最新版本大多满足此要求)

你当前的环境是“Istio 1.27 及以上 + K8s 1.29 及以上”的组合,因此无需额外配置,这种最新的架构就会自动应用。🎉


5. 重新理解 2/2 的含义 🔢

现在,`kubectl get pod` 的 2/2 是如何计算的就变得清晰了。

  1. 主容器 (details):定义在 `spec.containers` 中 ➡️ +1
  2. 原生 Sidecar (istio-proxy):位于 `spec.initContainers` 中,但设置了 `restartPolicy: Always` ➡️ +1
  3. 常规 Init (istio-init):完成任务后退出(Completed) ➡️ 0

因此,总数为 2。这是一个完全正常且健康的状态,请放心!


6. 总结与结语 📝

这个变化不仅仅是结构上的调整,它是一个非常受欢迎的更新,从根本上解决了长期困扰 Kubernetes 工程师的“Sidecar 生命周期问题 (Lifecycle Issue)”

  • YAML 的 containers 中没有代理? 👉 请检查 `initContainers`。
  • 看到了 `restartPolicy: Always`? 👉 恭喜你!你正在使用最新的原生 Sidecar 功能。
  • 运行 Job(批处理)工作负载时:现在不再需要 `quitquitquit` 之类的技巧来确保代理干净地终止。

各位使用最新技术栈的朋友们,请不要被变化的 YAML 结构所困扰,尽情享受这个强大的功能吧!祝大家今天也有愉快云端航行!⛵️☁️



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注