2. Service Mesh 控制面与数据面

理解 OpenShift Service Mesh 的治理能力,第一步不是记住 CRD 名称,而是把“谁下发规则、谁执行规则、规则如何进入 Pod”这条链路拆清楚。Service Mesh 在逻辑上分为控制面与数据面:控制面负责配置的接收、校验、转换与分发;数据面负责在真实业务流量路径上执行路由、负载均衡、mTLS、遥测采集等动作。OpenShift 上的 Service Mesh 由上游 Istio 与 Envoy 组合实现,并通过 Operator 与 Sidecar 注入机制完成平台化集成。

控制面:Istio 的配置中枢

控制面的核心组件是 istiod。它并不是一个“转发流量的代理”,而是配置与证书的分发中心。管理员通过 Kubernetes 或 OpenShift 的 CRD 声明期望状态,例如 VirtualService 描述路由规则、DestinationRule 描述目标子集与连接策略、PeerAuthentication 描述 mTLS 模式、Gateway 描述入口监听。istiod 监听这些资源,完成校验、合并与转换后,通过 xDS 协议(如 LDS、RDS、CDS、EDS、SDS)下发给数据面代理。

控制面还承担证书签发职责。在启用 mTLS 时,istiod 内置 CA 为每个工作负载签发身份证书,证书中的 SPIFFE 身份形如 spiffe://cluster.local/ns/<namespace>/sa/<serviceaccount>。这意味着网格内的身份绑定到 ServiceAccount,而不是 IP 或主机名,为跨命名空间、跨集群的零信任通信提供基础。

数据面:Envoy 与 Sidecar 的工作方式

数据面由 Envoy 代理构成。Envoy 是一个高性能 L4/L7 代理,支持 HTTP/2、gRPC、TCP,具备动态配置、熔断、重试、超时、流量镜像、指标采集等能力。在 Sidecar 模式下,每个业务 Pod 内会注入一个 Envoy 容器,与业务容器共享网络命名空间。业务容器的入站和出站流量被 iptables 规则重定向到 Envoy:入站流量默认进入 15006 端口,出站流量默认进入 15001 端口,Envoy 再根据 xDS 下发的监听器、路由和集群配置决定如何处理。

Envoy 还暴露管理端口 15000 和指标端口 15090。运维人员可以通过 istioctl proxy-config 或 Envoy 管理接口查看当前生效的 listener、route、cluster、endpoint,从而判断配置是否真正下发到数据面。这一点在排障时非常关键:控制面资源存在,不代表数据面已经生效。

OpenShift Service Mesh:控制面 → 数据面 → 业务流量路径 控制面(istiod) CRD 监听:VirtualService / DestinationRule 校验 / 合并 / 转换为 xDS 配置 CA 签发 SPIFFE 身份证书 LDS / RDS / CDS / EDS / SDS xDS 下发 数据面 Pod(共享网络命名空间) 业务容器 监听 :8080 应用逻辑 不感知网格 ServiceAccount 身份 Envoy Sidecar 入站 :15006 出站 :15001 管理 :15000 指标 :15090 iptables 重定向:业务流量透明劫持至 Envoy 业务流量路径与治理动作 客户端 发起请求 源 Envoy 路由 / 重试 / mTLS 目标 Envoy 鉴权 / 遥测 / 熔断 业务容器 处理请求 治理动作在 Envoy 内执行:路由、负载均衡、mTLS、重试、超时、熔断、指标采集 控制面只下发配置,不参与业务数据转发

Sidecar 注入机制:自动与手动

Sidecar 注入决定了一个 Pod 是否进入网格。OpenShift Service Mesh 支持两种方式:自动注入与手动注入。自动注入依赖命名空间标签 istio-injection=enabled(或 istio.io/rev=<revision>),当 Pod 创建时,MutatingAdmissionWebhook 会拦截 Pod 定义,向其中插入 Envoy 容器、init 容器和卷。init 容器负责写入 iptables 规则,Envoy 容器负责代理流量。

手动注入则通过 istioctl kube-inject 生成注入后的 YAML,再提交给集群。手动注入适合需要精确控制注入内容、或命名空间不便打标签的场景。无论哪种方式,注入结果都可以用以下命令验证:

# 查看命名空间是否启用自动注入
oc get namespace my-app --show-labels

# 查看 Pod 内是否包含 istio-proxy 容器
oc get pod -n my-app -o jsonpath='{.items[*].spec.containers[*].name}'

# 查看 Envoy 当前生效的监听器与路由
istioctl proxy-config listener deploy/my-app -n my-app
istioctl proxy-config route deploy/my-app -n my-app

如果 istio-proxy 未出现,通常说明命名空间标签缺失、注入 Webhook 未就绪,或 Pod 使用了 hostNetwork 等不兼容配置。此时应先检查 istiod 与注入 Webhook 的状态,而不是直接修改业务 Deployment。

OpenShift 集成架构:Operator 与平台能力

在 OpenShift 上,Service Mesh 不是手工安装 Istio,而是通过 ServiceMeshControlPlane(SMCP)与 ServiceMeshMemberRoll(SMMR)两个核心资源进行平台化集成。SMCP 定义控制面版本、组件副本数、资源限制、mTLS 模式、追踪与遥测配置;SMMR 则声明哪些命名空间加入网格。Operator 监听这些资源,自动部署 istiod、Ingress/Egress Gateway,并维护注入 Webhook 与证书轮换。

这种集成方式带来两个实际好处:第一,控制面生命周期由 Operator 管理,升级、扩缩容、证书轮换可声明式完成;第二,网格成员关系与 OpenShift 命名空间模型对齐,便于多租户隔离。典型配置如下:

apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
metadata:
  name: basic
  namespace: istio-system
spec:
  version: v2.6
  security:
    dataPlane:
      mtls: true
  tracing:
    type: Jaeger
    sampling: 10000

apiVersion: maistra.io/v1
kind: ServiceMeshMemberRoll
metadata:
  name: default
  namespace: istio-system
spec:
  members:
    - my-app
    - payment

当 SMCP 就绪后,istio-system 中会出现 istiod、istio-ingressgateway、istio-egressgateway 等工作负载。此时将业务命名空间加入 SMMR,并确保其带有注入标签,新创建的 Pod 才会自动携带 Envoy Sidecar。判断网格是否真正生效,可以观察三个信号:Pod 内出现 istio-proxy、Envoy 配置中能看到目标服务的 cluster 与 route、以及 Kiali 或 Prometheus 中出现对应服务的流量指标。

控制面与数据面的职责边界可以概括为:istiod 决定“应该怎样”,Envoy 决定“实际怎样”。排障时先确认控制面资源是否被 istiod 接受,再确认数据面是否收到并应用了对应 xDS 配置,最后才检查业务容器本身。

关键判断与常见误区

一个常见误区是认为“创建了 VirtualService 就一定生效”。实际上,VirtualService 必须绑定到正确的 Gateway 或 Sidecar 作用域,且目标主机必须存在于网格内。如果目标服务未注入 Sidecar,或者命名空间未加入 SMMR,路由规则不会在数据面生效。另一个误区是忽略 mTLS 模式冲突:如果 PeerAuthentication 设置为 STRICT,而调用方未注入 Sidecar,则连接会被拒绝。此时应检查调用方是否在网格内,或临时将模式调整为 PERMISSIVE 进行验证。

从治理工程角度看,控制面与数据面的分离带来了可观测性与策略一致性,但也引入了配置传播延迟与排障复杂度。建议在变更后使用 istioctl analyze 检查配置冲突,并结合 Envoy 管理接口确认实际生效状态。只有把“声明—下发—执行—观测”四个环节都验证到位,Service Mesh 的治理能力才真正落地。