跳到内容

配置 Knative cert-manager 集成

Knative Serving 依赖于一个桥接组件来使用 cert-manager 进行自动证书颁发。如果您打算使用此功能,则需要启用 Knative cert-manager 集成。

先决条件

您的 Knative 集群中必须安装以下组件

警告

请确保您已安装 cert-manager。否则,Serving 控制器将无法正确启动。

Issuer 配置

Knative cert-manager 集成定义了三个对 cert-manager issuers 的引用,以配置用于 三种 Knative Serving 加密功能 的不同 CA。

  • issuerRef:用于入口(ingress)的外部域名证书的 issuer。
  • clusterLocalIssuerRef:用于入口(ingress)的集群本地域名证书的 issuer。
  • systemInternalIssuerRef:用于 Knative 内部组件使用的系统内部 TLS 证书的 issuer。

以下示例使用自签名 ClusterIssuer,并且 Knative cert-manager 集成将此 ClusterIssuer 引用到所有三个配置中。由于这不应在生产环境中使用(并且不支持在不中断服务的情况下轮换 CA),因此您应该考虑为每种用例使用哪个 CA,以及如何将信任分发给调用加密服务的客户端。对于 Knative 系统组件,Knative 提供了一种指定要信任的 CA 证书链的方法(详见下文)。

关于如何构建此结构没有通用的答案,这里有一个示例说明它可能是什么样子

功能 证书颁发机构 通过...信任
external-domain-tls Let's encrypt 浏览器客户端已包含 Let's encrypt 证书链,所有根 CA 将由 DevOps 团队添加到公司范围的 Docker 基础镜像中。
cluster-local-domain-tls 由集群管理员提供的 CA CA 由 DevOps 团队管理,并将添加到公司范围的 Docker 基础镜像中。
system-internal-tls 自签名 Cert-Manager ClusterIssuer CA 将由 cert-manager 填充。DevOps 团队将使用 trust-manager 将 CA 分发给 Knative 系统组件。

Issuer 选择

通常,您可以参考 cert-manager 文档。有适用于以下内容的示例:

重要

请注意,并非所有 issuer 类型都适用于每个 Knative 功能。

cluster-local-domain-tls 需要能够为集群本地域名(如 myapp.<namespace>myapp.<namespace>.svcmyapp.<namespace>.svc.cluster.local)颁发证书。CA 通常在集群外部,因此无法通过 ACME 协议(DNS01/HTTP01)进行验证。您可以使用允许创建这些证书的 issuer(例如,CA issuer)。

system-internal-tls 需要能够为 Knative 验证的特定 SAN(Subject Alternative Name)颁发证书。定义的 SAN 集合为:

  • kn-routing
  • kn-user-<namespace> ((其中每个 namespace 都是 Knative Service 已创建/将要创建的 namespace)
  • data-plane.knative.dev

由于这也不可能通过 ACME 协议(DNS01/HTTP01)进行,因此您需要配置一个允许创建这些证书的 issuer(例如,CA issuer)。

配置 Issuers

警告

自签名集群 issuer 不应在生产环境中使用,请参阅上面的 Issuer 配置 以获取更多信息。

  1. 创建并向您的集群应用以下自签名 ClusterIssuer

    # this issuer is used by cert-manager to sign all certificates
    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: cluster-selfsigned-issuer
    spec:
      selfSigned: {}
    ---
    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer # this issuer is specifically for Knative, it will use the CA stored in the secret created by the Certificate below
    metadata:
      name: knative-selfsigned-issuer
    spec:
      ca:
        secretName: knative-selfsigned-ca
    ---
    apiVersion: cert-manager.io/v1
    kind: Certificate # this creates a CA certificate, signed by cluster-selfsigned-issuer and stored in the secret knative-selfsigned-ca
    metadata:
      name: knative-selfsigned-ca
      namespace: cert-manager #  If you want to use it as a ClusterIssuer the secret must be in the cert-manager namespace.
    spec:
      secretName: knative-selfsigned-ca
      commonName: knative.dev
      usages:
        - server auth
      isCA: true
      issuerRef:
        kind: ClusterIssuer
        name: cluster-selfsigned-issuer
    
  2. 确保 ClusterIssuer 已就绪

    kubectl get clusterissuer cluster-selfsigned-issuer -o yaml
    kubectl get clusterissuer knative-selfsigned-issuer -o yaml
    
    结果:Status.Conditions 应包含 Ready=True

  3. 然后,在 config-certmanager ConfigMap 中引用 ClusterIssuer

    kubectl edit configmap config-certmanager -n knative-serving
    

    data 部分添加字段

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: config-certmanager
      namespace: knative-serving
      labels:
        networking.knative.dev/certificate-provider: cert-manager
    data:
      issuerRef: |
        kind: ClusterIssuer
        name: knative-selfsigned-issuer
      clusterLocalIssuerRef: |
        kind: ClusterIssuer
        name: knative-selfsigned-issuer
      systemInternalIssuerRef: |
        kind: ClusterIssuer
        name: knative-selfsigned-issuer
    

    确保文件已成功更新

    kubectl get configmap config-certmanager -n knative-serving -o yaml
    

无缝管理信任和轮换

如上所述,每个使用 HTTPS 调用 Knative Service 的客户端都需要信任 CA 和/或中间证书链。如果您查看 加密概述,您会发现有多个地方需要分发信任:

  • 集群外部客户端(浏览器和/或其他应用程序):这被视为 Knative 的范围之外。
  • 集群内部客户端(例如 Knative 或 Vanilla K8s 工作负载):见下文。
  • Knative 系统组件(例如 Activator、Queue-Proxy、Ingress-Controller):见下文。

为集群内部客户端(例如 Knative 或 Vanilla K8s 工作负载)建立信任

由于 Knative 不控制所有工作负载,并且设置高度依赖于您的运行时和/或语言,这超出了 Knative 的范围。但这里有一些需要考虑的点,因为有多种方法可以为您的应用程序提供 CA:

  • 在构建时将 CA 证书链添加到容器镜像(请注意,这会使 CA 轮换复杂化,您基本上需要重新构建每个应用程序)
  • 将 CA 证书链挂载到文件系统(例如,从 SecretConfigMap
  • 从环境变量读取
  • 通过 K8s API 从 Secret/ConfigMap 访问

如果无缝重新加载证书对您的客户端很重要,工作负载必须监视 K8s 资源(Secret/ConfigMap)的变化,或者监视文件系统的变化。如果工作负载监视文件系统,重要的是要注意,在 K8s 上使用 ionotify 来捕获变化的 Secrets/ConfigMaps 并不可靠。测试表明,定期轮询并检查文件系统上的证书是否发生变化更可靠。

这里有一些 golang 的示例

为 Knative 系统组件建立信任

Knative 系统组件可以配置为信任来自 ConfigMaps 的一个或多个 CA 证书链。集群管理员需要确保相应地进行配置,以避免在 轮换期间 出现任何中断。Knative 组件会查找组件运行所在命名空间中的 ConfigMap,例如:

  • knative-serving
  • istio-system(使用 net-istio 时)
  • kourier-system(使用 net-kourier 时)
  • Knative Service 运行的每个命名空间

Knative 会查找带有标签 networking.knative.dev/trust-bundle: "true"ConfigMap,并读取所有 data 键(无论名称如何)。一个键可以包含一个或多个 CA/中间证书。如果它们有效,它们将被添加到 Knative 组件的信任存储中。

这里有一个 ConfigMap 可能是什么样子的示例

apiVersion: v1
data:
  cacerts.pem: |
    -----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
  namespace: knative-serving

使用 trust-manager 分发证书链

由于将 CA 证书链分发到所有命名空间可能是一项繁琐的任务,您可以使用 trust-manager 来自动分发 CA 证书链。有关如何执行此操作的更多信息,请参阅其文档。

轮换期间的信任

在轮换 CA 和/或中间证书时,您的客户端需要信任旧的和新的 CA/证书链,直到轮换完成。使用上面的 信任方法,您可以实现完整的链轮换而不中断服务。

  1. 确保您现有的设置已启动并正在运行。
  2. 确保所有 Knative Service 都具有相关的证书且未过期。
  3. 确保您的 CA(和完整证书链)未过期。
  4. 将现有的新的 CA(和完整证书链)添加到信任证书链中(手动或通过 trust-manager)。
  5. 重新配置您的 cert-manager ClusterIssuersIssuers 以使用新的 CA。
  6. 等待直到所有证书过期并通过 cert-manager 续订。
  7. 所有证书现在都由新的 CA 签名。
  8. 添加一些宽限期,以确保所有组件都已拾取所有更改。
  9. 从信任证书链中删除旧的 CA。

我们使用分析和 cookie 来了解网站流量。有关您使用我们网站的信息会与 Google 共享以达到此目的。了解更多。