×

OpenShift Serverless 运算符提供 Kourier 作为 Knative 的默认入口。但是,无论 Kourier 是否启用,您都可以将 Service Mesh 与 OpenShift Serverless 一起使用。与 Kourier 禁用集成允许您配置 Kourier 入口不支持的其他网络和路由选项,例如 mTLS 功能。

请注意以下假设和限制

  • 所有 Knative 内部组件以及 Knative 服务都是 Service Mesh 的一部分,并且启用了 sidecar 注射。这意味着在整个网格中强制执行严格的 mTLS。对 Knative 服务的所有请求都需要 mTLS 连接,客户端必须发送其证书,但来自 OpenShift Routing 的调用除外。

  • 与 Service Mesh 集成的 OpenShift Serverless 只能定位**一个**服务网格。集群中可以存在多个网格,但 OpenShift Serverless 只能在一个网格上可用。

  • 不支持更改 OpenShift Serverless 所属的目标`ServiceMeshMemberRoll`,这意味着将 OpenShift Serverless 移动到另一个网格。更改目标 Service Mesh 的唯一方法是卸载并重新安装 OpenShift Serverless。

先决条件

  • 您可以访问具有集群管理员访问权限的 Red Hat OpenShift Serverless 帐户。

  • 您已安装 OpenShift CLI(`oc`)。

  • 您已安装 Serverless 运算符。

  • 您已安装 Red Hat OpenShift Service Mesh 运算符。

  • 以下过程中的示例使用域名`example.com`。此域名的示例证书用作签署子域名证书的证书颁发机构 (CA)。

    要在您的部署中完成和验证这些过程,您需要一个由广泛信任的公共 CA 签名的证书或您的组织提供的 CA。必须根据您的域名、子域名和 CA 调整示例命令。

  • 您必须配置通配符证书以匹配您的 OpenShift Container Platform 集群的域名。例如,如果您的 OpenShift Container Platform 控制台地址是https://console-openshift-console.apps.openshift.example.com,则必须配置通配符证书,以便域名是`*.apps.openshift.example.com`。有关配置通配符证书的更多信息,请参阅以下关于创建证书以加密传入外部流量的主题。

  • 如果您想使用任何域名,包括不是默认 OpenShift Container Platform 集群域名子域的域名,则必须为这些域名设置域名映射。有关更多信息,请参阅 OpenShift Serverless 文档中的创建自定义域名映射

OpenShift Serverless 只支持本指南中明确记录的 Red Hat OpenShift Service Mesh 功能的使用,不支持其他未记录的功能。

仅当 Service Mesh 版本为 2.2 或更高版本时,才支持将 Serverless 1.31 与 Service Mesh 一起使用。有关 1.31 以外版本的详细信息和信息,请参阅“Red Hat OpenShift Serverless 支持的配置”页面。

创建证书以加密传入的外部流量

默认情况下,Service Mesh mTLS 功能仅保护 Service Mesh 本身内部的流量,介于入口网关和具有 sidecar 的各个 Pod 之间。要加密流量在其流入 OpenShift Container Platform 集群时的流量,您必须在启用 OpenShift Serverless 和 Service Mesh 集成之前生成证书。

先决条件
  • 您在 OpenShift Container Platform 上具有集群管理员权限,或者您在 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 上具有集群或专用管理员权限。

  • 您已安装 OpenShift Serverless 运算符和 Knative Serving。

  • 安装 OpenShift CLI(oc)。

  • 您已创建项目或有权访问具有适当角色和权限以创建应用程序和其他工作负载的项目。

步骤
  1. 创建根证书和私钥,用于为您的 Knative 服务签名证书

    $ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
        -subj '/O=Example Inc./CN=example.com' \
        -keyout root.key \
        -out root.crt
  2. 创建通配符证书

    $ openssl req -nodes -newkey rsa:2048 \
        -subj "/CN=*.apps.openshift.example.com/O=Example Inc." \
        -keyout wildcard.key \
        -out wildcard.csr
  3. 签署通配符证书

    $ openssl x509 -req -days 365 -set_serial 0 \
        -CA root.crt \
        -CAkey root.key \
        -in wildcard.csr \
        -out wildcard.crt
  4. 使用通配符证书创建一个密钥

    $ oc create -n istio-system secret tls wildcard-certs \
        --key=wildcard.key \
        --cert=wildcard.crt

    当您将 OpenShift Serverless 与 Service Mesh 集成时,网关会拾取此证书,以便入站网关使用此证书提供服务。

将 Service Mesh 与 OpenShift Serverless 集成

验证安装前提条件

在安装和配置 Service Mesh 与 Serverless 的集成之前,请验证是否已满足前提条件。

步骤
  1. 检查冲突的网关

    示例命令
    $ oc get gateway -A -o jsonpath='{range .items[*]}{@.metadata.namespace}{"/"}{@.metadata.name}{" "}{@.spec.servers}{"\n"}{end}' | column -t
    示例输出
    knative-serving/knative-ingress-gateway  [{"hosts":["*"],"port":{"name":"https","number":443,"protocol":"HTTPS"},"tls":{"credentialName":"wildcard-certs","mode":"SIMPLE"}}]
    knative-serving/knative-local-gateway    [{"hosts":["*"],"port":{"name":"http","number":8081,"protocol":"HTTP"}}]

    此命令不应返回绑定port: 443hosts: ["*"]Gateway,除非是knative-serving中的Gateways和属于另一个 Service Mesh 实例的Gateways

    Serverless 所属的网格必须是不同的,最好只为 Serverless 工作负载保留。这是因为其他配置(例如Gateways)可能会干扰 Serverless 网关knative-local-gatewayknative-ingress-gateway。Red Hat OpenShift Service Mesh 只允许一个 Gateway 在同一端口 (port: 443) 上声明通配符主机绑定 (hosts: ["*"])。如果另一个 Gateway 已经绑定此配置,则必须为 Serverless 工作负载创建一个单独的网格。

  2. 检查 Red Hat OpenShift Service Mesh istio-ingressgateway 是否以 NodePortLoadBalancer 类型公开

    示例命令
    $ oc get svc -A | grep istio-ingressgateway
    示例输出
    istio-system   istio-ingressgateway  ClusterIP  172.30.46.146 none>   15021/TCP,80/TCP,443/TCP     9m50s

    此命令不应返回类型为NodePortLoadBalancerService对象。

    预期通过使用 OpenShift 路由的 OpenShift Ingress 调用集群外部 Knative 服务。不支持直接访问 Service Mesh,例如通过使用类型为NodePortLoadBalancerService对象公开istio-ingressgateway

安装和配置 Service Mesh

要将 Serverless 与 Service Mesh 集成,您需要使用特定配置安装 Service Mesh。

步骤
  1. istio-system命名空间中创建具有以下配置的ServiceMeshControlPlane资源

    如果您有现有的ServiceMeshControlPlane对象,请确保应用相同的配置。

    apiVersion: maistra.io/v2
    kind: ServiceMeshControlPlane
    metadata:
      name: basic
      namespace: istio-system
    spec:
      profiles:
      - default
      security:
        dataPlane:
          mtls: true (1)
      techPreview:
        meshConfig:
          defaultConfig:
            terminationDrainDuration: 35s (2)
      gateways:
        ingress:
          service:
            metadata:
              labels:
                knative: ingressgateway (3)
      proxy:
        networking:
          trafficControl:
            inbound:
              excludedPorts: (4)
              - 8444 # metrics
              - 8022 # serving: wait-for-drain k8s pre-stop hook
    1 在网格中强制执行严格的 mTLS。仅允许使用有效客户端证书的调用。
    2 Serverless 对 Knative 服务的优雅终止时间为 30 秒。istio-proxy需要更长的终止持续时间,以确保不会丢弃任何请求。
    3 为入站网关定义一个特定选择器,以仅针对 Knative 网关。
    4 这些端口由 Kubernetes 和集群监控调用,它们不是网格的一部分,无法使用 mTLS 调用。因此,这些端口从网格中排除。
  2. 将您想要与 Service Mesh 集成的命名空间作为成员添加到ServiceMeshMemberRoll对象中

    示例servicemesh-member-roll.yaml配置文件
    apiVersion: maistra.io/v1
    kind: ServiceMeshMemberRoll
    metadata:
      name: default
      namespace: istio-system
    spec:
      members: (1)
        - knative-serving
        - knative-eventing
        - your-OpenShift-projects
    1 要与 Service Mesh 集成的命名空间列表。

    此命名空间列表必须包含knative-servingknative-eventing命名空间。

  3. 应用ServiceMeshMemberRoll资源

    $ oc apply -f servicemesh-member-roll.yaml
  4. 创建必要的网关,以便 Service Mesh 可以接受流量。以下示例使用ISTIO_MUTUAL模式 (mTLS) 的knative-local-gateway对象

    示例istio-knative-gateways.yaml配置文件
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: knative-ingress-gateway
      namespace: knative-serving
    spec:
      selector:
        knative: ingressgateway
      servers:
        - port:
            number: 443
            name: https
            protocol: HTTPS
          hosts:
            - "*"
          tls:
            mode: SIMPLE
            credentialName: <wildcard_certs> (1)
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
     name: knative-local-gateway
     namespace: knative-serving
    spec:
     selector:
       knative: ingressgateway
     servers:
       - port:
           number: 8081
           name: https
           protocol: HTTPS (2)
         tls:
           mode: ISTIO_MUTUAL (2)
         hosts:
           - "*"
    ---
    apiVersion: v1
    kind: Service
    metadata:
     name: knative-local-gateway
     namespace: istio-system
     labels:
       experimental.istio.io/disable-gateway-port-translation: "true"
    spec:
     type: ClusterIP
     selector:
       istio: ingressgateway
     ports:
       - name: http2
         port: 80
         targetPort: 8081
    1 包含通配符证书的密钥的名称。
    2 knative-local-gateway对象提供 HTTPS 流量,并期望所有客户端都使用 mTLS 发送请求。这意味着只有来自 Service Mesh 内部的流量才是可能的。来自 Service Mesh 外部的负载必须通过 OpenShift 路由使用外部域。
  5. 应用Gateway资源

    $ oc apply -f istio-knative-gateways.yaml

安装和配置 Serverless

安装 Service Mesh 后,您需要使用特定配置安装 Serverless。

步骤
  1. 使用以下KnativeServing自定义资源安装 Knative Serving,该资源启用 Istio 集成

    示例knative-serving-config.yaml配置文件
    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      ingress:
        istio:
          enabled: true (1)
      deployments: (2)
      - name: activator
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: autoscaler
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      config:
        istio: (3)
          gateway.knative-serving.knative-ingress-gateway: istio-ingressgateway.<your-istio-namespace>.svc.cluster.local
          local-gateway.knative-serving.knative-local-gateway: knative-local-gateway.<your-istio-namespace>.svc.cluster.local
    1 启用 Istio 集成。
    2 为 Knative Serving 数据平面 Pod 启用 sidecar 注射。
    3 如果您的 istio 没有运行在istio-system命名空间中,则需要使用正确的命名空间设置这两个标志。
  2. 应用KnativeServing资源

    $ oc apply -f knative-serving-config.yaml
  3. 使用以下KnativeEventing对象安装 Knative Eventing,该对象启用 Istio 集成

    示例knative-eventing-config.yaml配置文件
    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeEventing
    metadata:
      name: knative-eventing
      namespace: knative-eventing
    spec:
      config:
        features:
          istio: enabled (1)
      workloads: (2)
      - name: pingsource-mt-adapter
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: imc-dispatcher
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: mt-broker-ingress
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: mt-broker-filter
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
    1 启用 Eventing Istio 控制器,为每个InMemoryChannelKafkaChannel服务创建一个DestinationRule
    2 为 Knative Eventing Pod 启用 sidecar 注射。
  4. 应用KnativeEventing资源

    $ oc apply -f knative-eventing-config.yaml
  5. 使用以下KnativeKafka自定义资源安装 Knative Kafka,该资源启用 Istio 集成

    示例knative-kafka-config.yaml配置文件
    apiVersion: operator.serverless.openshift.io/v1alpha1
    kind: KnativeKafka
    metadata:
      name: knative-kafka
      namespace: knative-eventing
    spec:
      channel:
        enabled: true
        bootstrapServers: <bootstrap_servers> (1)
      source:
        enabled: true
      broker:
        enabled: true
        defaultConfig:
          bootstrapServers: <bootstrap_servers> (1)
          numPartitions: <num_partitions>
          replicationFactor: <replication_factor>
        sink:
          enabled: true
      workloads: (2)
      - name: kafka-controller
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: kafka-broker-receiver
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: kafka-broker-dispatcher
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: kafka-channel-receiver
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: kafka-channel-dispatcher
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: kafka-source-dispatcher
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
      - name: kafka-sink-receiver
        labels:
          "sidecar.istio.io/inject": "true"
        annotations:
          "sidecar.istio.io/rewriteAppHTTPProbers": "true"
    1 Apache Kafka 集群 URL,例如my-cluster-kafka-bootstrap.kafka:9092
    2 为 Knative Kafka Pod 启用 sidecar 注射。
  6. 应用KnativeEventing对象

    $ oc apply -f knative-kafka-config.yaml
  7. 安装ServiceEntry以通知 Service Mesh KnativeKafka组件和 Apache Kafka 集群之间的通信

    示例kafka-cluster-serviceentry.yaml配置文件
    apiVersion: networking.istio.io/v1alpha3
    kind: ServiceEntry
    metadata:
      name: kafka-cluster
      namespace: knative-eventing
    spec:
      hosts: (1)
        - <bootstrap_servers_without_port>
      exportTo:
        - "."
      ports: (2)
        - number: 9092
          name: tcp-plain
          protocol: TCP
        - number: 9093
          name: tcp-tls
          protocol: TCP
        - number: 9094
          name: tcp-sasl-tls
          protocol: TCP
        - number: 9095
          name: tcp-sasl-tls
          protocol: TCP
        - number: 9096
          name: tcp-tls
          protocol: TCP
      location: MESH_EXTERNAL
      resolution: NONE
    1 Apache Kafka 集群主机的列表,例如my-cluster-kafka-bootstrap.kafka
    2 Apache Kafka 集群侦听器端口。

    spec.ports中列出的端口是示例 TPC 端口。实际值取决于 Apache Kafka 集群的配置方式。

  8. 应用ServiceEntry资源

    $ oc apply -f kafka-cluster-serviceentry.yaml

验证集成

安装启用 Istio 的 Service Mesh 和 Serverless 后,您可以验证集成是否有效。

步骤
  1. 创建一个启用了 sidecar 注射并使用直通路由的 Knative 服务

    示例knative-service.yaml配置文件
    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: <service_name>
      namespace: <namespace> (1)
      annotations:
        serving.knative.openshift.io/enablePassthrough: "true" (2)
    spec:
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "true" (3)
            sidecar.istio.io/rewriteAppHTTPProbers: "true"
        spec:
          containers:
          - image: <image_url>
    1 属于服务网格成员角色的命名空间。
    2 指示 Knative Serving 生成启用直通的路由,以便您生成的证书可以直接通过入站网关提供服务。
    3 将 Service Mesh sidecar 注射到 Knative 服务 Pod 中。

    始终将此示例中的注释添加到所有 Knative 服务中,以使其与 Service Mesh 协同工作。

  2. 应用Service资源

    $ oc apply -f knative-service.yaml
  3. 使用现在受 CA 信任的安全连接访问您的无服务器应用程序

    $ curl --cacert root.crt <service_url>

    例如,运行

    示例命令
    $ curl --cacert root.crt https://hello-default.apps.openshift.example.com
    示例输出
    Hello Openshift!

在使用带有 mTLS 的 Service Mesh 时启用 Knative Serving 和 Knative Eventing 指标

如果启用服务网格和相互传输层安全性 (mTLS),则 Knative Serving 和 Knative Eventing 的指标默认情况下会被禁用,因为服务网格阻止了 Prometheus 抓取指标。使用服务网格和 mTLS 时,您可以启用 Knative Serving 和 Knative Eventing 指标。

先决条件
  • 您拥有以下其中一种权限来访问集群:

    • OpenShift Container Platform 的集群管理员权限

    • AWS 上的 Red Hat OpenShift Service 的集群管理员权限

    • OpenShift Dedicated 的专用管理员权限

  • 您已安装 OpenShift CLI(`oc`)。

  • 您可以访问具有创建应用程序和其他工作负载的适当角色和权限的项目。

  • 您已在集群上安装了 OpenShift Serverless Operator、Knative Serving 和 Knative Eventing。

  • 您已安装启用了 mTLS 功能的 Red Hat OpenShift Service Mesh。

步骤
  1. 在 Knative Serving 自定义资源 (CR) 的 observability 说明中将 prometheus 指定为 metrics.backend-destination

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeServing
    metadata:
      name: knative-serving
      namespace: knative-serving
    spec:
      config:
        observability:
          metrics.backend-destination: "prometheus"
    ...

    此步骤可防止指标默认情况下被禁用。

    当您使用 manageNetworkPolicy: false 配置 ServiceMeshControlPlane 时,必须使用 KnativeEventing 上的注释以确保事件正确传递。

    Knative Eventing 使用相同的机制。要启用 Knative Eventing 的指标,您需要在 Knative Eventing 自定义资源 (CR) 的 observability 说明中将 prometheus 指定为 metrics.backend-destination,如下所示:

    apiVersion: operator.knative.dev/v1beta1
    kind: KnativeEventing
    metadata:
      name: knative-eventing
      namespace: knative-eventing
    spec:
      config:
        observability:
          metrics.backend-destination: "prometheus"
    ...
  2. 修改并重新应用 istio-system 命名空间中的默认服务网格控制平面,使其包含以下规范:

    ...
    spec:
      proxy:
        networking:
          trafficControl:
            inbound:
              excludedPorts:
              - 8444
    ...

禁用默认网络策略

OpenShift Serverless Operator 默认情况下会生成网络策略。要禁用默认网络策略生成,您可以在 KnativeEventingKnativeServing 自定义资源 (CR) 中添加 serverless.openshift.io/disable-istio-net-policies-generation 注释。

先决条件
  • 您拥有以下其中一种权限来访问集群:

    • OpenShift Container Platform 的集群管理员权限

    • AWS 上的 Red Hat OpenShift Service 的集群管理员权限

    • OpenShift Dedicated 的专用管理员权限

  • 您已安装 OpenShift CLI(`oc`)。

  • 您可以访问具有创建应用程序和其他工作负载的适当角色和权限的项目。

  • 您已在集群上安装了 OpenShift Serverless Operator、Knative Serving 和 Knative Eventing。

  • 您已安装启用了 mTLS 功能的 Red Hat OpenShift Service Mesh。

步骤
  • serverless.openshift.io/disable-istio-net-policies-generation: "true" 注释添加到您的 Knative 自定义资源。

    OpenShift Serverless Operator 默认情况下会生成所需的网络策略。当您使用 manageNetworkPolicy: false 配置 ServiceMeshControlPlane 时,必须禁用默认网络策略生成以确保事件正确传递。要禁用默认网络策略生成,您可以在 KnativeEventingKnativeServing 自定义资源 (CR) 中添加 serverless.openshift.io/disable-istio-net-policies-generation 注释。

    1. 通过运行以下命令为 KnativeEventing CR 添加注释:

      $ oc edit KnativeEventing -n knative-eventing
      KnativeEventing CR 示例
      apiVersion: operator.knative.dev/v1beta1
      kind: KnativeEventing
      metadata:
        name: knative-eventing
        namespace: knative-eventing
        annotations:
          serverless.openshift.io/disable-istio-net-policies-generation: "true"
    2. 通过运行以下命令为 KnativeServing CR 添加注释:

      $ oc edit KnativeServing -n knative-serving
      KnativeServing CR 示例
      apiVersion: operator.knative.dev/v1beta1
      kind: KnativeServing
      metadata:
        name: knative-serving
        namespace: knative-serving
        annotations:
          serverless.openshift.io/disable-istio-net-policies-generation: "true"

通过为服务网格使用密钥过滤来提高 net-istio 内存使用率

默认情况下,Kubernetes client-go 库的 informers 实现会获取特定类型的所有资源。当有很多资源可用时,这可能会导致很大的开销,从而导致 Knative net-istio 入口控制器在大型集群上由于内存泄漏而失败。但是,Knative net-istio 入口控制器提供了一种过滤机制,该机制使控制器只能获取与 Knative 相关的密钥。

密钥过滤在 OpenShift Serverless Operator 端默认启用。默认情况下,环境变量 ENABLE_SECRET_INFORMER_FILTERING_BY_CERT_UID=true 会添加到 net-istio 控制器 pod 中。

如果启用密钥过滤,则必须使用 networking.internal.knative.dev/certificate-uid: "<id>" 标签标记所有密钥。否则,Knative Serving 无法检测到它们,从而导致失败。必须标记新的和现有的密钥。

先决条件
  • 您在 OpenShift Container Platform 上具有集群管理员权限,或者您在 Red Hat OpenShift Service on AWS 或 OpenShift Dedicated 上具有集群或专用管理员权限。

  • 您已创建项目或有权访问具有适当角色和权限以创建应用程序和其他工作负载的项目。

  • 安装 Red Hat OpenShift Service Mesh。只有服务网格的 OpenShift Serverless 仅支持与 Red Hat OpenShift Service Mesh 2.0.5 或更高版本一起使用。

  • 安装 OpenShift Serverless Operator 和 Knative Serving。

  • 安装 OpenShift CLI(oc)。

您可以通过使用 KnativeServing 自定义资源 (CR) 中的 workloads 字段将 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-istio-controller