4.5. External 和 Ingress 路由


4.5.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 路由一起使用,以提供额外的精细路由功能,如流量分割。

4.5.1.1. 其他资源

4.5.2. 自定义标签和注解

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

4.5.2.1. 为 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>
      ...

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

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

      $ kn service create <service_name> \
        --image=<image> \
        --annotation <annotation_name>=<annotation_value> \
        --label <label_value>=<label_value>

  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

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

4.5.3. 为 Knative 服务配置路由

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

注意

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

4.5.3.1. 为 Knative 服务配置 OpenShift Container Platform 路由

先决条件

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

    2. 应用 Service 资源:

      $ oc apply -f <filename>
    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

  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

    您将看到以下输出:

    No resources found in knative-serving-ingress namespace.
  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
    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>

4.5.4. 全局 HTTPS 重定向

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

4.5.4.1. HTTPS 重定向全局设置

启用 HTTPS 重定向的 KnativeServing CR 示例

apiVersion: operator.knative.dev/v1beta1
kind: KnativeServing
metadata:
  name: knative-serving
spec:
  config:
    network:
      httpProtocol: "redirected"
...

4.5.5. 外部路由的 URL 方案

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

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

默认规格

...
spec:
  config:
    network:
      default-external-scheme: "https"
...

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

HTTP 覆盖规格

...
spec:
  config:
    network:
      default-external-scheme: "http"
...

4.5.6. 每个服务的 HTTPS 重定向

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

4.5.6.1. 为服务重定向 HTTPS

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

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: example
  namespace: default
  annotations:
    networking.knative.dev/http-option: "redirected"
spec:
  ...

4.5.7. 集群本地可用性

默认情况下,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 标签。

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

先决条件

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

流程

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

    $ oc label ksvc <service_name> networking.knative.dev/visibility=cluster-local

验证

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

    $ oc get ksvc

    输出示例

    NAME            URL                                                                         LATESTCREATED     LATESTREADY       READY   REASON
    hello           http://hello.default.svc.cluster.local                                      hello-tx2g7       hello-tx2g7       True

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

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

先决条件

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

流程

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

    $ export san="knative"
    注意

    需要主题备用名称(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
  3. 生成使用 SAN 验证的服务器密钥:

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

    $ openssl x509 -req -extfile <(printf "subjectAltName=DNS:$san") \
      -days 365 -in tls.csr \
      -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt
  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 -
    2. 更新 KnativeServing 自定义资源 (CR) spec,以使用 Kourier 网关创建的 secret:

      KnativeServing CR 示例

      ...
      spec:
        config:
          kourier:
            cluster-cert-secret: server-certs
      ...

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

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

4.5.8. Kourier 网关服务类型

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

默认规格

...
spec:
  ingress:
    kourier:
      service-type: ClusterIP
...

4.5.8.1. 设置 Kourier 网关服务类型

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

LoadBalancer 覆盖规格

...
spec:
  ingress:
    kourier:
      service-type: LoadBalancer
...

4.5.9. 使用 HTTP2 和 gRPC

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

4.5.9.1. 使用 HTTP2 和 gRPC 与无服务器应用程序交互

重要

此方法需要使用 LoadBalancer 服务类型公开 Kourier 网关。您可以通过在 KnativeServing 自定义资源定义 (CRD) 中添加以下 YAML 来配置:

...
spec:
  ingress:
    kourier:
      service-type: LoadBalancer
...

先决条件

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

流程

  1. 找到应用程序主机。请参阅验证无服务器应用程序部署中的相关内容。
  2. 查找 ingress 网关的公共地址:

    $ oc -n knative-serving-ingress get svc kourier

    输出示例

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                                             PORT(S)                                                                                                                                      AGE
    kourier   LoadBalancer   172.30.51.103   a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com   80:31380/TCP,443:31390/TCP   67m

    公共地址位于 EXTERNAL-IP 字段,在本例中是 a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com

  3. 手动在 HTTP 请求的主机标头中设置应用程序的主机,但将请求定向到 ingress 网关的公共地址。

    $ curl -H "Host: hello-default.example.com" a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com

    输出示例

    Hello Serverless!

    您还可以通过将授权设置为应用程序的主机来发出 gRPC 请求,同时将请求直接定向到 ingress 网关:

    grpc.Dial(
        "a83e86291bcdd11e993af02b7a65e514-33544245.us-east-1.elb.amazonaws.com:80",
        grpc.WithAuthority("hello-default.example.com:80"),
        grpc.WithInsecure(),
    )
    注意

    如上例所示,请确保将对应的端口(默认为 80)附加到两个主机中。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.