×

3scale Istio 适配器是一个可选适配器,允许您标记在 Red Hat OpenShift 服务网格中运行的服务,并将该服务与 3scale API 管理解决方案集成。它不是 Red Hat OpenShift 服务网格所必需的。

您只能将 3scale Istio 适配器与 Red Hat OpenShift 服务网格 2.0 及以下版本一起使用。Mixer 组件在 2.0 版本中已弃用,并在 2.1 版本中移除。对于 Red Hat OpenShift 服务网格 2.1.0 及更高版本,您应该使用3scale WebAssembly 模块

如果要使用 3scale Istio 适配器启用 3scale 后端缓存,还必须启用 Mixer 策略和 Mixer 遥测。请参阅部署 Red Hat OpenShift 服务网格控制平面

将 3scale 适配器与 Red Hat OpenShift 服务网格集成

您可以使用这些示例来配置对使用 3scale Istio 适配器的服务的请求。

先决条件
  • Red Hat OpenShift 服务网格 2.x 版本

  • 有效的 3scale 帐户(SaaS3scale 2.9 本地部署

  • 启用后端缓存需要 3scale 2.9 或更高版本

  • Red Hat OpenShift 服务网格先决条件

  • 确保已启用 Mixer 策略执行。更新 Mixer 策略执行部分提供了检查当前 Mixer 策略执行状态和启用策略执行的说明。

  • 如果您使用的是 mixer 插件,则必须启用 Mixer 策略和遥测。

    • 升级时,您需要正确配置服务网格控制平面 (SMCP)。

要配置 3scale Istio 适配器,请参阅 Red Hat OpenShift 服务网格自定义资源,了解有关将适配器参数添加到自定义资源文件的说明。

请特别注意kind: handler资源。您必须使用您的3scale账户凭据更新此资源。您可以选择向处理程序添加service_id,但这仅用于向后兼容,因为它只会使处理程序对您3scale账户中的一个服务有用。如果您向处理程序添加service_id,则为其他服务启用3scale需要您创建更多具有不同service_id的处理程序。

按照以下步骤,为每个3scale账户使用单个处理程序

步骤
  1. 为您的3scale账户创建一个处理程序,并指定您的账户凭据。省略任何服务标识符。

      apiVersion: "config.istio.io/v1alpha2"
      kind: handler
      metadata:
       name: threescale
      spec:
       adapter: threescale
       params:
         system_url: "https://<organization>-admin.3scale.net/"
         access_token: "<ACCESS_TOKEN>"
       connection:
         address: "threescale-istio-adapter:3333"

    可选地,您可以在params部分内提供backend_url字段来覆盖由3scale配置提供的URL。如果适配器在与3scale本地实例相同的集群上运行,并且您希望利用内部集群DNS,这可能会很有用。

  2. 如下编辑或修补属于您3scale账户的任何服务的Deployment资源

    1. 添加标签"service-mesh.3scale.net/service-id",其值为有效的service_id

    2. 添加标签"service-mesh.3scale.net/credentials",其值为步骤1中处理程序资源的名称

  3. 每当您打算添加更多服务时,请执行步骤2将其链接到您的3scale账户凭据及其服务标识符。

  4. 使用您的3scale配置修改规则配置,以将规则分派到threescale处理程序。

    规则配置示例
      apiVersion: "config.istio.io/v1alpha2"
      kind: rule
      metadata:
        name: threescale
      spec:
        match: destination.labels["service-mesh.3scale.net"] == "true"
        actions:
          - handler: threescale.handler
            instances:
              - threescale-authorization.instance

生成3scale自定义资源

适配器包含一个工具,允许您生成handlerinstancerule自定义资源。

表1. 用法
选项 描述 必填 默认值

-h, --help

生成可用选项的帮助输出

--name

此URL、令牌对的唯一名称

-n, --namespace

生成模板的命名空间

istio-system

-t, --token

3scale访问令牌

-u, --url

3scale管理门户URL

--backend-url

3scale后端URL。如果设置,它将覆盖从系统配置读取的值

-s, --service

3scale API/服务ID

--auth

要指定的3scale身份验证模式 (1=API密钥,2=应用ID/应用密钥,3=OIDC)

混合

-o, --output

保存生成的清单的文件

标准输出

--version

输出CLI版本并立即退出

从URL示例生成模板

  • 通过从已部署的适配器生成清单中的3scale适配器容器映像,通过oc exec运行以下命令。

  • 使用3scale-config-gen命令可以避免YAML语法和缩进错误。

  • 如果您使用注释,可以省略--service

  • 此命令必须通过oc exec在容器映像内调用。

步骤
  • 使用3scale-config-gen命令自动生成模板文件,允许令牌、URL对作为单个处理程序被多个服务共享

    $ 3scale-config-gen --name=admin-credentials --url="https://<organization>-admin.3scale.net:443" --token="[redacted]"
  • 以下示例生成在处理程序中嵌入服务ID的模板

    $ 3scale-config-gen --url="https://<organization>-admin.3scale.net" --name="my-unique-id" --service="123456789" --token="[redacted]"
其他资源

从已部署的适配器生成清单

  • NAME是您用来标识您使用3scale管理的服务的标识符。

  • CREDENTIALS_NAME引用是与规则配置中match部分对应的标识符。如果您使用CLI工具,则会自动将其设置为NAME标识符。

  • 它的值不需要是任何特定内容:标签值只需与规则的内容匹配即可。有关更多信息,请参见通过适配器路由服务流量

  1. 运行此命令以从istio-system命名空间中已部署的适配器生成清单

    $ export NS="istio-system" URL="https://replaceme-admin.3scale.net:443" NAME="name" TOKEN="token"
    oc exec -n ${NS} $(oc get po -n ${NS} -o jsonpath='{.items[?(@.metadata.labels.app=="3scale-istio-adapter")].metadata.name}') \
    -it -- ./3scale-config-gen \
    --url ${URL} --name ${NAME} --token ${TOKEN} -n ${NS}
  2. 这将生成到终端的示例输出。如有必要,请编辑这些示例并使用oc create命令创建对象。

  3. 当请求到达适配器时,适配器需要知道服务如何映射到3scale上的API。您可以通过两种方式提供此信息

    1. 标记工作负载(推荐)

    2. 将处理程序硬编码为service_id

  4. 使用所需的注释更新工作负载

    只有在处理程序中未嵌入服务ID时,才需要更新此示例中提供的服务ID。**处理程序中的设置优先**。

    $ export CREDENTIALS_NAME="replace-me"
    export SERVICE_ID="replace-me"
    export DEPLOYMENT="replace-me"
    patch="$(oc get deployment "${DEPLOYMENT}"
    patch="$(oc get deployment "${DEPLOYMENT}" --template='{"spec":{"template":{"metadata":{"labels":{ {{ range $k,$v := .spec.template.metadata.labels }}"{{ $k }}":"{{ $v }}",{{ end }}"service-mesh.3scale.net/service-id":"'"${SERVICE_ID}"'","service-mesh.3scale.net/credentials":"'"${CREDENTIALS_NAME}"'"}}}}}' )"
    oc patch deployment "${DEPLOYMENT}" --patch ''"${patch}"''

通过适配器路由服务流量

请按照以下步骤通过3scale适配器驱动服务的流量。

先决条件
  • 来自您的3scale管理员的凭据和服务ID。

步骤
  1. 匹配您之前在kind: rule资源的配置中创建的规则destination.labels["service-mesh.3scale.net/credentials"] == "threescale"

  2. 将上述标签添加到目标工作负载的Deployment上的PodTemplateSpec以集成服务。值threescale指的是生成的处理程序的名称。此处理程序存储调用3scale所需的访问令牌。

  3. 将标签destination.labels["service-mesh.3scale.net/service-id"] == "replace-me"添加到工作负载,以便在请求时通过实例将服务ID传递给适配器。

配置3scale中的集成设置

请按照此步骤配置3scale集成设置。

对于3scale SaaS客户,Red Hat OpenShift Service Mesh作为早期访问计划的一部分启用。

步骤
  1. 导航到**[your_API_name]** → **集成**

  2. 点击**设置**。

  3. 部署下选择**Istio**选项。

    • 默认情况下选择身份验证下的**API密钥(user_key)**选项。

  4. 点击**更新产品**以保存您的选择。

  5. 点击**配置**。

  6. 点击**更新配置**。

缓存行为

来自3scale系统API的响应默认情况下在适配器中缓存。当条目超过cacheTTLSeconds值时,它们将从缓存中清除。同样默认情况下,将在缓存条目过期前几秒尝试自动刷新缓存条目,这基于cacheRefreshSeconds值。您可以通过将此值设置高于cacheTTLSeconds值来禁用自动刷新。

可以通过将cacheEntriesMax设置为非正值来完全禁用缓存。

通过使用刷新过程,其主机变得不可访问的缓存值将在最终过期后被清除之前被重试。

验证请求

此版本支持以下身份验证方法

  • **标准API密钥**:充当标识符和秘密令牌的单个随机字符串或哈希值。

  • **应用程序标识符和密钥对**:不可变的标识符和可变的秘密密钥字符串。

  • **OpenID身份验证方法**:从JSON Web令牌解析的客户端ID字符串。

应用身份验证模式

修改instance自定义资源,如以下身份验证方法示例所示,以配置身份验证行为。您可以从以下位置接受身份验证凭据:

  • 请求头

  • 请求参数

  • 请求头和查询参数

指定来自标头中的值时,它们必须是小写。例如,如果您想发送一个名为User-Key的标头,则必须在配置中将其引用为request.headers["user-key"]

API密钥身份验证方法

服务网格根据subject自定义资源参数中的user选项中指定的规则,在查询参数和请求头中查找API密钥。它按照自定义资源文件中给定的顺序检查这些值。您可以通过省略不需要的选项来限制API密钥的搜索范围,只在查询参数或请求头中搜索。

在这个例子中,服务网格首先在user_key查询参数中查找API密钥。如果查询参数中没有API密钥,服务网格就会检查user-key请求头。

API密钥认证方法示例
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: threescale-authorization
  namespace: istio-system
spec:
  template: authorization
  params:
    subject:
      user: request.query_params["user_key"] | request.headers["user-key"] | ""
    action:
      path: request.url_path
      method: request.method | "get"

如果您想让适配器检查不同的查询参数或请求头,请根据需要更改名称。例如,要检查名为“key”的查询参数中的API密钥,请将request.query_params["user_key"]更改为request.query_params["key"]

应用ID和应用密钥对认证方法

服务网格根据subject自定义资源参数中的properties选项中指定的规则,在查询参数和请求头中查找应用ID和应用密钥。应用密钥是可选的。它按照自定义资源文件中给定的顺序检查这些值。您可以通过不包含不需要的选项来限制凭据的搜索范围,只在查询参数或请求头中搜索。

在这个例子中,服务网格首先在查询参数中查找应用ID和应用密钥,如果需要,再检查请求头。

应用ID和应用密钥对认证方法示例
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: threescale-authorization
  namespace: istio-system
spec:
  template: authorization
  params:
    subject:
        app_id: request.query_params["app_id"] | request.headers["app-id"] | ""
        app_key: request.query_params["app_key"] | request.headers["app-key"] | ""
    action:
      path: request.url_path
      method: request.method | "get"

如果您想让适配器检查不同的查询参数或请求头,请根据需要更改名称。例如,要检查名为identification的查询参数中的应用ID,请将request.query_params["app_id"]更改为request.query_params["identification"]

OpenID认证方法

要使用OpenID Connect (OIDC) 认证方法,请在subject字段的properties值中设置client_id,并可选设置app_key

您可以使用前面描述的方法来操作此对象。在下面显示的示例配置中,客户端标识符(应用程序ID)是从JSON Web Token (JWT)的azp标签中解析的。您可以根据需要修改此项。

OpenID认证方法示例
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: threescale-authorization
spec:
  template: threescale-authorization
  params:
    subject:
      properties:
        app_key: request.query_params["app_key"] | request.headers["app-key"] | ""
        client_id: request.auth.claims["azp"] | ""
      action:
        path: request.url_path
        method: request.method | "get"
        service: destination.labels["service-mesh.3scale.net/service-id"] | ""

为了使此集成正常工作,仍然需要在3scale中完成OIDC,以便在身份提供商 (IdP) 中创建客户端。您应该为要在与该服务相同命名空间中保护的服务创建一个请求授权。JWT 通过请求的Authorization标头传递。

在下面定义的示例RequestAuthentication中,请根据需要替换issuerjwksUriselector

OpenID策略示例
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: jwt-example
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: productpage
  jwtRules:
  - issuer: >-
      http://keycloak-keycloak.34.242.107.254.nip.io/auth/realms/3scale-keycloak
    jwksUri: >-
      http://keycloak-keycloak.34.242.107.254.nip.io/auth/realms/3scale-keycloak/protocol/openid-connect/certs

混合认证方法

您可以选择不强制执行特定的身份验证方法,并接受任何有效凭据。如果同时提供了API密钥和应用程序ID/应用程序密钥对,服务网格将使用API密钥。

在这个例子中,服务网格首先检查查询参数中的API密钥,然后检查请求头。如果没有API密钥,则检查查询参数中的应用程序ID和密钥,然后检查请求头。

混合认证方法示例
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: threescale-authorization
spec:
  template: authorization
  params:
    subject:
      user: request.query_params["user_key"] | request.headers["user-key"] |
      properties:
        app_id: request.query_params["app_id"] | request.headers["app-id"] | ""
        app_key: request.query_params["app_key"] | request.headers["app-key"] | ""
        client_id: request.auth.claims["azp"] | ""
    action:
      path: request.url_path
      method: request.method | "get"
      service: destination.labels["service-mesh.3scale.net/service-id"] | ""

3scale适配器指标

适配器默认情况下会报告各种Prometheus指标,这些指标在8080端口的/metrics端点上公开。这些指标提供了对适配器和3scale之间交互性能的洞察。该服务被标记为可被Prometheus自动发现和抓取。

自服务网格1.x之前的版本以来,3scale Istio适配器指标存在不兼容的更改。

在Prometheus中,指标名称已更改,并为后端缓存添加了一个指标,因此从服务网格2.0开始,存在以下指标:

表2. Prometheus指标
指标 类型 描述

threescale_latency

直方图

适配器和3scale之间的请求延迟。

threescale_http_total

计数器

对3scale后端的请求的HTTP状态响应代码。

threescale_system_cache_hits

计数器

从配置缓存中获取的3scale系统请求总数。

threescale_backend_cache_hits

计数器

从后端缓存中获取的3scale后端请求总数。

3scale后端缓存

3scale后端缓存为3scale服务管理API的客户端提供授权和报告缓存。此缓存嵌入在适配器中,可以在某些情况下实现更低的响应延迟,前提是管理员愿意接受权衡。

3scale后端缓存默认情况下是禁用的。3scale后端缓存功能在速率限制方面牺牲了准确性,并且可能会丢失自上次刷新以来发生的命中,以换取较低的延迟和更高的处理器和内存资源消耗。

启用后端缓存的优势

以下是启用后端缓存的优势:

  • 当您发现访问由3scale Istio适配器管理的服务时延迟很高时,请启用后端缓存。

  • 启用后端缓存将阻止适配器不断检查3scale API管理器以进行请求授权,从而降低延迟。

    • 这会在内存中创建一个3scale授权缓存,供3scale Istio适配器在尝试联系3scale API管理器进行授权之前存储和重用。然后,授权将花费更少的时间来授予或拒绝。

  • 当您在运行3scale Istio适配器的服务网格与托管3scale API管理器的地理位置不同时,后端缓存非常有用。

    • 这通常是3scale托管(SaaS)平台的情况,但如果用户在位于不同地理位置的其他集群、不同的可用区或任何网络开销达到3scale API管理器的明显位置中托管其3scale API管理器,也是如此。

获得更低延迟的权衡

以下是获得更低延迟的权衡:

  • 每次刷新时,每个3scale适配器的授权状态都会更新。

    • 这意味着两个或多个适配器实例会在刷新期间引入更大的不准确性。

    • 更有可能授予过多的请求,超过限制并导致不稳定的行为,这会导致一些请求通过而另一些请求未通过,具体取决于哪个适配器处理每个请求。

  • 无法刷新其数据并更新其授权信息的适配器缓存可能会在未向API管理器报告其信息的情况下关闭或崩溃。

  • 当适配器缓存无法确定是否必须授予或拒绝请求时(可能是由于联系API管理器时网络连接问题),将应用失败打开或失败关闭策略。

  • 当发生缓存未命中时,通常在适配器启动后或长时间断开连接后,查询 API 管理器的延迟会增加。

  • 启用缓存后,适配器缓存需要进行比未启用缓存时更多授权计算工作,这会占用处理器资源。

  • 内存需求将与缓存管理的限制数量、应用程序数量和服务数量的组合成比例增长。

后端缓存配置设置

以下几点解释了后端缓存配置设置

  • 在 3scale 配置选项中查找配置后端缓存的设置。

  • 最后 3 个设置控制后端缓存的启用。

    • PARAM_USE_CACHE_BACKEND - 设置为 true 以启用后端缓存。

    • PARAM_BACKEND_CACHE_FLUSH_INTERVAL_SECONDS - 设置连续尝试将缓存数据刷新到 API 管理器之间的时间(以秒为单位)。

    • PARAM_BACKEND_CACHE_POLICY_FAIL_CLOSED - 设置当缓存数据不足且无法连接到 3scale API 管理器时,是否允许/打开或拒绝/关闭对服务的请求。

3scale Istio 适配器 APIcast 模拟

在以下情况下,3scale Istio 适配器的行为与 APIcast 相同

  • 当请求无法匹配任何定义的映射规则时,返回的 HTTP 代码为 404 未找到。之前为 403 禁止。

  • 当请求被拒绝,因为它超过了限制,返回的 HTTP 代码为 429 请求过多。之前为 403 禁止。

  • 通过 CLI 生成默认模板时,它将使用下划线而不是短横线作为标题,例如:user_key 而不是 user-key

3scale Istio 适配器验证

您可能需要检查 3scale Istio 适配器是否按预期工作。如果您的适配器无法工作,请使用以下步骤来帮助解决问题。

步骤
  1. 确保 3scale-adapter pod 在 Service Mesh 控制平面命名空间中运行。

    $ oc get pods -n istio-system
  2. 检查 3scale-adapter pod 是否已打印出有关其启动的信息,例如其版本。

    $ oc logs istio-system
  3. 当对受 3scale 适配器集成保护的服务执行请求时,始终尝试缺少正确凭据的请求并确保它们失败。检查 3scale 适配器日志以收集更多信息。

3scale Istio 适配器故障排除清单

作为安装 3scale Istio 适配器的管理员,可能有多种情况会导致您的集成无法正常工作。使用以下列表来排除安装故障

  • YAML 缩进错误。

  • 缺少 YAML 部分。

  • 忘记将 YAML 中的更改应用到集群。

  • 忘记使用service-mesh.3scale.net/credentials 键标记服务工作负载。

  • 使用不包含 service_id 的处理程序时(以便每个帐户可重用),忘记使用 service-mesh.3scale.net/service-id 标记服务工作负载。

  • Rule 自定义资源指向错误的处理程序或实例自定义资源,或者引用缺少相应的命名空间后缀。

  • Rule 自定义资源的 match 部分可能无法匹配您正在配置的服务,或者它指向当前未运行或不存在的目标工作负载。

  • 处理程序中 3scale 管理门户的访问令牌或 URL 错误。

  • Instance 自定义资源的 params/subject/properties 部分未能列出 app_idapp_keyclient_id 的正确参数,原因可能是它们指定了错误的位置(例如查询参数、标头和授权声明),或者参数名称与用于测试的请求不匹配。

  • 未能使用配置生成器,而没有意识到它实际上位于适配器容器镜像中,需要使用 oc exec 来调用它。