配置 waypoint 代理

waypoint 代理是基于 Envoy 代理的可选部署,用于将 Layer 7(L7)处理添加到一组定义的工作负载中。

waypoint 代理的安装、升级和扩缩独立于应用;应用所有者不会感知到它们的存在。 与每个工作负载并行运行 Envoy 代理实例的 Sidecar 数据平面模式相比, 所需的代理数量可以大大减少。

一个或一组 waypoint 可以在具有相似安全边界的应用之间共享。 这可能是特定工作负载的所有实例,或者命名空间中的所有工作负载。

Sidecar 模式相比,在 Ambient 模式下, 策略由目标 waypoint 强制执行。在许多方面,waypoint 充当资源(命名空间、服务或 Pod)的网关。 Istio 强制所有进入资源的流量都经过 waypoint,然后 waypoint 强制执行该资源的所有策略。

您需要 waypoint 代理吗?

Ambient 的分层方法允许用户以更细致的递进方式采用 Istio, 从无网格平滑过渡到安全的 L4 覆盖,再到完整的 L7 处理。

Ambient 模式的大部分功能都是由 ztunnel 节点代理提供的。 ztunnel 的范围仅限于处理 Layer 4(L4)的流量,因此它可以作为共享组件安全地运行。

当您配置重定向到某个 waypoint 时,流量将由 ztunnel 转发到该 waypoint。 如果您的应用需要以下任一 L7 网格功能,您将需要使用 waypoint 代理:

  • 流量管理:HTTP 路由和负载均衡、熔断、限流、故障注入、重试、超时
  • 安全性:基于请求类型或 HTTP 头等 L7 原装特性的丰富授权策略
  • 可观察性:HTTP 指标、访问日志、链路追踪

部署 waypoint 代理

waypoint 代理是使用 Kubernetes Gateway 资源部署的。

请注意,Kubernetes Gateway API CRD 不会默认安装在大多数 Kubernetes 集群上, 因此请确保在使用 Gateway API 之前已安装好这些 CRD:

$ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
  kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.0/standard-install.yaml

您可以使用 istioctl waypoint 子命令来生成、应用或列出这些资源。

部署 waypoint 后,整个命名空间(或您选择的任何服务或 Pod)必须先进行注册才能使用。

您在为特定命名空间部署 waypoint 代理之前, 请先确认该命名空间带有 istio.io/dataplane-mode: ambient 标签:

$ kubectl get ns -L istio.io/dataplane-mode
NAME              STATUS   AGE   DATAPLANE-MODE
istio-system      Active   24h
default           Active   24h   ambient

istioctl 可以为 waypoint 代理生成 Kubernetes Gateway 资源。 例如,要为 default 命名空间生成名为 waypoint 的 waypoint 代理,该代理可以处理命名空间中这些服务的流量:

$ istioctl waypoint generate --for service -n default
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  labels:
    istio.io/waypoint-for: service
  name: waypoint
  namespace: default
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE

请注意,Gateway 资源的 gatewayClassNameistio-waypoint, 它实例化了一个 Istio 管理的 waypoint。Gateway 资源标有 istio.io/waypoint-for: service, 表示 waypoint 可以处理服务的流量,这是默认设置。

要直接部署 waypoint 代理,请使用 apply 代替 generate

$ istioctl waypoint apply -n default
waypoint default/waypoint applied

或者,您可以部署生成的 Gateway 资源:

$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  labels:
    istio.io/waypoint-for: service
  name: waypoint
  namespace: default
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE
EOF

当 Gateway 资源被应用后,istiod 会监控资源, 自动为用户部署和管理相应的 waypoint Deployment 和服务。

waypoint 流量类型

默认情况下,waypoint 仅处理发往其命名空间中服务的流量。 做出这种选择是因为单独指向 Pod 的流量很少, 并且通常被用于 Prometheus 抓取等内部目的, 而且通过 L7 处理会产生额外开销,这是预期之外的开销。

waypoint 也可以处理所有流量,仅处理直接发送到集群中工作负载(Pod 或 VM)的流量, 或者根本不处理任何流量。被重定向到 waypoint 的流量类型由 Gateway 对象上的 istio.io/waypoint-for 标签决定。

使用 istioctl waypoint apply--for 参数来更改可以重定向到 waypoint 的流量类型:

waypoint-for原始目标地类型
serviceKubernetes 服务
workloadPod IP 或 VM IP
all服务和工作负载流量
none无流量(用于测试)

waypoint 的选择基于流量最初发送到的目标类型, 即 serviceworkload。如果流量发送到没有 waypoint 的服务, waypoint 不会被转移:即使它最终到达的工作负载确实存在一个附加的 waypoint。

使用 waypoint 代理

当 waypoint 代理被部署后,除非您显式配置某些资源来使用它,否则它默认不会被任何资源使用。

要使命名空间、服务或 Pod 能够使用 waypoint, 请添加 istio.io/use-waypoint 标签,取值为 waypoint 名称。

如果您使用 istioctl 部署命名空间的 waypoint, 则可以使用 --enroll-namespace 参数自动标记一个命名空间:

$ istioctl waypoint apply -n default --enroll-namespace
waypoint default/waypoint applied
namespace default labeled with "istio.io/use-waypoint: waypoint"

或者,您可以使用 kubectlistio.io/use-waypoint: waypoint 标签添加到 default 命名空间:

$ kubectl label ns default istio.io/use-waypoint=waypoint
namespace/default labeled

当一个命名空间被注册为使用 waypoint 后,使用 Ambient 数据平面模式的任何 Pod 向该命名空间中运行的任何服务发出的所有请求都将通过 waypoint 进行路由,以进行 L7 处理和策略执行。

如果您喜欢更精细的操作粒度,而不是对整个命名空间使用 waypoint, 则可以仅注册特定服务或 Pod 来使用 waypoint。如果您只需要命名空间中的某些服务具有 L7 功能, 如果您只想将 WasmPlugin 之类的扩展应用于特定服务,或者如果您正在通过其 Pod IP 地址调用 Kubernetes 无头服务, 这可能很有用。

入口网关与 waypoint

istio.io/use-waypoint 标签用于管控东西向流量: 来自网格内其他 Pod、发往带有该标签的命名空间、服务或工作负载的请求, 将通过目标 waypoint 进行七层策略处理与遥测。

Istio 入口网关流向该 Service 的流量是单独建模的。 默认情况下,源自入口网关的流量不会使用目标服务的 waypoint, 即使该服务或命名空间上已设置了 istio.io/use-waypoint 标签。

若要将入口流量(Ingress traffic)导向与网格流量(Mesh traffic)相同的 waypoint, 请在 Kubernetes Service 上,或在 Namespace 上(以便应用于该命名空间内的所有服务)将 istio.io/ingress-use-waypoint 标签设置为 true(此功能自 Istio 1.25 版本起受支持)。 有关支持的资源类型,请参阅资源标签参考文档。

$ kubectl label service reviews istio.io/ingress-use-waypoint=true
service/reviews labeled

控制平面仅在 istiod 启用了 ENABLE_INGRESS_WAYPOINT_ROUTING 时才会应用此行为; 该参数默认为 false。详见 pilot-discovery 环境变量参考中的 ENABLE_INGRESS_WAYPOINT_ROUTING

配置服务以使用特定 waypoint

使用示例 Bookinfo 应用中的服务, 我们可以为 reviews 服务部署一个名为 reviews-svc-waypoint 的 waypoint:

$ istioctl waypoint apply -n default --name reviews-svc-waypoint
waypoint default/reviews-svc-waypoint applied

reviews 服务打标签以使用 reviews-svc-waypoint waypoint:

$ kubectl label service reviews istio.io/use-waypoint=reviews-svc-waypoint
service/reviews labeled

从网格中的 Pod 到 reviews 服务的所有请求现在都将通过 reviews-svc-waypoint waypoint 进行路由。

配置 Pod 以使用特定 waypoint

reviews-v2 Pod 部署一个名为 reviews-v2-pod-waypoint 的 waypoint。

$ istioctl waypoint apply -n default --name reviews-v2-pod-waypoint --for workload
waypoint default/reviews-v2-pod-waypoint applied

reviews-v2 Pod 打标签以使用 reviews-v2-pod-waypoint waypoint:

$ kubectl label pod -l version=v2,app=reviews istio.io/use-waypoint=reviews-v2-pod-waypoint
pod/reviews-v2-5b667bcbf8-spnnh labeled

从 Ambient 网格中的 Pod 到 reviews-v2 Pod IP 的所有请求现在都将通过 reviews-v2-pod-waypoint waypoint 进行路由,以进行 L7 处理和策略执行。

要求流量经过航点 waypoint

istio.io/use-waypoint 标签记录了您通过 waypoint 发送流量的意图, 但它本身并不能保证这种情况会发生。ztunnel 在以下情况下将流量直接路由到目的地,而不是使请求失败:

  • 指定的 waypoint 不存在或没有地址;或
  • 流量类型与 waypoint 处理的流量不匹配;例如,当 waypoint 仅处理服务流量时, 直接发送到工作负载(Pod 或 VM IP)的请求,这是默认

在任何一种情况下,waypoint 执行的任何 L7 策略都不会生效,并且流量就像未配置 waypoint 一样流动。

如果强制执行某个 waypoint 的 L7 策略是一项安全要求, 请使用仅允许该 waypoint 身份的 AuthorizationPolicy 强制该 waypoint。 waypoint 使用以其 Gateway 命名的服务帐户, 因此仅允许该身份的目标工作负载策略会拒绝任何未经先通过 waypoint 就到达它们的客户端。 继续上面的 reviews-svc-waypoint waypoint:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: require-waypoint
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/reviews-svc-waypoint

此策略使用工作负载 selector 而不是 targetRef, 因此它由 ztunnel 在 L4 层强制执行。因此,它在两种旁路情况下都有效: 当 waypoint 不可用时,以及当客户端直接调用工作负载时。

在 waypoint 之间转移流量

更改服务上的 istio.io/use-waypoint 标签会将其所有流量立即移动到新的 waypoint。 要逐渐在两个 waypoint 之间移动服务,例如在升级期间验证新 waypoint 版本, 请在主 waypoint 旁边命名第二个“金丝雀” waypoint,并为其分配服务流量。 配置完全依赖于目标服务:客户端不知道它,并且不需要第二个 Service

名称类型目的
istio.io/use-waypoint-canary标签金丝雀 waypoint Gateway 的名称。
istio.io/use-waypoint-canary-namespace标签金丝雀 waypoint 的命名空间(如果它不是服务的命名空间)。
istio.io/use-waypoint-canary-weight注解发送到金丝雀的流量份额,为 0 到 100 之间的整数。主 waypoint 接收余数。默认为 0。

继续上面的 reviews 服务,部署第二个 waypoint 并向其发送 5% 的服务流量, 将剩余的 95% 留在 reviews-svc-waypoint 上:

$ istioctl waypoint apply -n default --name reviews-svc-waypoint-v2
waypoint default/reviews-svc-waypoint-v2 applied
$ kubectl label service reviews istio.io/use-waypoint-canary=reviews-svc-waypoint-v2
$ kubectl annotate service reviews istio.io/use-waypoint-canary-weight=5

当你对金丝雀部署有了信心时,就增加权重。一旦金丝雀部署承载了所有流量, 通过将其设为主 waypoint 并删除金丝雀配置来提升它:

$ kubectl label service reviews istio.io/use-waypoint=reviews-svc-waypoint-v2 --overwrite
$ kubectl label service reviews istio.io/use-waypoint-canary-
$ kubectl annotate service reviews istio.io/use-waypoint-canary-weight-

要随时回滚,请删除金丝雀标签。该服务返回通过主 waypoint 发送其所有流量。

支持的资源

ServiceServiceEntryNamespace 支持金丝雀标签和注解。 与 istio.io/use-waypoint 不同,PodWorkloadEntry 支持它们: 拆分是在服务级别定义的,因此它对于网格和入口流量的行为相同。

在命名空间上配置的金丝雀仅适用于也从该命名空间继承其主 waypoint 的服务。 如果服务设置了自己的 istio.io/use-waypoint,它也必须设置自己的金丝雀配置; 该服务将忽略命名空间的金丝雀标签。

两个 waypoint 都能够面向服务。每个都必须准备好, 必须允许从服务的命名空间附加,并且必须处理 serviceall 流量。

权重适用的对象

  • 网格流量ztunnel 每个连接分割: 权重是选择金丝雀的连接的份额。已建立的连接永远不会移动, 因此,其客户端持有长期连接的服务只有在这些客户端重新连接时才会接近配置的权重。 出于同样的原因,观察到的分割是近似的,并且仅在大量连接上才有意义。
  • 入口流量由入口网关按请求分割,并且仅适用于选择使用 istio.io/ingress-use-waypoint 的服务, 如入口网关和 waypoint 中所述。 如果没有选择加入,入口流量将继续绕过这两个 waypoint。

网格分割需要 Istio 1.31 或更高版本的 ztunnel。在升级数据平面时, 仍在运行较旧 ztunnel 的节点将其所有连接发送到主 waypoint, 因此网格上的分割滞后于配置的权重,直到每个节点都升级为止。入口分割不依赖于 ztunnel。

附加到 waypoint 的配置

两个 waypoint 提供相同的服务,因此在轮班期间必须保持有效的任何配置都必须在两个 waypoint 都适用。 以 Service 为目标的策略和路由(例如 AuthorizationPolicy 或以服务作为其 parentRefHTTPRoute) 由处理流量的任何 waypoint 强制执行,无需重复。

附加到 waypoint Gateway 本身的配置是另一回事。 选择路径点的 WasmPlugintargetRef 命名为 Gateway 的策略仅适用于该 waypoint。 在转移流量之前将其复制到金丝雀上,否则通过金丝雀的流量份额将使用一组不同的策略进行处理。

无效配置

无法使用的金丝雀并不致命。该服务继续单独使用其主 waypoint,原因在服务的 istio.io/WaypointBound 条件中报告:

$ kubectl get service reviews -o jsonpath='{.status.conditions}'

当金丝雀 waypoint 不存在、未准备好、不允许从服务的命名空间附加或无法处理服务流量时, 将应用此回退;当权重不是 0 到 100 之间的整数时(CanaryInvalidWeight); 当金丝雀命名与主要路径点相同的路径点时(CanarySameAsPrimary)。

跨命名空间使用 waypoint

开箱即用,waypoint 代理可供同一命名空间内的资源使用。 从 Istio 1.23 开始,可以在不同的命名空间中使用 waypoint。 在本节中,我们将研究启用跨命名空间使用所需的网关配置,以及如何配置资源以使用来自不同命名空间的 waypoint。

配置一个用于跨命名空间使用的 waypoint

为了能够跨命名空间使用 waypoint, 应将 Gateway 配置为允许来自其他命名空间的路由

以下 Gateway 将允许名为 cross-namespace-waypoint-consumer 的命名空间中的资源使用此 egress-gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: egress-gateway
  namespace: common-infrastructure
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            kubernetes.io/metadata.name: cross-namespace-waypoint-consumer

配置资源以使用跨命名空间 waypoint 代理

默认情况下,Istio 控制平面将在与应用标签的资源相同的命名空间中查找使用 istio.io/use-waypoint 标签指定的 waypoint。可以通过添加新标签 istio.io/use-waypoint-namespace 来使用另一个命名空间中的 waypoint。 istio.io/use-waypoint-namespace 适用于所有支持 istio.io/use-waypoint 标签的资源。 这两个标签一起分别指定 waypoint 的名称和命名空间。例如,要配置名为 istio-siteServiceEntry 以使用名为 common-infrastructure 的命名空间中名为 egress-gateway 的 waypoint,可以使用以下命令:

$ kubectl label serviceentries.networking.istio.io istio-site istio.io/use-waypoint=egress-gateway
serviceentries.networking.istio.io/istio-site labeled
$ kubectl label serviceentries.networking.istio.io istio-site istio.io/use-waypoint-namespace=common-infrastructure
serviceentries.networking.istio.io/istio-site labeled

清理

您可以通过执行以下操作从命名空间中删除所有 waypoint:

$ istioctl waypoint delete --all -n default
$ kubectl label ns default istio.io/use-waypoint-

删除 Kubernetes Gateway API CRD:

$ kubectl delete -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.0/standard-install.yaml
这些信息有用吗?
您是否有更多建议和改进意见?

感谢您的反馈!