Serving


Red Hat OpenShift Serverless 1.35

开始使用 Knative Serving 和配置服务

Red Hat OpenShift Documentation Team

摘要

本文档提供有关开始使用 Knative Serving 的信息。它演示了如何配置应用程序并涵盖自动扩展、流量分割和外部和入口路由等功能。

第 1 章 Knative Serving 入门

1.1. 创建无服务器应用程序

无服务器应用程序已创建并部署为 Kubernetes 服务,由路由和配置定义,并包含在 YAML 文件中。要使用 OpenShift Serverless 部署无服务器应用程序,您必须创建一个 Knative Service 对象。

Knative Service 对象 YAML 文件示例

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: showcase 
1

  namespace: default 
2

spec:
  template:
    spec:
      containers:
        - image: quay.io/openshift-knative/showcase 
3

          env:
            - name: GREET 
4

              value: Ciao
Copy to Clipboard Toggle word wrap

1
应用程序的名称。
2
应用程序使用的命名空间。
3
应用程序的镜像。
4
示例应用程序输出的环境变量。

使用以下任一方法创建一个无服务器应用程序:

  • 从 OpenShift Container Platform web 控制台创建 Knative 服务。

    对于 OpenShift Container Platform,请参阅 创建应用程序

  • 使用 Knative (kn) CLI 创建 Knative 服务。
  • 使用 oc CLI 创建并应用 Knative Service 对象作为 YAML 文件。

1.1.1. 使用 Knative CLI 创建无服务器应用程序

通过使用 Knative (kn) CLI 创建无服务器应用程序,通过直接修改 YAML 文件来提供更精简且直观的用户界面。您可以使用 kn service create 命令创建基本无服务器应用程序。

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 已安装 Knative (kn) CLI。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。

流程

  • 创建 Knative 服务:

    $ kn service create <service-name> --image <image> --tag <tag-value>
    Copy to Clipboard Toggle word wrap

    其中:

    • --image 是应用的镜像的 URI。
    • --tag 是一个可选标志,可用于向利用服务创建的初始修订版本添加标签。

      示例命令

      $ kn service create showcase \
          --image quay.io/openshift-knative/showcase
      Copy to Clipboard Toggle word wrap

      输出示例

      Creating service 'showcase' in namespace 'default':
      
        0.271s The Route is still working to reflect the latest desired specification.
        0.580s Configuration "showcase" is waiting for a Revision to become ready.
        3.857s ...
        3.861s Ingress has not yet been reconciled.
        4.270s Ready to serve.
      
      Service 'showcase' created with latest revision 'showcase-00001' and URL:
      http://showcase-default.apps-crc.testing
      Copy to Clipboard Toggle word wrap

1.1.2. 使用 YAML 创建无服务器应用程序

使用 YAML 文件创建 Knative 资源使用声明性 API,它允许您以声明性的方式描述应用程序,并以可重复的方式描述应用程序。要使用 YAML 创建无服务器应用程序,您必须创建一个 YAML 文件来定义 Knative Service 对象,然后使用 oc apply 来应用它。

创建服务并部署应用程序后,Knative 会为应用程序的这个版本创建一个不可变的修订版本。Knative 还将执行网络操作,为您的应用程序创建路由、入口、服务和负载平衡器,并根据流量自动扩展或缩减 pod。

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。
  • 安装 OpenShift CLI (oc) 。

流程

  1. 创建包含以下示例代码的 YAML 文件:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: showcase
      namespace: default
    spec:
      template:
        spec:
          containers:
            - image: quay.io/openshift-knative/showcase
              env:
                - name: GREET
                  value: Bonjour
    Copy to Clipboard Toggle word wrap
  2. 导航到包含 YAML 文件的目录,并通过应用 YAML 文件来部署应用程序:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap

1.1.3. 使用离线模式创建服务

您可以在离线模式下执行 kn service 命令,以便集群中不会发生任何更改,而是在本地机器上创建服务描述符文件。创建描述符文件后,您可以在向集群传播更改前修改该文件。

重要

Knative CLI 的离线模式只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

先决条件

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

流程

  1. 在离线模式下,创建一个本地 Knative 服务描述符文件:

    $ kn service create showcase \
        --image quay.io/openshift-knative/showcase \
        --target ./ \
        --namespace test
    Copy to Clipboard Toggle word wrap

    输出示例

    Service 'showcase' created in namespace 'test'.
    Copy to Clipboard Toggle word wrap

    • --target ./ 标志启用脱机模式,并将 ./ 指定为用于存储新目录树的目录。

      如果您没有指定现有目录,但使用文件名,如 --target my-service.yaml,则不会创建目录树。相反,当前目录中只创建服务描述符 my-service.yaml 文件。

      文件名可以具有 .yaml.yml.json 扩展名。选择 .json 以 JSON 格式创建服务描述符文件。

    • namespace test 选项将新服务放在 test 命名空间中。

      如果不使用 --namespace,且您登录到 OpenShift Container Platform 集群,则会在当前命名空间中创建描述符文件。否则,描述符文件会在 default 命名空间中创建。

  2. 检查创建的目录结构:

    $ tree ./
    Copy to Clipboard Toggle word wrap

    输出示例

    ./
    └── test
        └── ksvc
            └── showcase.yaml
    
    2 directories, 1 file
    Copy to Clipboard Toggle word wrap

    • 使用 --target 指定的当前 ./ 目录包含新的 test/ 目录,它在指定的命名空间后命名。
    • test/ 目录包含 ksvc,它在资源类型后命名。
    • ksvc 目录包含描述符文件 showcase.yaml,它根据指定的服务名称命名。
  3. 检查生成的服务描述符文件:

    $ cat test/ksvc/showcase.yaml
    Copy to Clipboard Toggle word wrap

    输出示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      creationTimestamp: null
      name: showcase
      namespace: test
    spec:
      template:
        metadata:
          annotations:
            client.knative.dev/user-image: quay.io/openshift-knative/showcase
          creationTimestamp: null
        spec:
          containers:
          - image: quay.io/openshift-knative/showcase
            name: ""
            resources: {}
    status: {}
    Copy to Clipboard Toggle word wrap

  4. 列出新服务的信息:

    $ kn service describe showcase --target ./ --namespace test
    Copy to Clipboard Toggle word wrap

    输出示例

    Name:       showcase
    Namespace:  test
    Age:
    URL:
    
    Revisions:
    
    Conditions:
      OK TYPE    AGE REASON
    Copy to Clipboard Toggle word wrap

    • --target ./ 选项指定包含命名空间子目录的目录结构的根目录。

      另外,您可以使用 --target 选项直接指定 YAML 或 JSON 文件名。可接受的文件扩展包括 .yaml.yml.json

    • --namespace 选项指定命名空间,与 kn 通信包含所需服务描述符文件的子目录。

      如果不使用 --namespace,并且您登录到 OpenShift Container Platform 集群,kn 会在以当前命名空间命名的子目录中搜索该服务。否则,kndefault/ 子目录中搜索。

  5. 使用服务描述符文件在集群中创建服务:

    $ kn service create -f test/ksvc/showcase.yaml
    Copy to Clipboard Toggle word wrap

    输出示例

    Creating service 'showcase' in namespace 'test':
    
      0.058s The Route is still working to reflect the latest desired specification.
      0.098s ...
      0.168s Configuration "showcase" is waiting for a Revision to become ready.
     23.377s ...
     23.419s Ingress has not yet been reconciled.
     23.534s Waiting for load balancer to be ready
     23.723s Ready to serve.
    
    Service 'showcase' created to latest revision 'showcase-00001' is available at URL:
    http://showcase-test.apps.example.com
    Copy to Clipboard Toggle word wrap

1.1.4. 验证无服务器应用程序的部署

要验证您的无服务器应用程序是否已成功部署,您必须获取 Knative 创建的应用程序的 URL,然后向该 URL 发送请求并检查其输出。OpenShift Serverless 支持 HTTP 和 HTTPS URL,但 oc get ksvc 的输出始终使用 http:// 格式打印 URL。

先决条件

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

先决条件

  • 安装 OpenShift CLI (oc) 。

流程

  1. 查找应用程序 URL:

    $ oc get ksvc <service_name>
    Copy to Clipboard Toggle word wrap

    输出示例

    NAME       URL                                   LATESTCREATED    LATESTREADY      READY   REASON
    showcase   http://showcase-default.example.com   showcase-00001   showcase-00001   True
    Copy to Clipboard Toggle word wrap

  2. 向集群发出请求并观察其输出。

    HTTP 请求示例(使用 HTTPie 工具)

    $ http showcase-default.example.com
    Copy to Clipboard Toggle word wrap

    HTTPS 请求示例

    $ https showcase-default.example.com
    Copy to Clipboard Toggle word wrap

    输出示例

    HTTP/1.1 200 OK
    Content-Type: application/json
    Server: Quarkus/2.13.7.Final-redhat-00003 Java/17.0.7
    X-Config: {"sink":"http://localhost:31111","greet":"Ciao","delay":0}
    X-Version: v0.7.0-4-g23d460f
    content-length: 49
    
    {
        "artifact": "knative-showcase",
        "greeting": "Ciao"
    }
    Copy to Clipboard Toggle word wrap

  3. 可选。如果您的系统中没有安装 HTTPie 工具,可以使用 curl 工具:

    HTTPS 请求示例

    $ curl http://showcase-default.example.com
    Copy to Clipboard Toggle word wrap

    输出示例

    {"artifact":"knative-showcase","greeting":"Ciao"}
    Copy to Clipboard Toggle word wrap

  4. 可选。如果您在证书链中收到与自签名证书相关的错误,您可以在 HTTPie 命令中添加-- verify=no 标志来忽略这个错误:

    $ https --verify=no showcase-default.example.com
    Copy to Clipboard Toggle word wrap

    输出示例

    HTTP/1.1 200 OK
    Content-Type: application/json
    Server: Quarkus/2.13.7.Final-redhat-00003 Java/17.0.7
    X-Config: {"sink":"http://localhost:31111","greet":"Ciao","delay":0}
    X-Version: v0.7.0-4-g23d460f
    content-length: 49
    
    {
        "artifact": "knative-showcase",
        "greeting": "Ciao"
    }
    Copy to Clipboard Toggle word wrap

    重要

    在生产部署中不能使用自签名证书。这个方法仅用于测试目的。

  5. 可选。如果 OpenShift Container Platform 集群配置有证书颁发机构 (CA) 签名但尚未为您的系统配置全局证书,您可以使用 curl 命令指定此证书。证书的路径可使用 --cacert 标志传递给 curl 命令:

    $ curl https://showcase-default.example.com --cacert <file>
    Copy to Clipboard Toggle word wrap

    输出示例

    {"artifact":"knative-showcase","greeting":"Ciao"}
    Copy to Clipboard Toggle word wrap

OpenShift Serverless 由多个不同的组件组成,它们具有不同的资源要求和扩展行为。这些组件水平可扩展,但其资源要求和配置高度依赖于实际用例。

control-plane 组件
这些组件负责观察和响应自定义资源,并持续重新配置系统,如控制器 Pod。
data-plane 组件
这些组件直接参与请求和响应处理,例如 Knative Servings activator 组件。

使用以下测试设置记录以下指标和发现:

  • 运行 OpenShift Container Platform 4.13 的集群
  • 在 AWS 中运行 4 个计算节点的集群,机器类型为 m6.xlarge
  • OpenShift Serverless 1.30

2.1. OpenShift Serverless Serving 开销

由于 OpenShift Serverless Serving 的组件是 data-plane 的一部分,来自客户端的请求会通过以下方法进行路由:

  • ingress-gateway (Kourier 或 Service Mesh)
  • activator 组件
  • 每个 Knative Service 中的 queue-proxy sidecar 容器

这些组件在网络中引入了额外的跃点,并执行额外的任务,例如添加可观察性和请求排队。以下是测量的延迟开销:

  • 每个额外网络跃点都会为请求添加 0.5 ms 到 1 ms 延迟。根据 Knative Service 的当前负载,并在请求前将 Knative Service 缩减为零,则 activator 组件并不总是是 data-plane 的一部分。
  • 根据有效负载大小,每个组件消耗最多 1 个 CPU vCPU,以每秒处理 2500 个请求。

2.2. OpenShift Serverless Serving 的已知限制

可以创建的 Knative 服务的最大数量为 3,000。这与 OpenShift Container Platform Kubernetes 服务限制 10,000 对应,因为 1 个 Knative Service 创建 3 个 Kubernetes 服务。

2.3. OpenShift Serverless Serving 扩展和性能

OpenShift Serverless Serving 必须根据以下参数进行扩展和配置:

  • Knative 服务数
  • 修订数
  • 系统中并发请求数
  • 请求有效负载的大小
  • 用户 web 应用程序添加的 Knative Service 的 startup-latency 和响应延迟
  • 随着时间的推移更改 KnativeService 自定义资源(CR)的数量

2.3.1. KnativeServing 默认配置

默认情况下,OpenShift Serverless Serving 配置为运行具有高可用性和中型 CPU 和内存请求和限值的所有组件。这意味着 KnativeServing CR 中的 high-available 字段会自动设置为 2,所有系统组件都会扩展到两个副本。此配置适用于中型工作负载场景,并已使用以下内容进行测试:

  • 170 Knative Services
  • 每个 Knative Service 的 1-2 个修订版本
  • 89 测试场景主要侧重于测试 control plane
  • 48 重新创建 Knative Services 被删除并重新创建的情况
  • 41 稳定场景,在请求速度缓慢但持续发送到系统

在这些测试情况下,系统组件会有效地使用:

Expand
组件测量资源

openshift-serverless项目中的 Operator

1 GB 内存, 0.2 个内核的 CPU

在项目 knative-serving中提供组件

5 GB 内存, 2.5 个内核 CPU

2.3.2. OpenShift Serverless Serving 的最小要求

虽然默认设置适用于中型工作负载,但可能会超额化用于较小的设置,或针对高工作负载场景进行大小化。要为最小工作负载场景配置 OpenShift Serverless Serving,您需要了解系统组件的空闲消耗。

2.3.2.1. 空闲消耗

空闲消耗取决于 Knative 服务的数量。为 knative-serving 和 knative- serving -ingress OpenShift Container Platform 项目中的组件测量以下内存用量:

Expand
组件0 个服务100 个服务500 个服务1000 个服务

Activator

55Mi

86Mi

300Mi

450Mi

autoscaler

52Mi

102Mi

225Mi

350Mi

controller

100Mi

135Mi

310Mi

500Mi

webhook

60Mi

60Mi

60Mi

60Mi

3scale-kourier-gateway

20Mi

60Mi

190Mi

330Mi

net-kourier-controller

90Mi

170Mi

340Mi

430Mi

注意

已安装 3scale-kourier-gatewaynet-kourier-controller 组件或 istio-ingressgatewaynet-istio-controller 组件。

net-istio 的内存消耗基于网格中的 pod 总数。

2.3.3. 为最小工作负载配置 Serving

流程

  • 您可以使用 KnativeServing 自定义资源(CR)为最小工作负载配置 Knative Serving:

    KnativeServing CR 中的最小工作负载配置

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      high-availability:
        replicas: 1 
    1
    
      workloads:
        - name: activator
          replicas: 2 
    2
    
          resources:
            - container: activator
              requests:
                cpu: 250m 
    3
    
                memory: 60Mi 
    4
    
              limits:
                cpu: 1000m
                memory: 600Mi
        - name: controller
          replicas: 1 
    5
    
          resources:
            - container: controller
              requests:
                cpu: 10m
                memory: 100Mi
              limits: 
    6
    
                cpu: 200m
                memory: 300Mi
        - name: webhook
          replicas: 2
          resources:
            - container: webhook
              requests:
                cpu: 100m 
    7
    
                memory: 60Mi
              limits:
                cpu: 200m
                memory: 200Mi
      podDisruptionBudgets: 
    8
    
        - name: activator-pdb
          minAvailable: 1
        - name: webhook-pdb
          minAvailable: 1
    Copy to Clipboard Toggle word wrap

    1
    把它设置为 1 可将所有系统组件扩展到一个副本。
    2
    激活器应始终扩展到至少 2 个实例,以避免停机。
    3
    Activator CPU 请求不应小于 250m,因为 HorizontalPodAutoscaler 将使用此请求作为扩展和缩减的引用。
    4
    将内存请求调整为上表中的空闲值。另外,根据您的预期负载调整内存限值(这可能需要自定义测试来查找最佳值)。
    5
    一个 Webhook 和一个控制器足以满足最小工作负载的情况
    6
    这些限制足以满足最小工作负载的情况,但可能需要根据您的具体工作负载进行调整。
    7
    Webhook CPU 请求不应小于 100m,因为 HorizontalPodAutoscaler 将使用此请求作为扩展和缩减的引用。
    8
    PodDistruptionBudgets 调整为小于 replicas 的值,以避免节点维护期间出现问题。

2.3.4. 为高工作负载配置 Serving

您可以使用 KnativeServing 自定义资源(CR)为高工作负载配置 Knative Serving。以下发现与为高工作负载配置 Knative Serving 相关:

注意

这些发现已使用有效负载大小为 0-32 kb 的请求进行测试。这些测试中使用的 Knative Service 后端有 0 到 10 秒的启动延迟,并在 0 到 5 秒之间响应时间。

  • 所有 data-plane 组件在更高的请求和限值上增加 CPU 使用量,因此必须测试并可能会增加 CPU 请求和限值。
  • activator 组件可能需要更多内存,当它需要缓冲更多或较大的请求有效负载时,因此可能需要增加内存请求和限值。
  • 一个 activator pod 可以在开始增加延迟前每秒处理大约 2500 个请求,在某些情况下会导致错误。
  • 一个 3scale-kourier-gatewayistio-ingressgateway pod 也可以在开始增加延迟前每秒处理大约 2500 个请求,在某些情况下会导致错误。
  • 每个 data-plane 组件最多消耗 1 个 vCPU 来每秒处理 2500 个请求。请注意,这高度依赖于有效负载大小和 Knative Service 后端的响应时间。
重要

Knative Service 用户工作负载的快速启动和快速响应对于整个系统的良好性能至关重要。当 Knative Service 用户后端扩展或请求并发达到其容量时,Knative Serving 组件会缓冲传入的请求。如果您的 Knative Service 用户工作负载引入长时间的启动或请求延迟,它将过载 激活器 组件(CPU 和内存配置太低),或者导致调用客户端的错误。

流程

  • 要微调安装,请使用之前的发现以及您自己的测试结果来配置 KnativeServing 自定义资源:

    KnativeServing CR 中的高工作负载配置

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      high-availability:
        replicas: 2 
    1
    
      workloads:
        - name: component-name 
    2
    
          replicas: 2 
    3
    
          resources:
            - container: container-name
              requests:
                cpu: 
    4
    
                memory:
              limits:
                cpu:
                memory:
      podDisruptionBudgets: 
    5
    
        - name: name-of-pod-disruption-budget
          minAvailable: 1
    Copy to Clipboard Toggle word wrap

    1
    将此参数设置为至少 2 个,以确保每个组件都至少有两个实例正在运行。您还可以使用 工作负载 覆盖某些组件的副本。
    2
    使用 工作负载 列表配置特定组件。使用组件的部署名称并设置 replicas 字段。
    3
    对于 activatorwebhook3scale-kourier-gateway 组件(使用 pod 横向自动扩展(HPAs)),replicas 字段会设置最小副本数。实际的副本数取决于 HPAs 完成的 CPU 负载和扩展。
    4
    至少根据空闲消耗设置请求和限制 CPU 和内存,同时考虑之前的发现和您自己的测试结果。
    5
    PodDistruptionBudgets 调整为小于 副本 的值,以避免节点维护期间出现问题。默认 minAvailable 设置为 1,因此如果您增加所需的副本,还必须增加 minAvailable
重要

由于每个环境高度具体,因此测试和查找您自己的理想配置至关重要。使用 OpenShift Container Platform 的监控和警报功能持续监控您的实际资源消耗,并根据需要进行修改。

如果使用 OpenShift Serverless 和 Service Mesh 集成,则 istio-proxy sidecar 容器会添加额外的 CPU 处理。有关此信息的更多信息,请参阅 Service Mesh 文档。

第 3 章 自动缩放

3.1. 自动缩放

Knative Serving 为应用程序提供自动扩展功能(或 autoscaling),以满足传入的需求。例如,如果应用程序没有流量,并且启用了缩减到零,Knative Serving 将应用程序缩减为零个副本。如果缩减到零,则应用程序会缩减到为集群中的应用程序配置的最小副本数。如果应用流量增加,也可以向上扩展副本来满足需求。

Knative 服务的自动扩展设置可以是由集群管理员配置的全局设置(或 Red Hat OpenShift Service on AWS 和 OpenShift Dedicated 的专用管理员)或为各个服务配置的每个修订设置。

您可以使用 OpenShift Container Platform Web 控制台修改服务的每个修订设置,方法是修改服务的 YAML 文件,或使用 Knative (kn) CLI 修改服务。

注意

您为服务设置的任何限制或目标均是针对应用程序的单个实例来衡量。例如,将 target 注解设置为 50 可将自动扩展器配置为缩放应用程序,以便每个修订一次处理 50 个请求。

3.2. 扩展范围

缩放范围决定了可在任意给定时间为应用程序服务的最小和最大副本数。您可以为应用设置规模绑定,以帮助防止冷启动和控制计算成本。

3.2.1. 最小扩展范围

为应用程序提供服务的最小副本数量由 min-scale 注解决定。如果没有启用缩减为零,则 min-scale 值默认为 1

如果满足以下条件,min-scale 值默认为 0 个副本:

  • 不设置 min-scale 注解
  • 启用扩展到零
  • 使用类 KPA

带有 min-scale 注解的 service spec 示例

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: showcase
  namespace: default
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/min-scale: "0"
...
Copy to Clipboard Toggle word wrap

3.2.1.1. 使用 Knative CLI 设置 min-scale 注解

使用 Knative (kn) CLI 设置 min-scale 注解,比直接修改 YAML 文件提供了一个更加精简且直观的用户界面。您可以使用带有 --scale-min 标志的 kn service 命令为服务创建或修改 min-scale 值。

先决条件

  • 在集群中安装了 Knative Serving。
  • 已安装 Knative (kn) CLI。

流程

  • 使用 --scale-min 标志设置服务的最小副本数:

    $ kn service create <service_name> --image <image_uri> --scale-min <integer>
    Copy to Clipboard Toggle word wrap

    示例命令

    $ kn service create showcase --image quay.io/openshift-knative/showcase --scale-min 2
    Copy to Clipboard Toggle word wrap

3.2.2. 最大扩展范围

可提供应用程序的副本数量由 max-scale 注解决定。如果没有设置 max-scale 注解,则创建的副本数没有上限。

带有 max-scale 注解的 service spec 示例

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: showcase
  namespace: default
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/max-scale: "10"
...
Copy to Clipboard Toggle word wrap

3.2.2.1. 使用 Knative CLI 设置 max-scale 注解

使用 Knative (kn) CLI 设置 max-scale 注解,比直接修改 YAML 文件提供了一个更精简且直观的用户界面。您可以使用带有 --scale-max 标志的 kn service 命令为服务创建或修改 max-scale 值。

先决条件

  • 在集群中安装了 Knative Serving。
  • 已安装 Knative (kn) CLI。

流程

  • 使用 --scale-max 标志设置服务的最大副本数:

    $ kn service create <service_name> --image <image_uri> --scale-max <integer>
    Copy to Clipboard Toggle word wrap

    示例命令

    $ kn service create showcase --image quay.io/openshift-knative/showcase --scale-max 10
    Copy to Clipboard Toggle word wrap

3.3. 并发

并发请求数决定了应用程序的每个副本可在任意给定时间处理的并发请求数。并发可以配置为软限制硬限制

  • 软限制是目标请求限制,而不是严格实施的绑定。例如,如果流量突发,可以超过软限制目标。
  • 硬限制是严格实施的上限请求限制。如果并发达到硬限制,则请求将被缓冲,必须等到有足够的可用容量来执行请求。

    重要

    只有在应用程序中明确用例时才建议使用硬限制配置。指定较少的硬限制可能会对应用程序的吞吐量和延迟造成负面影响,并可能导致冷启动。

添加软目标和硬限制意味着自动扩展以并发请求的软目标数为目标,但为请求的最大数量施加硬限制值。

如果硬限制值小于软限制值,则软限制值将降级,因为不需要将目标设定为多于实际处理的请求数。

3.3.1. 配置软并发目标

软限制是目标请求限制,而不是严格实施的绑定。例如,如果流量突发,可以超过软限制目标。您可以通过在 spec 中设置 autoscaling.knative.dev/target 注解,或者使用带有正确标记的 kn service 命令为 Knative 服务指定软并发目标。

流程

  • 可选:在 Service 自定义资源的 spec 中为您的 Knative 服务设置 autoscaling.knative.dev/target 注解:

    服务规格示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: showcase
      namespace: default
    spec:
      template:
        metadata:
          annotations:
            autoscaling.knative.dev/target: "200"
    Copy to Clipboard Toggle word wrap

  • 可选: 使用 kn service 命令指定 --concurrency-target 标志:

    $ kn service create <service_name> --image <image_uri> --concurrency-target <integer>
    Copy to Clipboard Toggle word wrap

    创建服务的示例,并发目标为 50 请求

    $ kn service create showcase --image quay.io/openshift-knative/showcase --concurrency-target 50
    Copy to Clipboard Toggle word wrap

3.3.2. 配置硬并发限制

硬并发限制是严格强制执行上限的上限。如果并发达到硬限制,则请求将被缓冲,必须等到有足够的可用容量来执行请求。您可以通过修改 containerConcurrency spec 或使用带有正确标记的 kn service 命令为 Knative 服务指定硬并发限制。

流程

  • 可选:在 Service 自定义资源的 spec 中为您的 Knative 服务设置 containerConcurrency spec:

    服务规格示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: showcase
      namespace: default
    spec:
      template:
        spec:
          containerConcurrency: 50
    Copy to Clipboard Toggle word wrap

    默认值为 0,这意味着允许同时访问服务的一个副本的请求数量没有限制。

    大于 0 的值指定允许一次传输到服务的一个副本的请求的确切数量。这个示例将启用 50 个请求的硬并发限制。

  • 可选: 使用 kn service 命令指定 --concurrency-limit 标志:

    $ kn service create <service_name> --image <image_uri> --concurrency-limit <integer>
    Copy to Clipboard Toggle word wrap

    创建服务且并发限制为 50 个请求的命令示例

    $ kn service create showcase --image quay.io/openshift-knative/showcase --concurrency-limit 50
    Copy to Clipboard Toggle word wrap

3.3.3. 并发目标使用率

此值指定自动扩展实际的目标并发限制的百分比。这也称为指定运行副本的热性(hotness),允许自动扩展在达到定义的硬限制前进行扩展。

例如,如果 containerConcurrency 值设置为 10,并且 target-utilization-percentage 值设置为 70%,则自动扩展会在所有现有副本的平均并发请求数量达到 7 时创建一个新的副本。编号为 7 到 10 的请求仍然会被发送到现有的副本,但达到 containerConcurrency 值后会启动额外的副本。

使用 target-utilization-percentage 注解配置的服务示例

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: showcase
  namespace: default
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/target-utilization-percentage: "70"
...
Copy to Clipboard Toggle word wrap

3.4. Scale-to-zero

Knative Serving 为应用程序提供自动扩展功能(或 autoscaling),以满足传入的需求。

3.4.1. 启用 scale-to-zero

您可以使用 enable-scale-to-zero spec,为集群中的应用程序全局启用或禁用 scale-to-zero。

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。
  • 使用默认的 Knative Pod Autoscaler。如果使用 Kubernetes Horizontal Pod Autoscaler,则缩减为零功能将不可用。

流程

  • KnativeServing 自定义资源 (CR) 中修改 enable-scale-to-zero spec:

    KnativeServing CR 示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
    spec:
      config:
        autoscaler:
          enable-scale-to-zero: "false" 
    1
    Copy to Clipboard Toggle word wrap

    1
    enable-scale-to-zero spec 可以是 "true""false"。如果设置为 true,则会启用 scale-to-zero。如果设置为 false,应用程序将缩减至配置的最小扩展绑定。默认值为 "true"

3.4.2. 配置 scale-to-zero 宽限期

Knative Serving 为应用程序提供自动缩放为零个 pod。您可以使用 scale-to-zero-grace-period spec 定义上限,Knative 在删除应用程序的最后一个副本前等待 scale-to-zero machinery 原位。

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。
  • 使用默认的 Knative Pod Autoscaler。如果使用 Kubernetes Horizontal Pod Autoscaler,则缩减为零功能将不可用。

流程

  • KnativeServing 自定义资源 (CR) 中修改 scale-to-zero-grace-period spec:

    KnativeServing CR 示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
    spec:
      config:
        autoscaler:
          scale-to-zero-grace-period: "30s" 
    1
    Copy to Clipboard Toggle word wrap

    1
    宽限期(以秒为单位)。默认值为 30 秒。

第 4 章 配置 OpenShift Serverless 应用程序

4.1. 对 Serving 的多容器支持

您可以使用单个 Knative 服务部署多容器 pod。这个方法可用于将应用程序职责划分为较小的特殊部分。

4.1.1. 配置多容器服务

默认启用多容器支持。您可以通过指定服务中的多个容器来创建多容器 pod。

流程

  1. 修改您的服务使其包含其他容器。只有一个容器可以处理请求,因此为一个容器指定一个 端口。以下是有两个容器的示例配置:

    多容器配置

    apiVersion: serving.knative.dev/v1
    kind: Service
    ...
    spec:
      template:
        spec:
          containers:
            - name: first-container 
    1
    
              image: gcr.io/knative-samples/helloworld-go
              ports:
                - containerPort: 8080 
    2
    
            - name: second-container 
    3
    
              image: gcr.io/knative-samples/helloworld-java
    Copy to Clipboard Toggle word wrap

    1
    第一个容器配置。
    2
    第一个容器的端口规格。
    3
    第二个容器配置。

4.1.2. 探测多容器服务

您可以为多个容器指定就绪度和存活度探测。默认情况下不启用此功能,您必须使用 KnativeServing 自定义资源(CR)配置它。

流程

  1. 通过在 KnativeServing CR 中启用 多容器代理功能,为您的服务配置多容器 探测。

    多容器探测配置

    ...
    spec:
      config:
        features:
          "multi-container-probing": enabled 
    1
    
    ...
    Copy to Clipboard Toggle word wrap

    1
    启用多容器 -probing 功能
  2. 应用更新的 KnativeServing CR。

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap
  3. 修改您的多容器服务,使其包含指定的探测。

    多容器探测

    apiVersion: serving.knative.dev/v1
    kind: Service
    ...
    spec:
     template:
       spec:
         containers:
           - name: first-container
             image: ghcr.io/knative/helloworld-go:latest
             ports:
               - containerPort: 8080
             readinessProbe: 
    1
    
               httpGet:
                 port: 8080
           - name: second-container
             image: gcr.io/knative-samples/helloworld-java
             readinessProbe: 
    2
    
               httpGet:
                 port: 8090
    Copy to Clipboard Toggle word wrap

    1
    第一个容器的就绪度探测
    2
    第二个容器的就绪度探测
4.1.2.1. 其他资源

4.2. EmptyDir 卷

emptyDir 卷是创建 pod 时创建的空卷,用来提供临时工作磁盘空间。当为其创建 pod 被删除时,emptyDir 卷会被删除。

4.2.1. 配置 EmptyDir 扩展

kubernetes.podspec-volumes-emptydir 扩展控制 emptyDir 卷是否与 Knative Serving 搭配使用。要使用 emptyDir 卷启用,您必须修改 KnativeServing 自定义资源 (CR) 使其包含以下 YAML:

KnativeServing CR 示例

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: knative-serving
spec:
  config:
    features:
      kubernetes.podspec-volumes-emptydir: enabled
...
Copy to Clipboard Toggle word wrap

4.3. Serving 的持久性卷声明

有些无服务器应用程序需要持久性数据存储。通过配置不同的卷类型,您可以为 Knative 服务提供数据存储。服务支持挂载卷类型,如 secretconfigMapprojected、和 emptyDir

您可以为 Knative 服务配置持久性卷声明(PVC)。持久性卷类型作为插件实现。要确定是否有可用的持久性卷类型,您可以检查集群中的可用或安装的存储类。支持持久性卷,但需要启用功能标记。

警告

大型卷的挂载可能会导致应用程序的开始时间出现显著的延迟。

4.3.1. 启用 PVC 支持

流程

  1. 要启用 Knative Serving 使用 PVC 并写入它们,请修改 KnativeServing 自定义资源 (CR) 使其包含以下 YAML:

    启用具有写入访问的 PVC

    ...
    spec:
      config:
        features:
          "kubernetes.podspec-persistent-volume-claim": enabled
          "kubernetes.podspec-persistent-volume-write": enabled
    ...
    Copy to Clipboard Toggle word wrap

    • kubernetes.podspec-persistent-volume-claim 扩展控制持久性卷 (PV) 是否可以用于 Knative Serving。
    • kubernetes.podspec-persistent-volume-write 扩展控制 Knative Serving 是否使用写入访问权限。
  2. 要声明 PV,请修改您的服务使其包含 PV 配置。例如,您可能具有以下配置的持久性卷声明:

    注意

    使用支持您请求的访问模式的存储类。例如,您可以使用 ReadWriteMany 访问模式的 ocs-storagecluster-cephfs 存储类。

    支持 ocs-storagecluster-cephfs 存储类,并来自 Red Hat OpenShift Data Foundation

    PersistentVolumeClaim 配置

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: example-pv-claim
      namespace: my-ns
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: ocs-storagecluster-cephfs
      resources:
        requests:
          storage: 1Gi
    Copy to Clipboard Toggle word wrap

    在这种情况下,若要声明具有写访问权限的 PV,请修改服务,如下所示:

    Knative 服务 PVC 配置

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      namespace: my-ns
    ...
    spec:
     template:
       spec:
         containers:
             ...
             volumeMounts: 
    1
    
               - mountPath: /data
                 name: mydata
                 readOnly: false
         volumes:
           - name: mydata
             persistentVolumeClaim: 
    2
    
               claimName: example-pv-claim
               readOnly: false 
    3
    Copy to Clipboard Toggle word wrap

    1
    卷挂载规格。
    2
    持久性卷声明规格。
    3
    启用只读访问的标记。
    注意

    要在 Knative 服务中成功使用持久性存储,您需要额外的配置,如 Knative 容器用户的用户权限。

4.4. init 容器

Init 容器是 pod 中应用程序容器之前运行的专用容器。它们通常用于为应用程序实施初始化逻辑,其中可能包括运行设置脚本或下载所需的配置。您可以通过修改 KnativeServing 自定义资源 (CR) 来启用 init 容器用于 Knative 服务。

注意

Init 容器可能会导致应用程序的启动时间较长,应该谨慎地用于无服务器应用程序,这应该经常被扩展或缩减。

4.4.1. 启用 init 容器

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。

流程

  • 通过在 KnativeServing CR 中添加 kubernetes.podspec-init-containers 标记来启用 init 容器的使用:

    KnativeServing CR 示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
    spec:
      config:
        features:
          kubernetes.podspec-init-containers: enabled
    ...
    Copy to Clipboard Toggle word wrap

4.5. 启动探测

启动探测验证服务是否已成功启动,有助于降低启动进程的容器的冷启动时间。启动探测仅在容器初始化阶段运行,且不会定期执行。如果启动探测失败,则容器遵循定义的 restartPolicy

4.5.1. 进度期限

默认情况下,服务有一个进度期限,用于定义服务的时间限制,以完成其初始启动。使用启动探测时,请确保将进度截止时间设置为超过启动探测所需的最长时间。如果进度截止时间设置得太低,启动探测可能无法在达到截止时间前完成,这可能会阻止服务启动。

如果您在部署中遇到这些条件,请考虑增加进度期限:

  • 服务镜像的大小需要很长时间才能拉取。
  • 由于初始缓存 priming,该服务需要很长时间才能变为 READY
  • 集群依赖于自动扩展来为新 pod 分配资源。

4.5.2. 配置启动探测

对于 OpenShift Serverless Serving,默认情况下不定义启动探测。您可以在部署配置中为容器定义启动探测。

流程

  • 通过修改部署配置,为您的服务定义启动探测。以下示例显示了有两个容器的配置:

    定义的星号探测示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    # ...
    spec:
      template:
        spec:
           containers:
            - name: first-container
              image: <image>
              ports:
                - containerPort: 8080
              # ...
              startupProbe: 
    1
    
              httpGet:
                port: 8080
                path: "/"
            - name: second-container
              image: <image>
              # ...
              startupProbe: 
    2
    
              httpGet:
                port: 8081
                path: "/"
    Copy to Clipboard Toggle word wrap

    1
    启动 第一容器 的 探测.
    2
    第二容器 启动探测.

4.5.3. 配置进度期限

您可以配置进度截止时间设置,以指定在系统报告 Knative Revision 失败前部署的最长时间。此时间限制可以以秒为单位或分钟为单位。

要有效地配置进度期限,请考虑以下参数:

  • initialDelaySeconds
  • failureThreshold
  • periodSeconds
  • timeoutSeconds

如果没有在指定的时间限制内实现初始扩展,Knative Autoscaler 组件会将修订版本扩展到 0, Knative 服务会进入终端 Failed 状态。

默认情况下,进度期限设置为 600 秒。这个值被指定为 Golang time.Duration 字符串,且必须舍入到最接近的秒。

流程

  • 要配置 progress deadline 设置,请在部署配置中使用注解。

    进程截止时间设置为 60 秒的示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    ...
    spec:
      template:
        metadata:
           annotations:
                serving.knative.dev/progress-deadline: "60s"
        spec:
            containers:
                - image: ghcr.io/knative/helloworld-go:latest
    Copy to Clipboard Toggle word wrap

4.6. 将镜像标签解析到摘要

如果 Knative Serving 控制器可以访问容器 registry,Knative Serving 会在创建服务的修订时将镜像标签解析为摘要。这被称为 tag-to-digest 解析,有助于为部署提供一致性。

4.6.1. tag-to-digest 解析

要让控制器访问 OpenShift Container Platform 上的容器 registry,您必须创建一个 secret,然后配置控制器自定义证书。您可以通过修改 KnativeServing 自定义资源 (CR) 中的 controller-custom-certs spec 来配置控制器自定义证书。secret 必须位于与 KnativeServing CR 相同的命名空间中。

如果 KnativeServing CR 中不包含 secret,此设置默认为使用公钥基础架构 (PKI) 。在使用 PKI 时,集群范围的证书会使用 config-service-sa 配置映射自动注入到 Knative Serving 控制器。OpenShift Serverless Operator 使用集群范围证书填充 config-service-sa 配置映射,并将配置映射作为卷挂载到控制器。

4.6.1.1. 使用 secret 配置 tag-to-digest 解析

如果 controller-custom-certs spec 使用 Secret 类型,secret 将被挂载为 secret 卷。Knative 组件直接使用 secret,假设 secret 具有所需的证书。

先决条件

  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。
  • 您已在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。

流程

  1. 创建 secret:

    示例命令

    $ oc -n knative-serving create secret generic custom-secret --from-file=<secret_name>.crt=<path_to_certificate>
    Copy to Clipboard Toggle word wrap

  2. 配置 KnativeServing 自定义资源 (CR) 中的 controller-custom-certs 规格以使用 Secret 类型:

    KnativeServing CR 示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      controller-custom-certs:
        name: custom-secret
        type: Secret
    Copy to Clipboard Toggle word wrap

4.7. 配置部署资源

在 Knative Serving 中,config-deployment 配置映射包含用于决定如何为 Knative 服务配置 Kubernetes Deployment 资源的设置。在 OpenShift Serverless Serving 中,您可以在 KnativeServing 自定义资源(CR)的 deployment 部分中配置这些设置。

您可以使用 deployment 部分来配置以下内容:

  • 标签解析
  • 运行时环境
  • 进度期限

4.7.1. 跳过标签解析

在 OpenShift Serverless Serving 中跳过标签解析可以通过避免对容器 registry 的不必要的查询来加快部署,从而减少对 registry 的延迟和依赖。

您可以通过修改 KnativeServing 自定义资源(CR)中的 registrySkippingTagResolving 设置,将 Serving 配置为跳过标签解析。

流程

  • KnativeServing CR 中,使用标签重新路由的 registry 列表修改 registry SkippingTagResolving 设置:

    配置的标签解析跳过示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
    spec:
      config:
        deployment:
          registriesSkippingTagResolving: "registry.example.com, another.registry.com"
    Copy to Clipboard Toggle word wrap

4.7.2. 配置可选择的 RuntimeClassName

您可以通过更新 KnativeServing 自定义资源(CR)中的 runtime-class-name 设置,将 OpenShift Serverless Serving 配置为为 Deployment 设置特定的 RuntimeClassName 资源。

此设置与服务标签交互,应用默认 RuntimeClassName 或与服务关联的标签匹配的默认 RuntimeClassName。

流程

  • KnativeServing CR 中,配置 runtime-class-name 设置:

    配置的 runtime-class-name 设置示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
    spec:
      config:
        deployment:
          runtime-class-name: |
            kata: {}
            gvisor:
              selector:
                my-label: selector
    Copy to Clipboard Toggle word wrap

4.7.3. 进度期限

默认情况下,服务有一个进度期限,用于定义服务的时间限制,以完成其初始启动。

如果您在部署中遇到这些条件,请考虑增加进度期限:

  • 服务镜像的大小需要很长时间才能拉取。
  • 由于初始缓存 priming,该服务需要很长时间才能变为 READY
  • 集群依赖于自动扩展来为新 pod 分配资源。

如果没有在指定的时间限制内实现初始扩展,Knative Autoscaler 组件会将修订版本扩展到 0, 服务进入终端 Failed 状态。

4.7.3.1. 配置进度期限

配置进度截止时间设置,以便在系统报告 Knative Revision 失败前设置部署进度的最长时间(以秒为单位或分钟)。

默认情况下,进度期限设置为 600 秒。这个值被指定为 Go time.Duration 字符串,且必须舍入到最接近的秒。

流程

通过修改 KnativeServing 自定义资源(CR)来配置进度期限。

  • KnativeServing CR 中,设置 progressDeadline 的值:

    进程截止时间设置为 60 秒的示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
    spec:
      config:
        deployment:
          progressDeadline: "60s"
    Copy to Clipboard Toggle word wrap

4.8. 配置 Kourier

Kourier 是 Knative Serving 的轻量级 Kubernetes 原生 Ingress。Kourier 作为 Knative 的网关,将 HTTP 流量路由到 Knative 服务。

4.8.1. 访问当前的 Envoy bootstrap 配置

Kourier 中的 Envoy 代理组件处理 Knative 服务的入站和出站 HTTP 流量。默认情况下,Kourier 在 knative-serving-ingress 命名空间中的 kourier-bootstrap 配置映射中包含 Envoy bootstrap 配置。

流程

  • 要获取当前的 Envoy bootstrap 配置,请运行以下命令:

    示例命令

    $ oc get cm kourier-bootstrap -n knative-serving-ingress -o yaml
    Copy to Clipboard Toggle word wrap

    例如,在默认配置中,example 命令会生成包含以下摘录的输出:

    输出示例

    Name:         kourier-bootstrap
    Namespace:    knative-serving-ingress
    Labels:       app.kubernetes.io/component=net-kourier
                  app.kubernetes.io/name=knative-serving
                  app.kubernetes.io/version=release-v1.10
                  networking.knative.dev/ingress-provider=kourier
                  serving.knative.openshift.io/ownerName=knative-serving
                  serving.knative.openshift.io/ownerNamespace=knative-serving
    Annotations:  manifestival: new
    Copy to Clipboard Toggle word wrap

    数据 输出示例

    dynamic_resources:
      ads_config:
        transport_api_version: V3
        api_type: GRPC
        rate_limit_settings: {}
        grpc_services:
        - envoy_grpc: {cluster_name: xds_cluster}
      cds_config:
        resource_api_version: V3
        ads: {}
      lds_config:
        resource_api_version: V3
        ads: {}
    node:
      cluster: kourier-knative
      id: 3scale-kourier-gateway
    static_resources:
      listeners:
        - name: stats_listener
          address:
            socket_address:
              address: 0.0.0.0
              port_value: 9000
          filter_chains:
            - filters:
                - name: envoy.filters.network.http_connection_manager
                  typed_config:
                    "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                    stat_prefix: stats_server
                    http_filters:
                      - name: envoy.filters.http.router
                        typed_config:
                          "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
                    route_config:
                      virtual_hosts:
                        - name: admin_interface
                          domains:
                            - "*"
                          routes:
                            - match:
                                safe_regex:
                                  regex: '/(certs|stats(/prometheus)?|server_info|clusters|listeners|ready)?'
                                headers:
                                  - name: ':method'
                                    string_match:
                                      exact: GET
                              route:
                                cluster: service_stats
      clusters:
        - name: service_stats
          connect_timeout: 0.250s
          type: static
          load_assignment:
            cluster_name: service_stats
            endpoints:
              lb_endpoints:
                endpoint:
                  address:
                    pipe:
                      path: /tmp/envoy.admin
        - name: xds_cluster
          # This keepalive is recommended by envoy docs.
          # https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol
          typed_extension_protocol_options:
            envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
              "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
              explicit_http_config:
                http2_protocol_options:
                  connection_keepalive:
                    interval: 30s
                    timeout: 5s
          connect_timeout: 1s
          load_assignment:
            cluster_name: xds_cluster
            endpoints:
              lb_endpoints:
                endpoint:
                  address:
                    socket_address:
                      address: "net-kourier-controller.knative-serving-ingress.svc.cluster.local."
                      port_value: 18000
          type: STRICT_DNS
    admin:
      access_log:
      - name: envoy.access_loggers.stdout
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
      address:
        pipe:
          path: /tmp/envoy.admin
    layered_runtime:
      layers:
        - name: static-layer
          static_layer:
            envoy.reloadable_features.override_request_timeout_by_gateway_timeout: false
    Copy to Clipboard Toggle word wrap

    BinaryData 输出示例

    Events:  <none>
    Copy to Clipboard Toggle word wrap

4.8.2. 为 Kourier getaways 自定义 kourier-bootstrap

Kourier 中的 Envoy 代理组件处理 Knative 服务的入站和出站 HTTP 流量。默认情况下,Kourier 在 knative-serving-ingress 命名空间中的 kourier-bootstrap 配置映射中包含 Envoy bootstrap 配置。您可以将此配置映射更改为自定义映射。

先决条件

  • 安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。

流程

  • 通过更改 KnativeServing 自定义资源(CR)中的 spec.ingress.kourier.bootstrap-configmap 字段来指定自定义 bootstrap 配置映射:

    KnativeServing CR 示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      config:
        network:
          ingress-class: kourier.ingress.networking.knative.dev
      ingress:
        kourier:
          bootstrap-configmap: my-configmap
          enabled: true
    # ...
    Copy to Clipboard Toggle word wrap

4.8.3. 启用管理员接口访问权限

您可以更改 envoy bootstrap 配置来启用对管理界面的访问。

重要

此流程假设足够了解 Knative,因为更改 envoy bootstrap 配置可能会导致 Knative 失败。红帽不支持在产品中没有测试或附带的自定义配置。

先决条件

  • 安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。

流程

  1. 要启用管理员接口访问权限,请在 bootstrap 配置映射中找到此配置:

    pipe:
      path: /tmp/envoy.admin
    Copy to Clipboard Toggle word wrap

    使用以下配置替换它:

    socket_address: 
    1
    
      address: 127.0.0.1
      port_value: 9901
    Copy to Clipboard Toggle word wrap
    1
    此配置支持访问 loopback 地址(127.0.0.1)和端口 9901 上的 Envoy admin 接口。
  2. service_stats 集群配置和 admin 配置中应用 socket_address 配置:

    1. 第一个位于 service_stats 集群配置中:

      clusters:
        - name: service_stats
          connect_timeout: 0.250s
          type: static
          load_assignment:
            cluster_name: service_stats
            endpoints:
              lb_endpoints:
                endpoint:
                  address:
                    socket_address:
                      address: 127.0.0.1
                      port_value: 9901
      Copy to Clipboard Toggle word wrap
    2. 第二个位于 admin 配置中:

      admin:
        access_log:
          - name: envoy.access_loggers.stdout
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
        address:
          socket_address:
            address: 127.0.0.1
            port_value: 9901
      Copy to Clipboard Toggle word wrap

4.9. 限制网络策略

4.9.1. 具有限制性网络策略的集群

如果您使用多个用户可访问的集群,您的集群可能会使用网络策略来控制哪些 pod、服务和命名空间可以通过网络相互通信。如果您的集群使用限制性网络策略,Knative 系统 Pod 可能无法访问 Knative 应用程序。例如,如果您的命名空间具有以下网络策略(拒绝所有请求),Knative 系统 pod 无法访问您的 Knative 应用程序:

拒绝对命名空间的所有请求的 NetworkPolicy 对象示例

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-by-default
  namespace: example-namespace
spec:
  podSelector:
  ingress: []
Copy to Clipboard Toggle word wrap

要允许从 Knative 系统 pod 访问应用程序,您必须为每个 Knative 系统命名空间添加标签,然后在应用程序命名空间中创建一个 NetworkPolicy 对象,以便为具有此标签的其他命名空间访问命名空间。

重要

拒绝对集群中非原生服务的请求的网络策略仍阻止访问这些服务。但是,通过允许从 Knative 系统命名空间访问 Knative 应用程序,您可以从集群中的所有命名空间中访问 Knative 应用程序。

如果您不想允许从集群中的所有命名空间中访问 Knative 应用程序,您可能需要为 Knative 服务使用 JSON Web Token 身份验证 。Knative 服务的 JSON Web 令牌身份验证需要 Service Mesh。

先决条件

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

流程

  1. knative.openshift.io/system-namespace=true 标签添加到需要访问应用程序的每个 Knative 系统命名空间:

    1. 标记 knative-serving 命名空间:

      $ oc label namespace knative-serving knative.openshift.io/system-namespace=true
      Copy to Clipboard Toggle word wrap
    2. 标记 knative-serving-ingress 命名空间:

      $ oc label namespace knative-serving-ingress knative.openshift.io/system-namespace=true
      Copy to Clipboard Toggle word wrap
    3. 标记 knative-eventing 命名空间:

      $ oc label namespace knative-eventing knative.openshift.io/system-namespace=true
      Copy to Clipboard Toggle word wrap
    4. 标记 knative-kafka 命名空间:

      $ oc label namespace knative-kafka knative.openshift.io/system-namespace=true
      Copy to Clipboard Toggle word wrap
  2. 在应用程序命名空间中创建一个 NetworkPolicy 对象,允许从带有 knative.openshift.io/system-namespace 标签的命名空间访问:

    NetworkPolicy 对象示例

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: <network_policy_name> 
    1
    
      namespace: <namespace> 
    2
    
    spec:
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              knative.openshift.io/system-namespace: "true"
      podSelector: {}
      policyTypes:
      - Ingress
    Copy to Clipboard Toggle word wrap

    1
    为您的网络策略提供名称。
    2
    应用程序所在的命名空间。

4.10. 配置修订超时

您可以在全局范围内或单独为修订版本配置超时持续时间,以控制请求上的时间。

4.10.1. 配置修订超时

您可以根据请求配置修订超时的默认秒数。

先决条件

  • 安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 在 OpenShift Container Platform 上,或具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群管理员权限。

流程

  • 选择配置修订超时的适当方法:

    • 要在全局范围内配置修订超时,请在 KnativeServing 自定义资源(CR)中设置 revision-timeout-seconds 字段:

      apiVersion: operator.knative.dev/v1beta1
      kind: KnativeServing
      metadata:
        name: knative-serving
        namespace: knative-serving
      spec:
        config:
          defaults:
            revision-timeout-seconds: "300"
      Copy to Clipboard Toggle word wrap
    • 通过在服务定义中设置 timeoutSeconds 字段来配置每个修订版本的超时:

      apiVersion: serving.knative.dev/v1
      kind: Service
      metadata:
        namespace: my-ns
      spec:
        template:
          spec:
            timeoutSeconds: 300
            containers:
            - image: ghcr.io/knative/helloworld-go:latest
      Copy to Clipboard Toggle word wrap

4.10.2. 配置最大修订超时

通过设置最大修订超时,您可以确保任何修订版本不会超过特定限制。

先决条件

  • 安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 在 OpenShift Container Platform 上,或具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群管理员权限。

流程

  • 要配置最大修订超时,请在 KnativeServing 自定义资源(CR)中设置 max-revision-timeout-seconds 字段:

    If this value is increased, the activator `terminationGracePeriodSeconds` should also be increased to prevent in-flight requests being disrupted.
    Copy to Clipboard Toggle word wrap
    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      config:
        defaults:
          max-revision-timeout-seconds: "600"
    Copy to Clipboard Toggle word wrap

第 5 章 调试无服务器应用程序

您可以使用各种方法对无服务器应用程序进行故障排除。

5.1. 检查终端输出

您可以检查部署命令输出,以查看部署是否成功。如果部署过程终止,您应该在输出中看到一条错误消息,该消息描述了部署失败的原因。这种类型的故障很可能是由于清单配置错误或无效命令而造成的。

流程

  • 在您部署和管理应用程序的客户端上打开命令输出。以下示例是 oc apply 命令失败后可能会看到的错误:

    Error from server (InternalError): error when applying patch:
    {"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"serving.knative.dev/v1\",\"kind\":\"Route\",\"metadata\":{\"annotations\":{},\"name\":\"route-example\",\"namespace\":\"default\"},\"spec\":{\"traffic\":[{\"configurationName\":\"configuration-example\",\"percent\":50}]}}\n"}},"spec":{"traffic":[{"configurationName":"configuration-example","percent":50}]}}
    to:
    &{0xc421d98240 0xc421e77490 default route-example STDIN 0xc421db0488 264682 false}
    for: "STDIN": Internal error occurred: admission webhook "webhook.knative.dev" denied the request: mutation failed: The route must have traffic percent sum equal to 100.
    ERROR: Non-zero return code '1' from command: Process exited with status 1
    Copy to Clipboard Toggle word wrap

    此输出表示您必须将路由流量百分比配置为等于 100。

5.2. 检查 pod 状态

您可能需要检查 Pod 对象的状态,以识别 Serverless 应用程序的问题。

流程

  1. 运行以下命令列出部署的所有 pod:

    $ oc get pods
    Copy to Clipboard Toggle word wrap

    输出示例

    NAME                                                      READY     STATUS             RESTARTS   AGE
    configuration-example-00001-deployment-659747ff99-9bvr4   2/2       Running            0          3h
    configuration-example-00002-deployment-5f475b7849-gxcht   1/2       CrashLoopBackOff   2          36s
    Copy to Clipboard Toggle word wrap

    在输出中,您可以看到所有带有所选数据状态的 pod。

  2. 运行以下命令,查看 pod 状态的详细信息:

    输出示例

    $ oc get pod <pod_name> --output yaml
    Copy to Clipboard Toggle word wrap

    在输出中,条件和 containerStatuses 字段对于调试可能特别有用。

5.3. 检查修订状态

您可能需要检查修订版本的状态,以识别 Serverless 应用程序的问题。

流程

  1. 如果使用 Configuration 对象配置路由,请运行以下命令获取为部署创建的 Revision 对象的名称:

    $ oc get configuration <configuration_name> --output jsonpath="{.status.latestCreatedRevisionName}"
    Copy to Clipboard Toggle word wrap

    您可以在 Route.yaml 文件中找到配置名称,该文件通过定义 OpenShift Route 资源来指定路由设置。

    如果您直接使用修订版本配置路由,请在 Route.yaml 文件中查找修订名称。

  2. 运行以下命令查询修订版本的状态:

    $ oc get revision <revision-name> --output yaml
    Copy to Clipboard Toggle word wrap

    就绪修订版本应具有 原因:ServiceReadystatus: "True",并在 其状态中键入:Ready 条件。如果存在这些条件,您可能需要检查 pod 状态或 Istio 路由。否则,资源状态包含错误消息。

5.4. 检查 Ingress 状态

您可能需要检查 Ingress 的状态,以识别 Serverless 应用程序的问题。

流程

  • 运行以下命令,检查 Ingress 的 IP 地址:

    $ oc get svc -n istio-system istio-ingressgateway
    Copy to Clipboard Toggle word wrap

    istio-ingressgateway 服务是 Knative 使用的 LoadBalancer 服务。

    如果没有外部 IP 地址,请运行以下命令:

    $ oc describe svc istio-ingressgateway -n istio-system
    Copy to Clipboard Toggle word wrap

    此命令打印没有置备 IP 地址的原因。最有可能是因为配额问题。

5.5. 检查路由状态

在某些情况下,Route 对象有问题。您可以使用 OpenShift CLI (oc)来检查其状态。

流程

  • 运行以下命令,查看部署应用程序的 Route 对象的状态:

    $ oc get route <route_name> --output yaml
    Copy to Clipboard Toggle word wrap

    <route_name > 替换为 Route 对象的名称。

    status 对象中的 conditions 对象在失败时说明原因。

5.6. 检查 Ingress 和 Istio 路由

有时,当 Istio 用作 Ingress 层时,Ingress 和 Istio 路由存在问题。您可以使用 OpenShift CLI (oc)查看它们的详细信息。

流程

  1. 运行以下命令列出所有 Ingress 资源及其对应的标签:

    $ oc get ingresses.networking.internal.knative.dev -o=custom-columns='NAME:.metadata.name,LABELS:.metadata.labels'
    Copy to Clipboard Toggle word wrap

    输出示例

    NAME            LABELS
    helloworld-go   map[serving.knative.dev/route:helloworld-go serving.knative.dev/routeNamespace:default serving.knative.dev/service:helloworld-go]
    Copy to Clipboard Toggle word wrap

    在这个输出中,标签 service.knative.dev/routeservice.knative.dev/routeNamespace 表示 Ingress 资源所在的 Route。应该会列出您的 Route 和 Ingress。

    如果您的 Ingress 不存在,路由控制器会假定您的 RouteService 对象的目标 Revision 对象未就绪。继续执行其他调试过程来诊断 Revision readiness 状态。

  2. 如果列出了 Ingress,请运行以下命令检查为路由创建的 ClusterIngress 对象:

    $ oc get ingresses.networking.internal.knative.dev <ingress_name> --output yaml
    Copy to Clipboard Toggle word wrap

    在输出的 status 部分中,如果 type=Ready 的状况的状态为 True,则 Ingress 可以正常工作。否则,输出中会包含错误消息。

  3. 如果 Ingress 的状态是 Ready,则代表有一个对应的 VirtualService 对象。运行以下命令,验证 VirtualService 对象的配置:

    $ oc get virtualservice -l networking.internal.knative.dev/ingress=<ingress_name> -n <ingress_namespace> --output yaml
    Copy to Clipboard Toggle word wrap

    VirtualService 对象中的网络配置必须与 IngressRoute 对象匹配。由于 VirtualService 对象不公开 Status 字段,您可能需要等待其设置传播。

第 6 章 Kourier 和 Istio ingresses

OpenShift Serverless 支持以下两个入口解决方案:

  • Kourier
  • 使用 Red Hat OpenShift Service Mesh 的 Istio

默认为 Kourier。

6.1. Kourier 和 Istio 入口解决方案

6.1.1. Kourier

Kourier 是 OpenShift Serverless 的默认入口解决方案。它具有以下属性:

  • 它基于 envoy 代理。
  • 它简单且轻量级。
  • 它提供 Serverless 必须提供其一组功能的基本路由功能。
  • 它支持基本可观察性和指标。
  • 它支持 Knative Service 路由的基本 TLS 终止。
  • 它只提供有限的配置和扩展选项。

6.1.2. 使用 OpenShift Service Mesh 的 Istio

使用 Istio 作为 OpenShift Serverless 的 ingress 解决方案启用一个额外的功能集,它基于 Red Hat OpenShift Service Mesh 提供的内容:

  • 所有连接之间的原生 mTLS
  • Serverless 组件是服务网格的一部分
  • 额外的可观察性和指标
  • 授权和身份验证支持
  • Red Hat OpenShift Service Mesh 支持的自定义规则和配置

但是,额外的功能会带来更高的开销和资源消耗。详情请参阅 Red Hat OpenShift Service Mesh 文档。

有关 Istio 要求和安装说明,请参阅 Serverless 文档中的"集成 Service Mesh with OpenShift Serverless"部分。

6.1.3. 流量配置和路由

无论您是否使用 Kourier 或 Istio,Knative Service 的流量都由 net-kourier-controllernet-istio-controllerknative-serving 命名空间中配置。

控制器读取 KnativeService 及其子自定义资源来配置入口解决方案。两个入口解决方案都提供了一个入口网关 pod,它成为流量路径的一部分。两个入口解决方案都基于 Envoy。默认情况下,每个 KnativeService 对象有两个路由:

  • 由 OpenShift 路由器转发 的集群外部路由,如 myapp-namespace.example.com
  • 包含集群域的 cluster-local 路由,如 myapp.namespace.svc.cluster.local。这个域可用于从 Knative 或其他用户工作负载调用 Knative 服务。

入口网关可以在服务模式或代理模式中转发请求:

  • 在 serving 模式中,请求直接进入 Knative 服务的 Queue-Proxy sidecar 容器。
  • 在代理模式中,请求首先通过 knative-serving 命名空间中的 Activator 组件。

模式选择取决于 Knative、Knative 服务和当前流量的配置。例如,如果 Knative Service 缩减为零,则请求将发送到 Activator 组件,该组件充当缓冲区,直到新的 Knative 服务 pod 启动为止。

第 7 章 服务传输加密

您可以启用 OpenShift Serverless Serving 传输加密,以允许使用 TLS 通过安全和加密的 HTTPS 连接传输数据。

重要

OpenShift Serverless Serving 传输加密只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

重要

服务传输加密仅适用于 Kourier 作为入口层。对于 Red Hat OpenShift Service Mesh,使用服务网格 mTLS 功能来确保加密的流量。

7.1. Serving 传输加密概述

OpenShift Serverless Serving 传输加密有三个部分:

外部域加密
在集群外部的入口层传输加密。例如,cluster-external 域,如 myapp-<namespace>.example.com
集群本地加密
在集群中的入口层上传输加密。例如,cluster-local 域,如 myapp.<namespace>.svc.cluster.local
system-internal 加密
ingress-gateway激活器queue-proxy Knative 内部组件之间的传输加密。
重要

control-plane 流量,包括 Kubernetes PreStopHooks、metadata 和 metrics,不包含用户数据且没有加密。

不同的部分彼此独立,可以单独启用和禁用。它们可以使用相同或不同的证书颁发机构(CA)为必要的证书签名。

注意

有关显示传输加密图,请参阅 OpenShift Serverless Serving Transport Encryption

7.1.1. 外部域加密

外部域的传输加密由集群的入口层处理,即 OpenShift Container Platform ingress 或 Red Hat OpenShift Service Mesh。

7.1.2. 集群本地加密

集群本地加密为集群本地域启用传输加密。它具有以下属性:

  • 证书通用名称(CN)或主题备用名称(SAN)包含 Knative Service 的 cluster-local 域,如 myapp.namespace.svc.cluster.local,myapp.namespace.svc,myapp.namespace.
  • ingress-controller 组件的 cluster-local 端点使用 SNI 来选择证书。
  • 要创建证书,Knative 依赖于 cert-manager,它需要安装和配置该功能才能正常工作。如需更多信息,请参阅 Red Hat OpenShift 的 cert-manager Operator
重要

调用者必须信任签署集群本地证书的 CA。这是 OpenShift Serverless 的范围。

7.1.3. system-internal 加密

system-internal 加密为 ingress-gatewayactivatorqueue-proxy Knative 内部组件启用传输加密。使用此配置时,这些组件托管 TLS 端点。

要使用这个功能,必须满足以下先决条件:

  • 要使 OpenShift Serverless 获取证书,必须安装并配置 cert-manager
  • 特定的 SAN 用于验证每个连接。每个组件都必须信任签发证书的 CA。为了满足此要求,OpenShift Serverless 系统组件会消耗并信任 CA 捆绑包。CA 捆绑包必须由集群管理员提供。

7.2. 选择证书签发者

签发者指的是 cert-manager issuers 和 cluster issuers。它们通过遵守证书签名请求来代表可生成签名证书的证书颁发机构(CA)。如需更多信息,请参阅有关签发者的 cert-manager 文档

根据您使用的加密功能,OpenShift Serverless 需要您的证书签发者能够签署某些证书。要识别您的证书签发者,请参阅 cert-manager integrations 列表,其中包含以下示例:

  • 存储在 Kubernetes secret 中的自定义 CA
  • HTTP-01 质询
  • DNS-01 质询
  • 自签名签发者

7.2.1. 兼容证书签发者

并非所有签发者类型都可用于每个 Knative Serving 加密功能。

  • 对于 cluster-local 加密,签发者必须能够为以下 cluster-local 域类型签名证书:

    • myapp.<namespace>
    • myapp.<namespace>.svc
    • myapp.<namespace>.svc.cluster.local

    由于 CA 通常不在集群中,因此无法使用自动证书管理环境(ACME)协议(DNS01/HTTP01)进行验证。您可以使用允许创建这些证书的签发者,如 cert-manager CA 签发者。

  • 对于系统内部加密,签发者必须能够使用以下主题备用名称(SAN)签署证书:

    • kn-routing
    • 格式 kn-user-<namespace> 格式的名称,其中 &lt;namespace> 是创建 Knative 服务的命名空间
    • data-plane.knative.dev

    Knative 要求这些 SAN 验证内部组件之间的连接。由于无法使用 ACME 协议(DNS01/HTTP01),所以您必须配置允许创建这些证书的签发者,如 cert-manager CA issuer。

7.3. 设置 OpenShift Serverless 传输加密

先决条件

  • 您可以访问具有集群管理员权限的 OpenShift Container Platform 帐户。
  • 安装 {oc-first}。
  • 为 Red Hat OpenShift 安装 cert-manager Operator。
  • 安装 OpenShift Serverless Operator。
重要

如果在为 Red Hat OpenShift 安装 cert-manager Operator 前安装 OpenShift Serverless Operator,则必须重启 knative-serving 命名空间中的 controller 和 activator 部署。重启这些部署失败可防止 Knative 创建必要的 cert-manager 资源,这会导致待处理的 Knative Services,并防止启用 Knative Serving cert-manager 集成。

7.3.1. 配置自助集群签发者

以下流程使用 SelfSigned issuer 作为 root 证书。有关此方法的影响和限制的详情,请参考 SelfSigned cert-manager 文档

如果您管理自己的特定于公司的私钥基础架构(PKI),请使用 CA 签发者。如需更多信息,请参阅 CA 签发者的 cert-manager 文档

流程

  1. 创建 SelfSigned ClusterIssuer 自定义资源(CR):

    ClusterIssuer CR 示例

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: knative-serving-selfsigned-issuer
    spec:
      selfSigned: {}
    Copy to Clipboard Toggle word wrap

  2. 运行以下命令来应用 ClusterIssuer CR:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap
  3. 创建引用 ClusterIssuer CR 的 root 证书:

    root 证书示例

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: knative-serving-selfsigned-ca
      namespace: cert-manager 
    1
    
    spec:
      secretName: knative-serving-ca 
    2
    
    
      isCA: true
      commonName: selfsigned-ca
      privateKey:
        algorithm: ECDSA
        size: 256
    
      issuerRef:
        name: knative-serving-selfsigned-issuer
        kind: ClusterIssuer
        group: cert-manager.io
    Copy to Clipboard Toggle word wrap

    1
    默认情况下,Red Hat OpenShift 命名空间 cert-manager 的 cert-manager Operator。
    2
    之后用于 Knative Serving 的 ClusterIssuer CR 的 secret 名称。
  4. 运行以下命令来应用 证书 CR:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap

7.3.2. 创建由 Serving 使用的 ClusterIssuer

要启用通过 Serving 使用证书,您必须创建一个集群签发者。

流程

  1. 为 Serving 创建 knative-serving-ca-issuer ClusterIssuer

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: knative-serving-ca-issuer
    spec:
      ca:
        secretName: knative-serving-ca 
    1
    Copy to Clipboard Toggle word wrap
    1
    Red Hat OpenShift 命名空间(默认为 cert-manager)的cert-manager Operator 中的 secret 名称,其中包含可供 OpenShift Serverless Serving 组件用于新证书的证书。
  2. 运行以下命令来应用 ClusterIssuer 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap

7.3.3. 配置传输加密

配置传输加密由两个部分组成:

  1. 指定要使用的 ClusterIssuer 签发者:

    • clusterLocalIssuerRef: 用于 ingress 的 cluster-local-domain 证书的签发者。
    • systemInternalIssuerRef: Knative 内部组件使用的 system-internal-tls 证书的签发者。
  2. 指定要使用的传输加密功能:

    • cluster-local-domain-tls :启用 cluster-local 域的传输加密功能
    • system-internal-tls :为 OpenShift Serverless Serving 内部组件启用传输加密功能。

流程

  1. KnativeServing 资源中启用传输加密:

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      ...
      config:
        certmanager:
          clusterLocalIssuerRef: |
            kind: ClusterIssuer
            name: knative-serving-ca-issuer 
    1
    
          systemInternalIssuerRef: |
            kind: ClusterIssuer
            name: knative-serving-ca-issuer 
    2
    
        network:
          cluster-local-domain-tls: Enabled 
    3
    
          system-internal-tls: Enabled 
    4
    Copy to Clipboard Toggle word wrap
    1
    为每个功能定义集群签发者。可以使用相同的或单独的集群签发者。
    2
    定义集群签发者。
    3
    启用 cluster-local-domain-tls 功能。这可以单独启用或禁用此功能。
    4
    启用 system-internal-tls 功能。
  2. 运行以下命令来应用 KnativeServing 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap
  3. 另外,还可更改 Ingress Controller 中的 defaultCertificate 值:

    apiVersion: operator.openshift.io/v1
    kind: IngressController
     ...
    spec:
      defaultCertificate:
        name: ca-ingress-cert
    Copy to Clipboard Toggle word wrap
  4. 如果更改了 defaultCertificate 值,则必须在 KnativeServing 自定义资源的 openshift-ingress-default-certificate 字段中指定自定义证书名称。

    例如,如果自定义证书名称是 ca-ingress-cert,请添加以下配置:

    ...
    spec:
      config:
        network:
          system-internal-tls: Enabled
          openshift-ingress-default-certificate: "ca-ingress-cert"
    ...
    Copy to Clipboard Toggle word wrap
  5. 如果启用了 cluster-local-domain-tlssystem-internal-tls,请运行以下命令重启 Controller 组件。

    重要

    当启用了 cluster-local-domain-tlssystem-internal-tls 功能时,您必须重启 Controller 组件以启用 Knative Serving cert-manager 集成。

    $ oc rollout restart deploy/controller -n knative-serving
    Copy to Clipboard Toggle word wrap
  6. 如果启用了 system-internal-tls,请运行以下命令重启 Activator 组件。

    重要

    激活 system-internal-tls 功能时,您必须重启 Activator 组件来重新配置其内部 Web 服务器,因为在运行时无法实现这个功能。

    $ oc rollout restart deploy/activator -n knative-serving
    Copy to Clipboard Toggle word wrap

7.4. 信任配置

当您启用任何传输加密功能时,您必须确保所有调用证书颁发机构(CA)的客户端都发出用于传输加密的证书。

有很多信任必须保证的:

  • 集群外部客户端,如浏览器或其他应用程序。这是 OpenShift Serverless 的范围。
  • OpenShift Serverless 系统组件,如 Activator、Queue-Proxy 和 Ingress-Controller。
  • 集群内部客户端,如 Knative Service 或其他工作负载。

为确保 OpenShift Serverless Serving 组件和 Knative Services 信任发布证书的 CA,您可以在以下命名空间中创建 ConfigMap,标签为 networking.knative.dev/trust-bundle: true

knative-serving
用于 OpenShift Serverless Serving 的系统组件。
knative-serving-ingress
对于 OpenShift Serverless Serving 的入口层。
istio-system 或您自己的 Service Mesh 命名空间
启用 Service Mesh 集成。

Knative 会使用此标签读取 ConfigMap 中的所有数据密钥,而不考虑名称。一个密钥可以包含一个或多个 CA 或中间证书。如果它们有效,则会将它们添加到 Knative 组件的信任存储中。

这是一个 ConfigMap 示例:

apiVersion: v1
data:
  cacerts.pem: | 
1

    -----BEGIN CERTIFICATE-----
    MIIDDTCCAfWgAwIBAgIQMQuip05h7NLQq2TB+j9ZmTANBgkqhkiG9w0BAQsFADAW
    MRQwEgYDVQQDEwtrbmF0aXZlLmRldjAeFw0yMzExMjIwOTAwNDhaFw0yNDAyMjAw
    OTAwNDhaMBYxFDASBgNVBAMTC2tuYXRpdmUuZGV2MIIBIjANBgkqhkiG9w0BAQEF
    AAOCAQ8AMIIBCgKCAQEA3clC3CV7sy0TpUKNuTku6QmP9z8JUCbLCPCLACCUc1zG
    FEokqOva6TakgvAntXLkB3TEsbdCJlNm6qFbbko6DBfX6rEggqZs40x3/T+KH66u
    4PvMT3fzEtaMJDK/KQOBIvVHrKmPkvccUYK/qWY7rgBjVjjLVSJrCn4dKaEZ2JNr
    Fd0KNnaaW/dP9/FvviLqVJvHnTMHH5qyRRr1kUGTrc8njRKwpHcnUdauiDoWRKxo
    Zlyy+MhQfdbbyapX984WsDjCvrDXzkdGgbRNAf+erl6yUm6pHpQhyFFo/zndx6Uq
    QXA7jYvM2M3qCnXmaFowidoLDsDyhwoxD7WT8zur/QIDAQABo1cwVTAOBgNVHQ8B
    Af8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAd
    BgNVHQ4EFgQU7p4VuECNOcnrP9ulOjc4J37Q2VUwDQYJKoZIhvcNAQELBQADggEB
    AAv26Vnk+ptQrppouF7yHV8fZbfnehpm07HIZkmnXO2vAP+MZJDNrHjy8JAVzXjt
    +OlzqAL0cRQLsUptB0btoJuw23eq8RXgJo05OLOPQ2iGNbAATQh2kLwBWd/CMg+V
    KJ4EIEpF4dmwOohsNR6xa/JoArIYH0D7gh2CwjrdGZr/tq1eMSL+uZcuX5OiE44A
    2oXF9/jsqerOcH7QUMejSnB8N7X0LmUvH4jAesQgr7jo1JTOBs7GF6wb+U76NzFa
    8ms2iAWhoplQ+EHR52wffWb0k6trXspq4O6v/J+nq9Ky3vC36so+G1ZFkMhCdTVJ
    ZmrBsSMWeT2l07qeei2UFRU=
    -----END CERTIFICATE-----
kind: ConfigMap
metadata:
  labels:
    networking.knative.dev/trust-bundle: "true"
  name: knative-bundle 
2

  namespace: knative-serving
Copy to Clipboard Toggle word wrap
1
提供组件信任包含有效 PEM 编码 CA 捆绑包的所有密钥。
2
您可以使用任意名称。
重要

当创建或更新 CA 捆绑包 ConfigMap 时,Serving 组件会自动获取它们,并将 CA 或中间证书添加到其 CA 信任存储中。每个新的 HTTP 连接都会刷新信任存储。

7.4.2. 自定义工作负载上的信任配置

由于 OpenShift Serverless Serving 不控制所有工作负载和管理信任,因此高度依赖于您的运行时和语言,自定义工作负载不在 OpenShift Serverless 范围内。以下是自定义工作负载的其他选项:

  • 将 CA 捆绑包添加到构建时的容器镜像。请注意,这会使 CA 轮转复杂,因为您必须在 CA 轮转时重建并重新部署每个应用程序。
  • 将 CA 捆绑包挂载到文件系统,如 Secret 或 ConfigMap,并确保您的应用程序使用它来验证 TLS 连接。
  • 从环境变量读取 CA 捆绑包,并确保您的应用程序使用它来验证 TLS 连接。
  • 使用 Kubernetes API 从 secret 或 ConfigMap 访问 CA 捆绑包,并确保应用程序使用它来验证 TLS 连接。

7.5. 确保无缝 CA 轮转

确保无缝 CA 轮转对于避免服务停机或处理紧急情况至关重要。

流程

  1. 创建新的 CA 证书。
  2. 将新 CA 证书的公钥添加到 CA 信任捆绑包中,如 "Trust configuration for OpenShift Serverless Operator Serving components 和 Knative Services" 部分所述。保留现有 CA 的公钥。
  3. 确保所有客户端都已使用最新的 CA 信任捆绑包集合。OpenShift Serverless Serving 组件将自动重新载入更改的 CA 信任捆绑包。
  4. 如果您有自定义工作负载使用信任捆绑包,请重新加载或相应地重启它们。
  5. 更新 knative-serving-ca-issuer 集群签发者,以引用包含新 CA 证书的 secret。
  6. 等待 cert-manager 续订所有证书或强制它续订所有证书。如需更多信息,请参阅 cert-manager 文档。
  7. CA 轮转完全完成后,您可以从信任捆绑包 configmap 中删除旧 CA 的公钥。有足够的时间对所有组件应用更改。

7.6. 验证启用传输加密

流程

  1. 创建 Knative Service:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: test-webapp
      namespace: test-namespace
    spec:
      template:
        spec:
          containers:
            - image: docker.io/openshift/hello-openshift
              env:
                - name: RESPONSE
                  value: "Hello Serverless!"
    Copy to Clipboard Toggle word wrap
  2. 运行以下命令来应用 Knative Service YAML:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap
  3. 检查 Knative Service 的状态:

    示例命令

    $ oc get ksvc -n test-namespace -o yaml
    Copy to Clipboard Toggle word wrap

    输出示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: test-webapp
      namespace: test-namespace
    # spec:
    # ...
    status:
      address:
        # cluster-local-domain:
        url: https://helloworld.test.svc.cluster.local 
    1
    Copy to Clipboard Toggle word wrap

    1
    如果您启用了 cluster-local-domain-tls,您将看到 HTTPS URL。
  4. 要验证 system-internal-tls 是否已启用,请运行以下命令来检查 Queue-Proxy 日志的输出:

    示例命令

    $ oc logs your-pod -n test-namespace -c queue-proxy | grep -E 'certDir|Certificate|tls'
    Copy to Clipboard Toggle word wrap

    如果您看到类似如下的行,则启用了 system-internal-tls

    {"severity":"INFO","timestamp":"2024-01-03T07:07:32.892810888Z","logger":"queueproxy","caller":"certificate/watcher.go:62","message":"Starting to watch the following directories for changes{certDir 15 0 /var/lib/knative/certs <nil>} {keyDir 15 0 /var/lib/knative/certs <nil>}","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"}
    {"severity":"INFO","timestamp":"2024-01-03T07:07:32.89397512Z","logger":"queueproxy","caller":"certificate/watcher.go:131","message":"Certificate and/or key have changed on disk and were reloaded.","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"}
    {"severity":"INFO","timestamp":"2024-01-03T07:07:32.894232939Z","logger":"queueproxy","caller":"sharedmain/main.go:282","message":"Starting tls server admin:8022","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"}
    {"severity":"INFO","timestamp":"2024-01-03T07:07:32.894268548Z","logger":"queueproxy","caller":"sharedmain/main.go:282","message":"Starting tls server main:8112","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"}
    Copy to Clipboard Toggle word wrap

第 8 章 流量分割

8.1. 流量分割概述

在 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 设置。

8.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
Copy to Clipboard Toggle word wrap

以下示例显示了一个 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
Copy to Clipboard Toggle word wrap

以下示例演示了如何扩展 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
Copy to Clipboard Toggle word wrap

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

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

8.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>
    Copy to Clipboard Toggle word wrap

    其中:

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

    示例命令

    $ kn service update showcase --traffic @latest=20,stable=80
    Copy to Clipboard Toggle word wrap

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

    示例命令

    $ kn service update showcase --traffic @latest=10,stable=60
    Copy to Clipboard Toggle word wrap

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

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

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

8.4.1. Knative CLI 流量分割标志

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

Expand
标记操作重复

--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

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

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

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

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

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

8.4.1.2. 修订版本的自定义 URL

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

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

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

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

$ kn service update <service_name> --tag @latest=example-tag
Copy to Clipboard Toggle word wrap
8.4.1.2.2. 示例:从修订中删除标签

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

注意

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

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

$ kn service update <service_name> --untag example-tag
Copy to Clipboard Toggle word wrap

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

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

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

先决条件

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

流程

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

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

    图 8.1. 无服务器应用程序

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

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

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

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

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

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

先决条件

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

流程

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

    $ oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}'
    Copy to Clipboard Toggle word wrap

    示例命令

    $ oc get ksvc showcase -o=jsonpath='{.status.latestCreatedRevisionName}'
    Copy to Clipboard Toggle word wrap

    输出示例

    $ showcase-00001
    Copy to Clipboard Toggle word wrap

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

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

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

    $ oc get ksvc <service_name> -o=jsonpath='{.status.latestCreatedRevisionName}'
    Copy to Clipboard Toggle word wrap

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

  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
    ...
    Copy to Clipboard Toggle word wrap

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

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

    $ oc get ksvc <service_name> --output jsonpath="{.status.traffic[*].url}"
    Copy to Clipboard Toggle word wrap

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

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

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

    ...
    spec:
      traffic:
        - revisionName: <first_revision_name>
          percent: 50
        - revisionName: <second_revision_name>
          percent: 50
          tag: v2
    ...
    Copy to Clipboard Toggle word wrap

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

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

    ...
    spec:
      traffic:
        - revisionName: <first_revision_name>
          percent: 0
        - revisionName: <second_revision_name>
          percent: 100
          tag: v2
    ...
    Copy to Clipboard Toggle word wrap

    提示

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

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

第 9 章 External 和 Ingress 路由

9.1. 路由概述

Knative 利用 OpenShift Container Platform TLS 终止来为 Knative 服务提供路由。创建 Knative 服务时,会自动为该服务创建一个 OpenShift Container Platform 路由。此路由由 OpenShift Serverless Operator 管理。OpenShift Container Platform 路由通过与 OpenShift Container Platform 集群相同的域公开 Knative 服务。

您可以禁用 OpenShift Container Platform 路由的 Operator 控制,以便您可以配置 Knative 路由来直接使用 TLS 证书。

Knative 路由也可以与 OpenShift Container Platform 路由一起使用,以提供额外的精细路由功能,如流量分割。

9.2. 自定义标签和注解

OpenShift Container Platform 路由支持使用自定义标签和注解,您可以通过修改 Knative 服务的元数据规格来配置这些标签和注解。自定义标签和注解从服务传播到 Knative 路由,然后传播到 Knative ingress,最后传播到 OpenShift Container Platform 路由。

先决条件

  • 您必须已在 OpenShift Container Platform 集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 安装 OpenShift CLI (oc) 。

流程

  1. 创建包含您要传播到 OpenShift Container Platform 路由的标签或注解的 Knative 服务:

    • 使用 YAML 创建服务:

      使用 YAML 创建的服务示例

      apiVersion: serving.knative.dev/v1
      kind: Service
      metadata:
        name: <service_name>
        labels:
          <label_name>: <label_value>
        annotations:
          <annotation_name>: <annotation_value>
      ...
      Copy to Clipboard Toggle word wrap

    • 要使用 Knative (kn) CLI 创建服务,请输入:

      使用 kn 命令创建的服务示例

      $ kn service create <service_name> \
        --image=<image> \
        --annotation <annotation_name>=<annotation_value> \
        --label <label_value>=<label_value>
      Copy to Clipboard Toggle word wrap

  2. 通过检查以下命令的输出来验证 OpenShift Container Platform 路由是否已使用您添加的注解或标签创建:

    验证命令示例

    $ oc get routes.route.openshift.io \
         -l serving.knative.openshift.io/ingressName=<service_name> \ 
    1
    
         -l serving.knative.openshift.io/ingressNamespace=<service_namespace> \ 
    2
    
         -n knative-serving-ingress -o yaml \
             | grep -e "<label_name>: \"<label_value>\""  -e "<annotation_name>: <annotation_value>" 
    3
    Copy to Clipboard Toggle word wrap

    1
    使用服务的名称。
    2
    使用创建服务的命名空间。
    3
    将您的值用于标签和注解名称和值。

9.3. 为 Knative 服务配置路由

如果要将 Knative 服务配置为在 OpenShift Container Platform 上使用 TLS 证书,则必须禁用 OpenShift Serverless Operator 为服务自动创建路由,而是手动为服务创建路由。

注意

完成以下步骤时,不会创建 knative-serving-ingress 命名空间中的默认 OpenShift Container Platform 路由。但是,应用程序的 Knative 路由仍然在此命名空间中创建。

先决条件

  • OpenShift Serverless Operator 和 Knative Serving 组件必须安装在 OpenShift Container Platform 集群中。
  • 安装 OpenShift CLI (oc) 。

流程

  1. 创建包含 service.knative.openshift.io/disableRoute=true 注解的 Knative 服务:

    重要

    service.knative.openshift.io/disableRoute=true 注解指示 OpenShift Serverless 不自动为您创建路由。但是,该服务仍然会显示 URL 并达到 Ready 状态。除非使用与 URL 中主机名相同的主机名创建自己的路由,此 URL 才能在外部工作。

    1. 创建 Knative Service 资源:

      资源示例

      apiVersion: serving.knative.dev/v1
      kind: Service
      metadata:
        name: <service_name>
        annotations:
          serving.knative.openshift.io/disableRoute: "true"
      spec:
        template:
          spec:
            containers:
            - image: <image>
      ...
      Copy to Clipboard Toggle word wrap

    2. 应用 Service 资源:

      $ oc apply -f <filename>
      Copy to Clipboard Toggle word wrap
    3. 可选。使用 kn service create 命令创建 Knative 服务:

      kn 命令示例

      $ kn service create <service_name> \
        --image=gcr.io/knative-samples/helloworld-go \
        --annotation serving.knative.openshift.io/disableRoute=true
      Copy to Clipboard Toggle word wrap

  2. 验证没有为服务创建 OpenShift Container Platform 路由:

    示例命令

    $ $ oc get routes.route.openshift.io \
      -l serving.knative.openshift.io/ingressName=$KSERVICE_NAME \
      -l serving.knative.openshift.io/ingressNamespace=$KSERVICE_NAMESPACE \
      -n knative-serving-ingress
    Copy to Clipboard Toggle word wrap

    您将看到以下输出:

    No resources found in knative-serving-ingress namespace.
    Copy to Clipboard Toggle word wrap
  3. knative-serving-ingress 命名空间中创建 Route 资源:

    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      annotations:
        haproxy.router.openshift.io/timeout: 600s 
    1
    
      name: <route_name> 
    2
    
      namespace: knative-serving-ingress 
    3
    
    spec:
      host: <service_host> 
    4
    
      port:
        targetPort: http2
      to:
        kind: Service
        name: kourier
        weight: 100
      tls:
        insecureEdgeTerminationPolicy: Allow
        termination: edge 
    5
    
        key: |-
          -----BEGIN PRIVATE KEY-----
          [...]
          -----END PRIVATE KEY-----
        certificate: |-
          -----BEGIN CERTIFICATE-----
          [...]
          -----END CERTIFICATE-----
        caCertificate: |-
          -----BEGIN CERTIFICATE-----
          [...]
          -----END CERTIFICATE----
      wildcardPolicy: None
    Copy to Clipboard Toggle word wrap
    1
    OpenShift Container Platform 路由的超时值。您必须设置与 max-revision-timeout-seconds 设置相同的值(默认为 600s )。
    2
    OpenShift Container Platform 路由的名称。
    3
    OpenShift Container Platform 路由的命名空间。这必须是 knative-serving-ingress
    4
    用于外部访问的主机名。您可以将其设置为 <service_name>-<service_namespace>.<domain>
    5
    您要使用的证书。目前,只支持 边缘(edge) 终止。
  4. 应用 Route 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap

9.4. 外部路由的 URL 方案

用于增强安全性,外部路由的 URL 方案默认为 HTTPS。这个方案由 KnativeServing 自定义资源 (CR) spec 中的 default-external-scheme 键决定。

9.4.1. 为外部路由设置 URL 方案

默认规格

...
spec:
  config:
    network:
      default-external-scheme: "https"
...
Copy to Clipboard Toggle word wrap

您可以通过修改 default-external-scheme 键来覆盖默认的 spec 以使用 HTTP:

HTTP 覆盖规格

...
spec:
  config:
    network:
      default-external-scheme: "http"
...
Copy to Clipboard Toggle word wrap

9.5. 集群本地可用性

默认情况下,Knative 服务会发布到一个公共 IP 地址。被发布到一个公共 IP 地址意味着 Knative 服务是公共应用程序,并有一个公开访问的 URL。

可以从集群以外访问公开的 URL。但是,开发人员可能需要构建后端服务,这些服务只能从集群内部访问(称为 私有服务 )。开发人员可以使用 networking.knative.dev/visibility=cluster-local 标签标记集群中的各个服务,使其私有。

重要

对于 OpenShift Serverless 1.15.0 及更新的版本,service.knative.dev/visibility 标签不再可用。您必须更新现有服务来改用 networking.knative.dev/visibility 标签。

9.5.1. 将集群可用性设置为集群本地

先决条件

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

流程

  • 通过添加 networking.knative.dev/visibility=cluster-local 标签来设置服务的可见性:

    $ oc label ksvc <service_name> networking.knative.dev/visibility=cluster-local
    Copy to Clipboard Toggle word wrap

验证

  • 输入以下命令并查看输出结果,检查您的服务的 URL 是否现在格式为 http://<service_name>.<namespace>.svc.cluster.local

    $ oc get ksvc
    Copy to Clipboard Toggle word wrap

    输出示例

    NAME            URL                                                                         LATESTCREATED     LATESTREADY       READY   REASON
    hello           http://hello.default.svc.cluster.local                                      hello-tx2g7       hello-tx2g7       True
    Copy to Clipboard Toggle word wrap

9.5.2. 为集群本地服务启用 TLS 身份验证

对于集群本地服务,使用 Kourier 本地网关 kourier-internal。如果要针对 Kourier 本地网关使用 TLS 流量,则必须在本地网关中配置您自己的服务器证书。

先决条件

  • 安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 有管理员权限。
  • 已安装 OpenShift (oc) CLI。

流程

  1. knative-serving-ingress 命名空间中部署服务器证书:

    $ export san="knative"
    Copy to Clipboard Toggle word wrap
    注意

    需要主题备用名称(SAN)验证,以便这些证书能够向 <app_name>.<namespace>.svc.cluster.local 提供请求。

  2. 生成 root 密钥和证书:

    $ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
        -subj '/O=Example/CN=Example' \
        -keyout ca.key \
        -out ca.crt
    Copy to Clipboard Toggle word wrap
  3. 生成使用 SAN 验证的服务器密钥:

    $ openssl req -out tls.csr -newkey rsa:2048 -nodes -keyout tls.key \
      -subj "/CN=Example/O=Example" \
      -addext "subjectAltName = DNS:$san"
    Copy to Clipboard Toggle word wrap
  4. 创建服务器证书:

    $ openssl x509 -req -extfile <(printf "subjectAltName=DNS:$san") \
      -days 365 -in tls.csr \
      -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt
    Copy to Clipboard Toggle word wrap
  5. 为 Kourier 本地网关配置 secret:

    1. 从前面的步骤创建的证书,在 knative-serving-ingress 命名空间中部署 secret:

      $ oc create -n knative-serving-ingress secret tls server-certs \
          --key=tls.key \
          --cert=tls.crt --dry-run=client -o yaml | oc apply -f -
      Copy to Clipboard Toggle word wrap
    2. 更新 KnativeServing 自定义资源 (CR) spec,以使用 Kourier 网关创建的 secret:

      KnativeServing CR 示例

      ...
      spec:
        config:
          kourier:
            cluster-cert-secret: server-certs
      ...
      Copy to Clipboard Toggle word wrap

Kourier 控制器在不重启该服务的情况下设置证书,因此您不需要重启 pod。

您可以通过端口 443 访问 Kourier 内部服务,方法是从客户端挂载并使用 ca.crt

9.6. Kourier 网关服务类型

Kourier 网关默认作为 ClusterIP 服务类型公开。此服务类型由 KnativeServing 自定义资源 (CR) 中的 service-type ingress spec 决定。

默认规格

...
spec:
  ingress:
    kourier:
      service-type: ClusterIP
...
Copy to Clipboard Toggle word wrap

9.6.1. 设置 Kourier 网关服务类型

您可以通过修改 service-type spec 来覆盖默认服务类型来使用负载均衡器服务类型:

LoadBalancer 覆盖规格

...
spec:
  ingress:
    kourier:
      service-type: LoadBalancer
...
Copy to Clipboard Toggle word wrap

9.7. 使用 HTTP2 和 gRPC

OpenShift Serverless 只支持不安全或边缘终端路由。不安全或边缘终端路由不支持 OpenShift Container Platform 中的 HTTP2。这些路由也不支持 gRPC,因为 gRPC 由 HTTP2 传输。如果您在应用程序中使用这些协议,则必须使用入口(ingress)网关直接调用应用程序。要做到这一点,您必须找到 ingress 网关的公共地址以及应用程序的特定主机。

重要

此方法适用于 OpenShift Container Platform 4.10 及更新的版本。有关旧版本,请参阅以下部分。

先决条件

  • 在集群上安装 OpenShift Serverless Operator 和 Knative Serving。
  • 安装 OpenShift CLI (oc) 。
  • 创建 Knative 服务。
  • 升级 OpenShift Container Platform 4.10 或更高版本。
  • 在 OpenShift Ingress 控制器中启用 HTTP/2。

流程

  1. serverless.openshift.io/default-enable-http2=true 注解添加到 KnativeServing 自定义资源中:

    $ oc annotate knativeserving <your_knative_CR> -n knative-serving serverless.openshift.io/default-enable-http2=true
    Copy to Clipboard Toggle word wrap
  2. 添加注解后,您可以验证 Kourier 服务的 appProtocol 值是否为 h2c

    $ oc get svc -n knative-serving-ingress kourier -o jsonpath="{.spec.ports[0].appProtocol}"
    Copy to Clipboard Toggle word wrap

    输出示例

    h2c
    Copy to Clipboard Toggle word wrap

  3. 现在,您可以对外部流量使用 HTTP/2 协议的 gRPC 框架,例如:

    import "google.golang.org/grpc"
    
    grpc.Dial(
       YOUR_URL, 
    1
    
       grpc.WithTransportCredentials(insecure.NewCredentials())), 
    2
    
    )
    Copy to Clipboard Toggle word wrap
    1
    您的 ksvc URL。
    2
    您的证书。

9.8. 在 OpenShift ingress 分片中使用 Serving

您可以在 OpenShift ingress 分片中使用 Knative Serving 来根据域分割入口流量。这可让您更有效地管理和将网络流量路由到集群的不同部分。

注意

即使 OpenShift ingress 分片可用,OpenShift Serverless 流量仍然通过单个 Knative Ingress Gateway 和 knative-serving 项目中的 activator 组件进行路由。

有关隔离网络流量的更多信息,请参阅使用 Service Mesh 将网络流量与 OpenShift Serverless 隔离

先决条件

  • 安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。

9.8.1. 配置 OpenShift ingress 分片

在配置 Knative Serving 前,您必须配置 OpenShift ingress 分片。

流程

  • 使用 IngressController CR 中的标签选择器配置 OpenShift Serverless,以匹配具有不同域的特定入口分片:

    IngressController CR 示例

    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: ingress-dev 
    1
    
      namespace: openshift-ingress-operator
    spec:
      routeSelector:
        matchLabels:
          router: dev 
    2
    
      domain: "dev.serverless.cluster.example.com" 
    3
    
      # ...
    ---
    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: ingress-prod 
    4
    
      namespace: openshift-ingress-operator
    spec:
      routeSelector:
        matchLabels:
          router: prod 
    5
    
      domain: "prod.serverless.cluster.example.com" 
    6
    
      # ...
    Copy to Clipboard Toggle word wrap

    1
    第一个入口分片的名称。
    2
    ingress-dev 分片匹配的标签选择器。
    3
    ingress-dev 分片的自定义域。
    4
    第二个入口分片的名称。
    5
    ingress-prod 分片匹配的标签选择器。
    6
    ingress-prod 分片的自定义域。

9.8.2. 在 KnativeServing CR 中配置自定义域

配置 OpenShift ingress 分片后,您必须配置 Knative Serving 以匹配它们。

流程

  • KnativeServing CR 中,通过添加 spec.config.domain 字段,将 Serving 配置为使用与入口分片相同的域和标签:

    KnativeServing CR 示例

    spec:
      config:
        domain: 
    1
    
          dev.serverless.cluster.example.com: |
            selector:
              router: dev
          prod.serverless.cluster.example.com: |
            selector:
              router: prod
      # ...
    Copy to Clipboard Toggle word wrap

    1
    这些值需要与入口分片配置中的值匹配。

9.8.3. 在 Knative Service 中目标特定的入口分片

配置 ingress 分片和 Knative Serving 后,您可以使用标签在 Knative Service 资源中以特定入口分片为目标。

流程

  • Service CR 中,添加与特定分片匹配的标签选择器:

    Service CR 示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: hello-dev
      labels:
        router: dev 
    1
    
    spec:
      template:
        spec:
          containers:
          - image: docker.io/openshift/hello-openshift
    ---
    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: hello-prod
      labels:
        router: prod 
    2
    
    spec:
      template:
        spec:
          containers:
          - image: docker.io/openshift/hello-openshift
      # ...
    Copy to Clipboard Toggle word wrap

    1 2
    标签必须与 KnativeServing CR 中的配置匹配。

9.8.4. 使用 OpenShift ingress 分片配置验证 Serving

配置 ingress 分片、Knative Serving 和服务后,您可以验证服务是否使用正确的路由和所选入口分片。

流程

  1. 运行以下命令输出集群中服务的信息:

    $ oc get ksvc
    Copy to Clipboard Toggle word wrap

    输出示例

    NAME         URL                                                             LATESTCREATED      LATESTREADY        READY   REASON
    hello-dev    https://hello-dev-default.dev.serverless.cluster.example.com    hello-dev-00001    hello-dev-00001    True
    hello-prod   https://hello-prod-default.prod.serverless.cluster.example.com  hello-prod-00001   hello-prod-00001   True
    Copy to Clipboard Toggle word wrap

  2. 运行以下命令,验证您的服务使用正确的路由和所选入口分片:

    $ oc get route -n knative-serving-ingress -o jsonpath='{range .items[*]}{@.metadata.name}{" "}{@.spec.host}{" "}{@.status.ingress[*].routerName}{"\n"}{end}'
    Copy to Clipboard Toggle word wrap

    输出示例

    route-19e6628b-77af-4da0-9b4c-1224934b2250-323461616533 hello-prod-default.prod.serverless.cluster.example.com ingress-prod
    route-cb5085d9-b7da-4741-9a56-96c88c6adaaa-373065343266 hello-dev-default.dev.serverless.cluster.example.com ingress-dev
    Copy to Clipboard Toggle word wrap

第 10 章 HTTP 配置

10.1. 全局 HTTPS 重定向

HTTPS 重定向为传入的 HTTP 请求提供重定向。这些重定向的 HTTP 请求会被加密。您可以通过为 KnativeServing 自定义资源 (CR) 配置 httpProtocol spec,为集群中的所有服务启用 HTTPS 重定向。

10.1.1. HTTPS 重定向全局设置

启用 HTTPS 重定向的 KnativeServing CR 示例

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: knative-serving
spec:
  config:
    network:
      httpProtocol: "redirected"
...
Copy to Clipboard Toggle word wrap

10.2. 每个服务的 HTTPS 重定向

您可以通过配置 networking.knative.dev/http-option 注解来为服务启用或禁用 HTTPS 重定向。

10.2.1. 为服务重定向 HTTPS

以下示例演示了如何在 Knative Service YAML 对象中使用此注解:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: example
  namespace: default
  annotations:
    networking.knative.dev/http-protocol: "redirected"
spec:
  ...
Copy to Clipboard Toggle word wrap

10.3. 对 HTTP/1 的完整双工支持

您可以通过配置 features.knative.dev/http-full-duplex 注解来为服务启用 HTTP/1 全双工支持。

注意

在启用前验证您的 HTTP 客户端,因为早期版本客户端可能不支持 HTTP/1 全双工。

以下示例演示了如何在修订 spec 级别的 Knative Service YAML 对象中使用此注解:

为 HTTP/1 提供完整双工支持的 KnativeServing CR 示例

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: example-service
  namespace: default
spec:
  template:
    metadata:
      annotations:
        features.knative.dev/http-full-duplex: "Enabled"
...
Copy to Clipboard Toggle word wrap

第 11 章 配置对 Knative 服务的访问

11.1. 为 Knative 服务配置 JSON Web 令牌身份验证

OpenShift Serverless 当前没有用户定义的授权功能。要为部署添加用户定义的授权,您必须将 OpenShift Serverless 与 Red Hat OpenShift Service Mesh 集成,然后为 Knative 服务配置 JSON Web Token (JWT) 身份验证和 sidecar 注入。

您可以使用 Service Mesh 2.x 和 OpenShift Serverless 在 Knative 服务中使用 JSON Web Token (JWT) 身份验证。要做到这一点,您必须在作为 ServiceMeshMemberRoll 对象成员的应用程序命名空间中创建身份验证请求和策略。您还必须为该服务启用 sidecar 注入。

重要

在启用了 Kourier 时,不支持在系统命名空间中向 pod 添加 sidecar 注入,如 knative-servingknative-serving-ingress

对于 OpenShift Container Platform,如果需要对这些命名空间中的 pod 进行 sidecar 注入,请参阅 OpenShift Serverless 文档中的 将 Service Mesh 与 OpenShift Serverless 原生集成

先决条件

  • 您已在集群中安装了 OpenShift Serverless Operator、Knative Serving 和 Red Hat OpenShift Service Mesh。
  • 安装 OpenShift CLI (oc) 。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。

流程

  1. 在您的服务中添加 sidecar.istio.io/inject="true" 注解:

    服务示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: <service_name>
    spec:
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "true" 
    1
    
            sidecar.istio.io/rewriteAppHTTPProbers: "true" 
    2
    
    ...
    Copy to Clipboard Toggle word wrap

    1
    添加 sidecar.istio.io/inject="true" 注解。
    2
    您必须在 Knative 服务中将注解 sidecar.istio.io/rewriteAppHTTPProbers: "true" 设置为 OpenShift Serverless 版本 1.14.0 或更新的版本,然后使用 HTTP 探测作为 Knative 服务的就绪度探测。
  2. 应用 Service 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap
  3. ServiceMeshMemberRoll 对象的每个无服务器应用程序命名空间中创建一个 RequestAuthentication 资源:

    apiVersion: security.istio.io/v1beta1
    kind: RequestAuthentication
    metadata:
      name: jwt-example
      namespace: <namespace>
    spec:
      jwtRules:
      - issuer: testing@secure.istio.io
        jwksUri: https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/jwks.json
    Copy to Clipboard Toggle word wrap
  4. 应用 RequestAuthentication 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap
  5. 通过创建以下 AuthorizationPolicy 资源,允许从 ServiceMeshMemberRoll 对象中的每个无服务器应用程序命名空间的系统 pod 访问 RequestAuthenticaton 资源:

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: allowlist-by-paths
      namespace: <namespace>
    spec:
      action: ALLOW
      rules:
      - to:
        - operation:
            paths:
            - /metrics 
    1
    
            - /healthz 
    2
    Copy to Clipboard Toggle word wrap
    1
    由系统 pod 收集指标的应用程序上的路径。
    2
    系统 pod 探测到应用程序的路径。
  6. 应用 AuthorizationPolicy 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap
  7. 对于作为 ServiceMeshMemberRoll 对象中成员的每个无服务器应用程序命名空间,请创建以下 AuthorizationPolicy 资源:

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: require-jwt
      namespace: <namespace>
    spec:
      action: ALLOW
      rules:
      - from:
        - source:
           requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
    Copy to Clipboard Toggle word wrap
  8. 应用 AuthorizationPolicy 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap

验证

  1. 如果您尝试使用 curl 请求来获取 Knative 服务 URL,则会被拒绝:

    示例命令

    $ curl http://hello-example-1-default.apps.mycluster.example.com/
    Copy to Clipboard Toggle word wrap

    输出示例

    RBAC: access denied
    Copy to Clipboard Toggle word wrap

  2. 使用有效 JWT 验证请求。

    1. 获取有效的 JWT 令牌:

      $ TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
      Copy to Clipboard Toggle word wrap
    2. 使用 curl 请求标头中的有效令牌访问该服务:

      $ curl -H "Authorization: Bearer $TOKEN"  http://hello-example-1-default.apps.example.com
      Copy to Clipboard Toggle word wrap

      现在允许请求:

      输出示例

      Hello OpenShift!
      Copy to Clipboard Toggle word wrap

您可以使用 Service Mesh 1.x 和 OpenShift Serverless 在 Knative 服务中使用 JSON Web Token (JWT) 身份验证。要做到这一点,您必须在作为 ServiceMeshMemberRoll 对象的成员的应用程序命名空间中创建策略。您还必须为该服务启用 sidecar 注入。

重要

在启用了 Kourier 时,不支持在系统命名空间中向 pod 添加 sidecar 注入,如 knative-servingknative-serving-ingress

对于 OpenShift Container Platform,如果需要对这些命名空间中的 pod 进行 sidecar 注入,请参阅 OpenShift Serverless 文档中的 将 Service Mesh 与 OpenShift Serverless 原生集成

先决条件

  • 您已在集群中安装了 OpenShift Serverless Operator、Knative Serving 和 Red Hat OpenShift Service Mesh。
  • 安装 OpenShift CLI (oc) 。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。

流程

  1. 在您的服务中添加 sidecar.istio.io/inject="true" 注解:

    服务示例

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: <service_name>
    spec:
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "true" 
    1
    
            sidecar.istio.io/rewriteAppHTTPProbers: "true" 
    2
    
    ...
    Copy to Clipboard Toggle word wrap

    1
    添加 sidecar.istio.io/inject="true" 注解。
    2
    您必须在 Knative 服务中将注解 sidecar.istio.io/rewriteAppHTTPProbers: "true" 设置为 OpenShift Serverless 版本 1.14.0 或更新的版本,然后使用 HTTP 探测作为 Knative 服务的就绪度探测。
  2. 应用 Service 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap
  3. 在作为 ServiceMeshMemberRoll 对象的成员的无服务器应用程序命名空间中创建策略,该策略只允许具有有效 JSON Web Tokens(JWT)的请求:

    重要

    路径 /metrics/healthz 必须包含在 excludePaths 中,因为它们是从 knative-serving 命名空间中的系统 pod 访问的。

    apiVersion: authentication.istio.io/v1alpha1
    kind: Policy
    metadata:
      name: default
      namespace: <namespace>
    spec:
      origins:
      - jwt:
          issuer: testing@secure.istio.io
          jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/jwks.json"
          triggerRules:
          - excludedPaths:
            - prefix: /metrics 
    1
    
            - prefix: /healthz 
    2
    
      principalBinding: USE_ORIGIN
    Copy to Clipboard Toggle word wrap
    1
    由系统 pod 收集指标的应用程序上的路径。
    2
    系统 pod 探测到应用程序的路径。
  4. 应用 Policy 资源:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap

验证

  1. 如果您尝试使用 curl 请求来获取 Knative 服务 URL,则会被拒绝:

    $ curl http://hello-example-default.apps.mycluster.example.com/
    Copy to Clipboard Toggle word wrap

    输出示例

    Origin authentication failed.
    Copy to Clipboard Toggle word wrap

  2. 使用有效 JWT 验证请求。

    1. 获取有效的 JWT 令牌:

      $ TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
      Copy to Clipboard Toggle word wrap
    2. 使用 curl 请求标头中的有效令牌访问该服务:

      $ curl http://hello-example-default.apps.mycluster.example.com/ -H "Authorization: Bearer $TOKEN"
      Copy to Clipboard Toggle word wrap

      现在允许请求:

      输出示例

      Hello OpenShift!
      Copy to Clipboard Toggle word wrap

第 12 章 为 Serving 配置 kube-rbac-proxy

kube-rbac-proxy 组件为 Knative Serving 提供内部身份验证和授权功能。

12.1. 为 Serving 配置 kube-rbac-proxy 资源

您可以使用 OpenShift Serverless Operator CR 全局覆盖 kube-rbac-proxy 容器的资源分配。

注意

您还可以覆盖特定部署的资源分配。

以下配置设置 Knative Serving kube-rbac-proxy 最小和最大 CPU 和内存分配:

KnativeServing CR 示例

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: knative-serving
  namespace: knative-serving
spec:
  config:
    deployment:
      "kube-rbac-proxy-cpu-request": "10m" 
1

      "kube-rbac-proxy-memory-request": "20Mi" 
2

      "kube-rbac-proxy-cpu-limit": "100m" 
3

      "kube-rbac-proxy-memory-limit": "100Mi" 
4
Copy to Clipboard Toggle word wrap

1
设置最小 CPU 分配。
2
设置最小 RAM 分配。
3
设置最大 CPU 分配数。
4
设置最大 RAM 分配数。

第 13 章 为 net-kourier 配置突发和 QPS

查询每秒(QPS)和 burst 值决定了对 API 服务器的请求或 API 调用的频率。

13.1. 为 net-kourier 配置 burst 和 QPS 值

查询每秒(QPS)值决定了发送到 API 服务器的客户端请求或 API 调用的数量。

burst 值决定了为处理存储来自客户端的请求数量。超过此缓冲区的请求将被丢弃。这对控制器很有用,且不会按时间统一分散请求。

net-kourier-controller 重启时,它会解析集群中部署的所有 入口 资源,这会导致大量 API 调用。因此,net-kourier-controller 可能需要很长时间才能启动。

您可以在 KnativeServing CR 中调整 net-kourier-controller 的 QPS 和 burst 值:

KnativeServing CR 示例

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: knative-serving
  namespace: knative-serving
spec:
  workloads:
  - name: net-kourier-controller
    env:
    - container: controller
      envVars:
      - name: KUBE_API_BURST
        value: "200" 
1

      - name: KUBE_API_QPS
        value: "200" 
2
Copy to Clipboard Toggle word wrap

1
控制器和 API 服务器之间的通信的 QPS 速率。默认值为 200。
2
Kubelet 和 API 服务器之间的通信突发容量。默认值为 200。

第 14 章 为 Knative 服务配置自定义域

14.1. 为 Knative 服务配置自定义域

Knative 服务会自动根据集群配置分配默认域名。例如,<service_name>-<namespace>.example.com。您可以通过将您自己的自定义域名映射到 Knative 服务来自定义 Knative 服务域。

您可以通过为服务创建 DomainMapping 资源来完成此操作。您还可以创建多个 DomainMapping 资源,将多个域和子域映射到单个服务。

14.2. 自定义域映射

您可以通过将您自己的自定义域名映射到 Knative 服务来自定义 Knative 服务域。要将自定义域名映射到自定义资源(CR),您必须创建一个映射到可寻址目标 CR 的 DomainMapping CR,如 Knative 服务或 Knative 路由。

14.2.1. 创建自定义域映射

您可以通过将您自己的自定义域名映射到 Knative 服务来自定义 Knative 服务域。要将自定义域名映射到自定义资源(CR),您必须创建一个映射到可寻址目标 CR 的 DomainMapping CR,如 Knative 服务或 Knative 路由。

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 安装 OpenShift CLI (oc) 。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。
  • 您已创建了 Knative 服务,并控制要映射到该服务的自定义域。

    注意

    您的自定义域必须指向 OpenShift Container Platform 集群的 IP 地址。

流程

  1. 在与您要映射的目标 CR 相同的命名空间中创建一个包含 DomainMapping CR 的 YAML 文件:

    apiVersion: serving.knative.dev/v1beta1
    kind: DomainMapping
    metadata:
     name: <domain_name> 
    1
    
     namespace: <namespace> 
    2
    
    spec:
     ref:
       name: <target_name> 
    3
    
       kind: <target_type> 
    4
    
       apiVersion: serving.knative.dev/v1
    Copy to Clipboard Toggle word wrap
    1
    要映射到目标 CR 的自定义域名。
    2
    DomainMapping CR 和目标 CR 的命名空间。
    3
    映射到自定义域的目标 CR 名称。
    4
    映射到自定义域的 CR 类型。

    服务域映射示例

    apiVersion: serving.knative.dev/v1beta1
    kind: DomainMapping
    metadata:
     name: example.com
     namespace: default
    spec:
     ref:
       name: showcase
       kind: Service
       apiVersion: serving.knative.dev/v1
    Copy to Clipboard Toggle word wrap

    路由域映射示例

    apiVersion: serving.knative.dev/v1beta1
    kind: DomainMapping
    metadata:
     name: example.com
     namespace: default
    spec:
     ref:
       name: example-route
       kind: Route
       apiVersion: serving.knative.dev/v1
    Copy to Clipboard Toggle word wrap

  2. DomainMapping CR 应用为 YAML 文件:

    $ oc apply -f <filename>
    Copy to Clipboard Toggle word wrap

14.3. 使用 Knative CLI 的 Knative 服务自定义域

您可以通过将您自己的自定义域名映射到 Knative 服务来自定义 Knative 服务域。您可以使用 Knative (kn) CLI 创建映射到可寻址目标 CR 的 DomainMapping 自定义资源 (CR) ,如 Knative 服务或 Knative 路由。

14.3.1. 使用 Knative CLI 创建自定义域映射

先决条件

  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 您已创建了 Knative 服务或路由,并控制要映射到该 CR 的自定义域。

    注意

    您的自定义域必须指向 OpenShift Container Platform 集群的 DNS。

  • 已安装 Knative (kn) CLI。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。

流程

  • 将域映射到当前命名空间中的 CR:

    $ kn domain create <domain_mapping_name> --ref <target_name>
    Copy to Clipboard Toggle word wrap

    示例命令

    $ kn domain create example.com --ref showcase
    Copy to Clipboard Toggle word wrap

    --ref 标志为域映射指定一个可寻址的目标 CR。

    如果使用 --ref 标志时没有提供前缀,则会假定目标为当前命名空间中的 Knative 服务。

  • 将域映射到指定命名空间中的 Knative 服务:

    $ kn domain create <domain_mapping_name> --ref <ksvc:service_name:service_namespace>
    Copy to Clipboard Toggle word wrap

    示例命令

    $ kn domain create example.com --ref ksvc:showcase:example-namespace
    Copy to Clipboard Toggle word wrap

  • 将域映射到 Knative 路由:

    $ kn domain create <domain_mapping_name> --ref <kroute:route_name>
    Copy to Clipboard Toggle word wrap

    示例命令

    $ kn domain create example.com --ref kroute:example-route
    Copy to Clipboard Toggle word wrap

14.4. 使用 Web 控制台进行域映射

您可以通过将您自己的自定义域名映射到 Knative 服务来自定义 Knative 服务域。您可以使用 OpenShift Container Platform Web 控制台将 DomainMapping 自定义资源(CR)映射到 Knative 服务。

14.4.1. 将自定义域映射到服务

先决条件

  • 已登陆到 web 控制台。
  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。这必须由集群管理员完成。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。
  • 您已创建了 Knative 服务,并控制要映射到该服务的自定义域。

    注意

    您的自定义域必须指向 OpenShift Container Platform 集群的 IP 地址。

流程

  1. 导航到 Topology 页面。
  2. 在您要映射到域的服务上单击鼠标右键,然后选择包含服务名称的 Edit 选项。例如,如果服务命名为 showcase,请选择 Edit showcase 选项。
  3. Advanced options 部分中,点 Show advanced Routing options

    1. 如果要映射到该服务的域映射 CR 已存在,您可以在域映射列表中选择。
    2. 如果要创建新域映射 CR,在框中输入域名,然后选择 Create 选项。例如,如果您在 example.com 中 键入,则 Create 选项为 Create "example.com"
  4. 单击 Save,将更改保存到您的服务。

验证

  1. 导航到 Topology 页面。
  2. 单击您创建的服务。
  3. 在服务信息窗口的 Resources 选项卡中,您可以看到您映射到域映射中列出的服务的域。

14.4.2. 限制密码套件

当您为入口指定 net-kourier 并使用 DomainMapping 时,用于 OpenShift 路由的 TLS 被设置为 passthrough,并且 Kourier 网关处理 TLS。在这种情况下,您可能需要限制允许用户限制允许 Kourier 的 TLS 密码套件。

先决条件

  • 已登陆到 web 控制台。
  • 已安装 OpenShift Serverless Operator。
  • 已安装 Knative Serving。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以创建应用程序和其他工作负载。

    注意

    您的自定义域必须指向集群的 IP 地址。

流程

  • KnativeServing CR 中,使用 cipher-suites 值来指定您要启用的密码套件:

    KnativeServing CR 示例

    spec:
      config:
        kourier:
          cipher-suites: ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-ECDSA-CHACHA20-POLY1305
    Copy to Clipboard Toggle word wrap

    将禁用其他密码套件。您可以使用逗号分隔来指定多个套件。

    注意

    Kourier 网关的容器镜像使用 Envoy 代理镜像,默认的启用的密码套件取决于 Envoy 代理的版本。

14.5. 使用 TLS 证书保护映射的服务

14.5.1. 使用 TLS 证书保护带有自定义域的服务

为 Knative 服务配置了自定义域后,您可以使用 TLS 证书来保护映射的服务。要做到这一点,您必须创建一个 Kubernetes TLS secret,然后更新 DomainMapping CR 以使用您创建的 TLS secret。

先决条件

  • 为 Knative 服务配置了自定义域,并有一个正常工作的 DomainMapping CR。
  • 您有来自证书授权机构供应商或自签名证书的 TLS 证书。
  • 您已从证书授权中心(CA)提供商或自签名证书获取 certkey 文件。
  • 安装 OpenShift CLI (oc) 。

流程

  1. 创建 Kubernetes TLS secret:

    $ oc create secret tls <tls_secret_name> --cert=<path_to_certificate_file> --key=<path_to_key_file>
    Copy to Clipboard Toggle word wrap
  2. networking.internal.knative.dev/certificate-uid: <id>' 标签添加到 Kubernetes TLS secret 中:

    $ oc label secret <tls_secret_name> networking.internal.knative.dev/certificate-uid="<id>"
    Copy to Clipboard Toggle word wrap

    如果您使用第三方 secret 供应商,如 cert-manager,您可以配置 secret Manager 来自动标记 Kubernetes TLS secret。cert-manager 用户可以使用提供的 secret 模板自动生成带有正确标签的 secret。在本例中,secret 过滤仅基于键,但这个值可以存储有用的信息,如 secret 包含的证书 ID。

    注意

    Red Hat OpenShift 的 cert-manager Operator 只是一个技术预览功能。如需更多信息,请参阅 为 Red Hat OpenShift 安装 cert-manager Operator 文档。

  3. 更新 DomainMapping CR,以使用您创建的 TLS secret:

    apiVersion: serving.knative.dev/v1beta1
    kind: DomainMapping
    metadata:
      name: <domain_name>
      namespace: <namespace>
    spec:
      ref:
        name: <service_name>
        kind: Service
        apiVersion: serving.knative.dev/v1
    # TLS block specifies the secret to be used
      tls:
        secretName: <tls_secret_name>
    Copy to Clipboard Toggle word wrap

验证

  1. 验证 DomainMapping CR 状态是否为 True,输出中的 URL 列显示了使用 scheme https 的映射域:

    $ oc get domainmapping <domain_name>
    Copy to Clipboard Toggle word wrap

    输出示例

    NAME                      URL                               READY   REASON
    example.com               https://example.com               True
    Copy to Clipboard Toggle word wrap

  2. 可选: 如果服务公开,请运行以下命令验证该服务是否可用:

    $ curl https://<domain_name>
    Copy to Clipboard Toggle word wrap

    如果证书是自签名的,请通过在 curl 命令中添加 -k 标志来跳过验证。

14.5.2. 使用 secret 过滤改进 net-kourier 内存用量

默认情况下,Kubernetes client-go 库的 informers 实施会获取特定类型的所有资源。当有很多资源可用时可能会导致大量开销。这可能会导致因为内存泄露的问题导致 Knative net-kourier ingress 控制器在大型集群中失败。但是,Knative net-kourier ingress 控制器提供了一个过滤机制,它可让控制器只获取 Knative 相关的 secret。

OpenShift Serverless Operator 端默认启用 secret 过滤。默认向 net-kourier 控制器 pod 添加环境变量 ENABLE_SECRET_INFORMER_FILTERING_BY_CERT_UID=true

重要

如果启用 secret 过滤,则所有 secret 都需要使用 networking.internal.knative.dev/certificate-uid: "<id>"。否则,Knative Serving 不会检测到它们,这会导致失败。您必须标记新的和现有的 secret。

先决条件

  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。
  • 创建或具有创建应用程序和其他工作负载的角色和权限的项目。
  • 安装 OpenShift Serverless Operator 和 Knative Serving。
  • 安装 OpenShift CLI (oc) 。

您可以使用 KnativeServing 自定义资源(CR)中的 workload 字段设置为 false 来禁用 secret 过滤,将 ENABLE_SECRET_INFORMER_FILTERING_BY_CERT_UID 变量设置为 false

KnativeServing CR 示例

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: knative-serving
  namespace: knative-serving
spec:
...
  workloads:
    - env:
        - container: controller
          envVars:
            - name: ENABLE_SECRET_INFORMER_FILTERING_BY_CERT_UID
              value: 'false'
      name: net-kourier-controller
Copy to Clipboard Toggle word wrap

第 15 章 Knative Serving 的高可用性配置

15.1. Knative 服务的高可用性

高可用性 (HA) 是 Kubernetes API 的标准功能,有助于确保在出现中断时 API 保持正常运行。在 HA 部署中,如果活跃控制器崩溃或被删除,另一个控制器就可以使用。此控制器会接管处理由现在不可用的控制器提供服务的 API。

OpenShift Serverless 中的 HA 可通过领导选举机制获得,该机制会在安装 Knative Serving 和 Eventing control plane 后默认启用。在使用领导选举 HA 模式时,控制器实例在需要前应该已在集群内调度并运行。这些控制器实例争用共享资源,即领导选举锁定。在任何给定时间可以访问领导选举机制锁定资源的控制器实例被称为领导 (leader) 。

15.2. Knative 部署的高可用性

默认情况下,Knative Serving activator, autoscaler,autoscaler -hpa,controller,webhook,domain-mapping,domainmapping-webhook,kourier-control, 和 kourier-gateway 组件提供高可用性(HA)。您可以通过修改 KnativeServing 自定义资源 (CR) 中的 spec.high-availability.replicas 值来更改这些组件的副本数。

15.2.1. 为 Knative Serving 配置高可用性副本

要为有资格的部署资源指定三个最小副本,请将自定义资源中的 spec.high-availability.replicas 的值设置为 3

先决条件

  • 在 OpenShift Container Platform 上具有集群管理员权限,或者具有 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 的集群或专用管理员权限。
  • 在集群中安装了 OpenShift Serverless Operator 和 Knative Serving。

流程

  1. 在 OpenShift Container Platform Web 控制台中导航至 OperatorHubInstalled Operators
  2. 选择 knative-serving 命名空间。
  3. 点 OpenShift Serverless Operator 的 Provided APIs 列表中的 Knative Serving 来进入 Knative Serving 选项卡。
  4. knative-serving,然后使用 knative-serving 页面中的 YAML 选项卡。
  5. 修改 KnativeServing CR 中的副本数量:

    YAML 示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      high-availability:
        replicas: 3
    Copy to Clipboard Toggle word wrap

  6. 您还可以指定特定工作负载的副本数量。

    注意

    特定于工作负载的配置会覆盖 Knative Serving 的全局设置。

    YAML 示例

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      high-availability:
        replicas: 3
      workloads:
      - name: webhook
        replicas: 4
    Copy to Clipboard Toggle word wrap

  7. 验证是否遵循高可用性限制:

    示例命令

    $ oc get hpa -n knative-serving
    Copy to Clipboard Toggle word wrap

    输出示例

    NAME        REFERENCE              TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    activator   Deployment/activator   0%/100%   3         22        3          2m24s
    webhook     Deployment/webhook     2%/100%   4         8         4          2m23s
    Copy to Clipboard Toggle word wrap

15.2.2. 覆盖中断预算

Pod Disruption Budget (PDB)是 Kubernetes API 的一个标准功能,有助于限制因维护原因需要重新调度 pod 时对应用程序的中断。

流程

  • 通过修改 KnativeServing 自定义资源(CR)中的 minAvailable 配置值来覆盖特定资源的默认 PDB。

PDB 示例,minAvailable 设置为 70%

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
 name: knative-serving
 namespace: knative-serving
spec:
 podDisruptionBudgets:
 - name: activator-pdb
   minAvailable: 70%
Copy to Clipboard Toggle word wrap

注意

例如,如果您通过将 high-availability.replicas 值更改为 1,请确保也将对应的 PDB minAvailable 值更新为 0。否则,pod 中断预算会阻止自动集群或 Operator 更新。

第 16 章 调优服务配置

16.1. 覆盖 Knative Serving 系统部署配置

您可以通过修改 KnativeServing 自定义资源(CR)中的 workload spec 来覆盖某些特定部署的默认配置。

16.1.1. 覆盖系统部署配置

目前,支持覆盖 resources, replicas, labels, annotations, 和 nodeSelector 项的默认配置设置,以及探测的 readinessliveness 字段的默认设置。

在以下示例中,KnativeServing CR 会覆盖 Webhook 部署,以便:

  • net-kourier-controllerreadiness 探测超时设置为 10 秒。
  • 部署指定了 CPU 和内存资源限制。
  • 部署有 3 个副本。
  • 添加 example-label: label 标签。
  • 添加 example-annotation: 注解。
  • nodeSelector 字段被设置为选择带有 disktype: hdd 标签的节点。
注意

KnativeServing CR 标签和注解设置覆盖部署本身和生成的 Pod 的部署标签和注解。

KnativeServing CR 示例

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: ks
  namespace: knative-serving
spec:
  high-availability:
    replicas: 2
  workloads:
  - name: net-kourier-controller
    readinessProbes: 
1

      - container: controller
        timeoutSeconds: 10
  - name: webhook
    resources:
    - container: webhook
      requests:
        cpu: 300m
        memory: 60Mi
      limits:
        cpu: 1000m
        memory: 1000Mi
    replicas: 3
    labels:
      example-label: label
    annotations:
      example-annotation: annotation
    nodeSelector:
      disktype: hdd
Copy to Clipboard Toggle word wrap

1
您可以使用 readinessliveness 探测覆盖来覆盖在 Kubernetes API 中指定的一个部署中的一个容器探测的所有字段,与探测 handler: exec, grpc, httpGet, 和 tcpSocket 相关的字段除外。

第 17 章 配置队列代理资源

Queue Proxy 是服务中的每个应用程序容器的 sidecar 容器。它提高了管理 Serverless 工作负载,确保有效的资源使用量。您可以配置 Queue Proxy。

17.1. 为 Knative Service 配置队列代理资源

除了在部署 configmap 中全局配置 Queue Proxy 资源请求和限值外,您还可以使用针对 CPU、内存和临时存储资源类型的对应注解在服务级别设置它们。

先决条件

  • 在集群中必须安装 Red Hat OpenShift Pipelines。
  • 已安装 OpenShift (oc) CLI。
  • 已安装 Knative (kn) CLI。

流程

  • 使用资源请求和限值修改服务的 configmap:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: example-service
      namespace: default
    spec:
      template:
        metadata:
          annotations:
            queue.sidecar.serving.knative.dev/cpu-resource-request: "1"
            queue.sidecar.serving.knative.dev/cpu-resource-limit: "2"
            queue.sidecar.serving.knative.dev/memory-resource-request: "1Gi"
            queue.sidecar.serving.knative.dev/memory-resource-limit: "2Gi"
            queue.sidecar.serving.knative.dev/ephemeral-storage-resource-request: "400Mi"
            queue.sidecar.serving.knative.dev/ephemeral-storage-resource-limit: "450Mi"
    Copy to Clipboard Toggle word wrap

    或者,您可以使用特殊的 queue.sidecar.serving.knative.dev/resource-percentage 注解,它将 Queue Proxy 资源作为应用程序容器的百分比计算。当从应用程序容器要求计算 CPU 和内存资源要求且它们位于以下边界之外时,这些值会被调整以适合边界。在这种情况下,以下最小和最大边界适用于 CPU 和内存资源要求:

    Expand
    表 17.1. 资源要求边界
    资源要求MinMax

    CPU 请求

    25m

    100m

    CPU 限制

    40m

    500m

    内存请求

    50Mi

    200Mi

    内存限制

    200Mi

    500Mi

    注意

    如果您使用对应的资源注解同时设置百分比注解和特定资源值,则后者具有优先权。

    警告

    queue.sidecar.serving.knative.dev/resource-percentage 注解现已弃用,并将在以后的 OpenShift Serverless 版本中删除。

法律通告

Copyright © 2025 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2026 Red Hat