第 10 章 安全性

10.1. 配置 TLS 身份验证

您可以使用 传输层安全 (TLS) 加密 Knative 流量并进行身份验证。

TLS 是 Knative Kafka 唯一支持的流量加密方法。红帽建议将 SASL 和 TLS 同时用于 Knative Kafka 资源。

注意

如果要使用 Red Hat OpenShift Service Mesh 集成启用内部 TLS,您必须使用 mTLS 启用 Service Mesh,而不是按照以下流程所述的内部加密。请参阅在使用带有 mTLS 的 Service Mesh 时启用 Knative Serving 指标的文档。

10.1.1. 为内部流量启用 TLS 身份验证

OpenShift Serverless 默认支持 TLS 边缘终止,以便最终用户的 HTTPS 流量加密。但是,OpenShift 路由后面的内部流量使用普通数据转发到应用。通过为内部流量启用 TLS,组件间发送的流量会进行加密,从而使此流量更加安全。

注意

如果要使用 Red Hat OpenShift Service Mesh 集成启用内部 TLS,您必须使用 mTLS 启用 Service Mesh,而不是按照以下流程所述的内部加密。

重要

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

有关红帽技术预览功能支持范围的详情,请参考 https://access.redhat.com/support/offerings/techpreview/

先决条件

  • 安装了 OpenShift Serverless Operator 和 Knative Serving。
  • 已安装 OpenShift (oc) CLI。

流程

  1. 在 spec 中创建一个包含 internal-encryption: "true" 字段的 Knative 服务:

    ...
    spec:
      config:
        network:
          internal-encryption: "true"
    ...
  2. 重启 knative-serving 命名空间中的 activator pod 来加载证书:

    $ oc delete pod -n knative-serving --selector app=activator

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

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

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

注意

如果您将 net-istio 用于 Ingress,并使用 security.dataPlane.mtls: true 通过 SMCP 启用 mTLS,Service Mesh 为 *.local 主机部署 DestinationRule,这代表不允许对 OpenShift Serverless 使用 DomainMapping

要临时解决这个问题,部署 PeerAuthentication 来启用 mTLS,而不是使用 security.dataPlane.mtls: true

先决条件

  • 为 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>
  2. 如果您使用 Red Hat OpenShift Service Mesh 作为 OpenShift Serverless 安装的 ingress,请使用以下内容标记 Kubernetes TLS secret:

    “networking.internal.knative.dev/certificate-uid": “<value>”

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

    注意

    {cert-manager-operator} 是一个技术预览功能。如需更多信息,请参阅安装 {cert-manager-operator} 文档。

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

    apiVersion: serving.knative.dev/v1alpha1
    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>

验证

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

    $ oc get domainmapping <domain_name>

    输出示例

    NAME                      URL                               READY   REASON
    example.com               https://example.com               True

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

    $ curl https://<domain_name>

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

10.1.4. 为 Kafka 代理配置 TLS 身份验证

Apache Kafka 客户端和服务器使用 传输层安全性 (TLS) 来加密 Knative 和 Kafka 之间的流量,以及用于身份验证。TLS 是 Knative Kafka 唯一支持的流量加密方法。

先决条件

  • 在 OpenShift Container Platform 上具有集群管理员权限。
  • OpenShift Serverless Operator、Knative Eventing 和 KnativeKafka CR 已安装在 OpenShift Container Platform 集群中。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。
  • 您有一个 Kafka 集群 CA 证书存储为一个 .pem 文件。
  • 您有一个 Kafka 集群客户端证书,并存储为 .pem 文件的密钥。
  • 安装 OpenShift CLI (oc) 。

流程

  1. knative-eventing 命名空间中创建证书文件作为 secret:

    $ oc create secret -n knative-eventing generic <secret_name> \
      --from-literal=protocol=SSL \
      --from-file=ca.crt=caroot.pem \
      --from-file=user.crt=certificate.pem \
      --from-file=user.key=key.pem
    重要

    使用密钥名称 ca.crtuser.crtuser.key。不要更改它们。

  2. 编辑 KnativeKafka CR,并在 broker spec 中添加对 secret 的引用:

    apiVersion: operator.serverless.openshift.io/v1alpha1
    kind: KnativeKafka
    metadata:
      namespace: knative-eventing
      name: knative-kafka
    spec:
      broker:
        enabled: true
        defaultConfig:
          authSecretName: <secret_name>
    ...

10.1.5. 为 Kafka 频道配置 TLS 验证

Apache Kafka 客户端和服务器使用 传输层安全性 (TLS) 来加密 Knative 和 Kafka 之间的流量,以及用于身份验证。TLS 是 Knative Kafka 唯一支持的流量加密方法。

先决条件

  • 在 OpenShift Container Platform 上具有集群管理员权限。
  • OpenShift Serverless Operator、Knative Eventing 和 KnativeKafka CR 已安装在 OpenShift Container Platform 集群中。
  • 您已创建了一个项目,或者具有适当的角色和权限访问项目,以便在 OpenShift Container Platform 中创建应用程序和其他工作负载。
  • 您有一个 Kafka 集群 CA 证书存储为一个 .pem 文件。
  • 您有一个 Kafka 集群客户端证书,并存储为 .pem 文件的密钥。
  • 安装 OpenShift CLI (oc) 。

流程

  1. 在所选命名空间中创建证书文件作为 secret:

    $ oc create secret -n <namespace> generic <kafka_auth_secret> \
      --from-file=ca.crt=caroot.pem \
      --from-file=user.crt=certificate.pem \
      --from-file=user.key=key.pem
    重要

    使用密钥名称 ca.crtuser.crtuser.key。不要更改它们。

  2. 编辑 KnativeKafka 自定义资源:

    $ oc edit knativekafka
  3. 引用您的 secret 和 secret 的命名空间:

    apiVersion: operator.serverless.openshift.io/v1alpha1
    kind: KnativeKafka
    metadata:
      namespace: knative-eventing
      name: knative-kafka
    spec:
      channel:
        authSecretName: <kafka_auth_secret>
        authSecretNamespace: <kafka_auth_secret_namespace>
        bootstrapServers: <bootstrap_servers>
        enabled: true
      source:
        enabled: true
    注意

    确保指定 bootstrap 服务器中的匹配端口。

    例如:

    apiVersion: operator.serverless.openshift.io/v1alpha1
    kind: KnativeKafka
    metadata:
      namespace: knative-eventing
      name: knative-kafka
    spec:
      channel:
        authSecretName: tls-user
        authSecretNamespace: kafka
        bootstrapServers: eventing-kafka-bootstrap.kafka.svc:9094
        enabled: true
      source:
        enabled: true