这篇讲什么

上一篇讲了 Service Mesh 该不该上。这篇把 Istio Ambient 跑通到可验收:先用节点级 ztunnel 拿到 L4 mTLS,需要 HTTP 路由、重试、金丝雀时再为目的服务部署 waypoint。业务 Pod 不注入 sidecar,也不用重启。控制平面仍是 istiod,数据平面换成「ztunnel + 按需 Envoy」。

先抓住这三点

  • 安装用 profile=ambient。同一命名空间不要同时打 istio-injection=enabledistio.io/dataplane-mode=ambient,冲突时 sidecar 优先。
  • 打上 istio.io/dataplane-mode=ambient 就进了网格:立刻有 mTLS 和 TCP 指标。没部署 waypoint,就没有 HTTP 级路由、重试和 L7 鉴权。
  • waypoint 是目的端网关。istio.io/use-waypoint 只表意图;waypoint 不存在或类型不匹配时,ztunnel 会直连目的,L7 策略不生效。

安装

Kubernetes 用 1.32+,Istio 用 1.31+。先装好 Gateway API CRD,再装 ambient profile:

kubectl get crd gateways.gateway.networking.k8s.io \
  || kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.0/experimental-install.yaml

curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH

istioctl install --set profile=ambient --skip-confirmation
istioctl verify-install

装完应该看到 istiod、istio-cni、ztunnel。少了 CNI 或 ztunnel 不要往下走。istio-system 不要打 ambient 标签。

把工作负载加进网格

以 Bookinfo 为例。先部署应用,再给命名空间打标签,不用重启 Pod

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f samples/bookinfo/platform/kube/bookinfo-versions.yaml

kubectl label namespace default istio.io/dataplane-mode=ambient
kubectl get pods

Pod 仍是 1/1,不会多出一个 sidecar 容器。此时服务间已经走 HBONE/mTLS。用 Kiali 看 Security 图也能确认锁标记;不想装仪表盘就看 ztunnel 日志。

kubectl -n istio-system logs ds/ztunnel --tail=50
istioctl experimental ztunnel-config services

L7 才上 waypoint

ztunnel 只做 L4。重试、超时、金丝雀、按 Header 的鉴权、HTTP 指标,都要 waypoint。建议先给整个命名空间 enroll,再给热点服务独立 waypoint:

istioctl waypoint apply -n default --enroll-namespace
kubectl get gateway
kubectl get ns default --show-labels

生成的 Gateway 的 gatewayClassName 必须是 istio-waypoint,监听 15008/HBONE。默认 istio.io/waypoint-for=service,只接打到 Service 的流量;Prometheus 直打 Pod IP 的抓取不会走这个 waypoint。

金丝雀怎么切

Ambient 下用 Gateway API 的 HTTPRoute,parentRefs 挂到 Kubernetes Service,不是挂到入口 Gateway。没有 waypoint 时这条路由不会生效:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
spec:
  parentRefs:
    - group: ""
      kind: Service
      name: reviews
      port: 9080
  rules:
    - backendRefs:
        - name: reviews-v1
          port: 9080
          weight: 90
        - name: reviews-v2
          port: 9080
          weight: 10

入口网关到 Service 的流量默认不走目的 waypoint。要让金丝雀对外也生效,给 Service 打 istio.io/ingress-use-waypoint=true,并确认 istiod 开了 ENABLE_INGRESS_WAYPOINT_ROUTING。这会变成入口 + waypoint 两跳 L7,延迟和鉴权都要按两层算。

怎么确认没配错

  • istioctl analyze 没有 Error。
  • Pod 仍是 1/1,命名空间能看到 istio.io/dataplane-mode=ambient
  • 有 waypoint 时,Service 上有 istio.io/use-waypoint,Gateway PROGRAMMED=True
  • L4 阶段能在 Kiali 看到 mTLS;L7 阶段才有 HTTP 状态码和重试指标。
  • 出问题先看 ztunnel 与 waypoint Pod 日志,不要只翻业务日志。

常见坑

  1. 同一命名空间混用 sidecar 注入与 ambient。sidecar 会抢过去,排障会变成「我明明打了 ambient」。
  2. 以为有了 HTTPRoute 就能金丝雀。没 enroll waypoint,路由不生效。waypoint 名字写错或只处理 service 却有人直连 Pod IP,同样被 ztunnel 绕过。
  3. 安全上要强制走 waypoint 时,光靠标签不够。用 AuthorizationPolicy 只放行 waypoint 的 ServiceAccount,ztunnel 在 L4 拦掉绕过。
  4. PeerAuthenticationSTRICT 会拒绝网格外流量。探活、批处理 Job、网格外客户端要先划进网格或给出例外。
  5. 重试没有预算会把局部故障放大成雪崩。先调超时和重试次数,再开全站 mTLS STRICT。
  6. 和 Cilium 网格、其他 CNI 插队叠加。Ambient 依赖 Istio CNI,上线前先核对平台是否明确支持这种组合。

什么时候用

新集群、多语言服务、要统一 mTLS 时,优先 Ambient。已有 sidecar 网格可以按命名空间混跑,不要一天切完。只想自动加密就停在 ztunnel;真正要 HTTP 金丝雀再给那个服务加 waypoint。十来个 Java 服务、已有 Spring Cloud Gateway 的,先别上。上线顺序仍然是:观测 → 超时重试 → mTLS STRICT。