4.4. 流量分割

4.4.1. 流量分割概述

在 Knative 应用程序中,可以通过创建流量分割来管理流量。流量分割被配置为由 Knative 服务管理的路由的一部分。

Knative 应用程序的流量管理

配置路由允许将请求发送到服务的不同修订版本。此路由由 Service 对象的 traffic spec 决定。

traffic 规格声明由一个或多个修订版本组成,每个修订版本负责处理整个流量的一部分。路由到每个修订版本的流量百分比必须添加到 100%,由 Knative 验证确保。

traffic 规格中指定的修订版本可以是固定的、名为修订的修订版本,或者可以指向"latest"修订,该修订跟踪服务所有修订版本列表的头。"latest" 修订版本是一个浮动引用类型,它在创建了新修订版本时更新。每个修订版本都可以附加标签,为该修订版本创建一个额外访问 URL。

traffic 规格可通过以下方法修改:

  • 直接编辑 Service 对象的 YAML。
  • 使用 Knative (kn) CLI --traffic 标志。
  • 使用 OpenShift Container Platform Web 控制台。

当您创建 Knative 服务时,它没有任何默认 traffic spec 设置。

4.4.2. traffic 规格示例

以下示例显示了一个 traffic 规格,其中 100% 的流量路由到该服务的最新修订版本。在 status 下,您可以看到 latestRevision 解析为的最新修订版本的名称:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: example-service
  namespace: default
spec:
...
  traffic:
  - latestRevision: true
    percent: 100
status:
  ...
  traffic:
  - percent: 100
    revisionName: example-service

以下示例显示了一个 traffic 规格,其中 100% 的流量路由到当前标记为 current 修订版本,并且该修订版本的名称指定为 example-service。标记为 latest 的修订版本会保持可用,即使没有流量路由到它:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: example-service
  namespace: default
spec:
...
  traffic:
  - tag: current
    revisionName: example-service
    percent: 100
  - tag: latest
    latestRevision: true
    percent: 0

以下示例演示了如何扩展 traffic 规格中的修订版本列表,以便在多个修订版本间分割流量。这个示例将 50% 的流量发送到标记为 current 修订版本,50% 的流量发送到标记为 candidate 的修订版本。标记为 latest 的修订版本会保持可用,即使没有流量路由到它:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: example-service
  namespace: default
spec:
...
  traffic:
  - tag: current
    revisionName: example-service-1
    percent: 50
  - tag: candidate
    revisionName: example-service-2
    percent: 50
  - tag: latest
    latestRevision: true
    percent: 0

4.4.3. 使用 Knative CLI 进行流量分割

使用 Knative (kn) CLI 创建流量分割功能,通过直接修改 YAML 文件,提供更精简且直观的用户界面。您可以使用 kn service update 命令在服务修订版本间分割流量。

4.4.3.1. 使用 Knative CLI 创建流量分割

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 已安装 Knative (kn) CLI。
  • 您已创建了 Knative 服务。

流程

  • 使用带有标准 kn service update 命令的 --traffic 标签指定服务修订版本以及您要路由到它的流量百分比:

    示例命令

    $ kn service update <service_name> --traffic <revision>=<percentage>

    其中:

    • <service_name> 是您要为其配置流量路由的 Knative 服务的名称。
    • <revision> 是您要配置为接收流量百分比的修订版本。您可以使用 --tag 标志指定修订版本的名称,或指定分配给修订版本的标签。
    • <percentage> 是您要发送到指定修订版本的流量百分比。
  • 可选: --traffic 标志可在一个命令中多次指定。例如,如果您有一个标记为 @latest 的修订版本以及名为 stable 的修订版本,您可以指定您要分割到每个修订版本的流量百分比:

    示例命令

    $ kn service update example-service --traffic @latest=20,stable=80

    如果您有多个修订版本,且没有指定应分割到最后一个修订版本的流量百分比,--traffic 标志可以自动计算此设置。例如,如果您有一个第三个版本名为 example,则使用以下命令:

    示例命令

    $ kn service update example-service --traffic @latest=10,stable=60

    剩余的 30% 的流量被分成 example 修订,即使未指定。

4.4.4. 用于流量分割的 CLI 标志

Knative (kn) CLI 支持作为 kn service update 命令的一部分对服务的流量块进行流量操作。

4.4.4.1. Knative CLI 流量分割标志

下表显示流量分割标志、值格式和标志执行的操作汇总。Repetition 列表示在 kn service update 命令中是否允许重复标志的特定值。

标记操作重复

--traffic

RevisionName=Percent

RevisionName 提供 Percent 的流量

--traffic

Tag=Percent

为带有 Tag的修订版本提供 Percent 的流量

--traffic

@latest=Percent

为最新可用的修订版本提供 Percent 的流量

--tag

RevisionName=Tag

RevisionName 提供 Tag

--tag

@latest=Tag

为最新可用的修订版本提供 Tag

--untag

Tag

从修订中删除 Tag

4.4.4.1.1. 多个标志和顺序优先级

所有流量相关标志均可使用单一 kn service update 命令指定。kn 定义这些标志的优先级。不考虑使用命令时指定的标志顺序。

通过 kn 评估标志时,标志的优先级如下:

  1. --untag:带有此标志的所有引用修订版本均将从流量块中移除。
  2. --tag:修订版本将按照流量块中的指定进行标记。
  3. --traffic:为引用的修订版本分配一部分流量分割。

您可以将标签添加到修订版本,然后根据您设置的标签来分割流量。

4.4.4.1.2. 修订版本的自定义 URL

使用 kn service update 命令为服务分配 --tag 标志,可为在更新服务时创建的修订版本创建一个自定义 URL。自定义 URL 遵循 https://<tag>-<service_name>-<namespace>.<domain>http://<tag>-<service_name>-<namespace>.<domain>

--tag--untag 标志使用以下语法:

  • 需要一个值。
  • 在服务的流量块中表示唯一标签。
  • 在一个命令中可多次指定.
4.4.4.1.2.1. 示例:将标签分配给修订版本

以下示例将标签 latest 分配给名为 example-revision 的修订版本:

$ kn service update <service_name> --tag @latest=example-tag
4.4.4.1.2.2. 示例:从修订中删除标签

您可以使用 --untag 标志来删除自定义 URL。

注意

如果修订版本删除了其标签,并分配了流量的 0%,则修订版本将完全从流量块中删除。

以下命令从名为 example-revision 的修订版本中删除所有标签:

$ kn service update <service_name> --untag example-tag

4.4.5. 在修订版本间分割流量

创建无服务器应用程序后,应用程序会在 OpenShift Container Platform Web 控制台中的 Developer 视角Topology 视图中显示。应用程序修订版本由节点表示,Knative 服务由节点的四边形表示。

代码或服务配置中的任何新更改都会创建一个新修订版本,也就是给定时间点上代码的快照。对于服务,您可以根据需要通过分割服务修订版本并将其路由到不同的修订版本来管理服务间的流量。

4.4.5.1. 使用 OpenShift Container Platform Web 控制台管理修订版本之间的流量

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 已登陆到 OpenShift Container Platform Web 控制台。

流程

要在 Topology 视图中的多个应用程序修订版本间分割流量:

  1. 点 Knative 服务在侧面面板中查看其概述信息。
  2. Resources 选项卡,查看服务的 RevisionsRoutes 列表。

    图 4.1. 无服务器应用程序

    odc serverless app
  3. 点侧边面板顶部的由 S 图标代表的服务,查看服务详情概述。
  4. YAML 选项卡,在 YAML 编辑器中修改服务配置,然后点 Save。例如,将 timeoutseconds 从 300 改为 301。这个配置更改会触发新修订版本。在 Topology 视图中会显示最新的修订,服务 Resources 选项卡现在会显示两个修订版本。
  5. Resources 选项卡中,点 Set Traffic Distribution 查看流量分布对话框:

    1. Splits 字段中为两个修订版本添加流量百分比。
    2. 添加标签以便为这两个修订版本创建自定义 URL。
    3. Save 查看两个节点,分别代表 Topology 视图中的两个修订版本。

      图 4.2. 无服务器应用程序修订

      odc serverless revisions

4.4.6. 使用蓝绿策略重新路由流量

您可以使用蓝绿部署策略,安全地将流量从应用的生产版本重新路由到新版本。

4.4.6.1. 使用蓝绿部署策略路由和管理流量

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 安装 OpenShift CLI (oc) 。

流程

  1. 创建并部署应用程序作为 Knative 服务。
  2. 通过查看以下命令的输出,查找部署服务时创建的第一个修订版本的名称:

    $ oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}'

    示例命令

    $ oc get ksvc example-service -o=jsonpath='{.status.latestCreatedRevisionName}'

    输出示例

    $ example-service-00001

  3. 在服务 spec 中添加以下 YAML 以将入站流量发送到修订版本:

    ...
    spec:
      traffic:
        - revisionName: <first_revision_name>
          percent: 100 # All traffic goes to this revision
    ...
  4. 验证您可以在 URL 输出中运行以下命令来查看您的应用程序:

    $ oc get ksvc <service_name>
  5. 通过修改服务的 template 规格中至少有一个字段来部署应用程序的第二个修订版本。例如,您可以修改服务的 imageenv 环境变量。您可以通过应用服务 YAML 文件重新部署服务,如果安装了 Knative (kn) CLI,也可以使用 kn service update 命令。
  6. 运行以下命令,查找您在重新部署服务时创建的第二个最新的修订版本的名称:

    $ oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}'

    此时,服务的第一个和第二个修订版本都已部署并运行。

  7. 更新您的现有服务,以便为第二个修订版本创建新的测试端点,同时仍然将所有其他流量发送到第一个修订版本:

    使用测试端点更新的服务 spec 示例

    ...
    spec:
      traffic:
        - revisionName: <first_revision_name>
          percent: 100 # All traffic is still being routed to the first revision
        - revisionName: <second_revision_name>
          percent: 0 # No traffic is routed to the second revision
          tag: v2 # A named route
    ...

    在通过重新应用 YAML 资源重新部署此服务后,应用的第二个修订现已被暂存。没有流量路由到主 URL 的第二个修订版本,Knative 会创建一个名为 v2 的新服务来测试新部署的修订版本。

  8. 运行以下命令,获取第二个修订版本的新服务的 URL:

    $ oc get ksvc <service_name> --output jsonpath="{.status.traffic[*].url}"

    在将任何流量路由到之前,您可以使用此 URL 验证新版本的应用运行正常。

  9. 再次更新您的现有服务,以便 50% 的流量发送到第一个修订版本,50% 发送到第二个修订版本:

    更新的服务 spec 在修订版本间分割流量 50/50 的示例

    ...
    spec:
      traffic:
        - revisionName: <first_revision_name>
          percent: 50
        - revisionName: <second_revision_name>
          percent: 50
          tag: v2
    ...

  10. 当您准备好将所有流量路由到应用程序的新版本时,请再次更新该服务,将 100% 的流量发送到第二个修订版本:

    更新的服务 spec 将所有流量发送到第二个修订版本的示例

    ...
    spec:
      traffic:
        - revisionName: <first_revision_name>
          percent: 0
        - revisionName: <second_revision_name>
          percent: 100
          tag: v2
    ...

    提示

    如果您不计划回滚修订版本,您可以删除第一个修订版本,而不是将其设置为流量的 0%。然后,不可路由的修订版本对象会被垃圾回收。

  11. 访问第一个修订版本的 URL,以验证没有更多流量发送到应用程序的旧版本。