配置 Knative cert-manager 集成¶
Knative Serving 依赖于一个桥接组件来使用 cert-manager 进行自动证书颁发。如果您打算使用此功能,则需要启用 Knative cert-manager 集成。
先决条件¶
您的 Knative 集群中必须安装以下组件
- Knative Serving.
cert-manager版本1.0.0或更高版本。
警告
请确保您已安装 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>.svc 和 myapp.<namespace>.svc.cluster.local)颁发证书。CA 通常在集群外部,因此无法通过 ACME 协议(DNS01/HTTP01)进行验证。您可以使用允许创建这些证书的 issuer(例如,CA issuer)。
system-internal-tls 需要能够为 Knative 验证的特定 SAN(Subject Alternative Name)颁发证书。定义的 SAN 集合为:
kn-routingkn-user-<namespace>((其中每个 namespace 都是 Knative Service 已创建/将要创建的 namespace) data-plane.knative.dev
由于这也不可能通过 ACME 协议(DNS01/HTTP01)进行,因此您需要配置一个允许创建这些证书的 issuer(例如,CA issuer)。
配置 Issuers¶
警告
自签名集群 issuer 不应在生产环境中使用,请参阅上面的 Issuer 配置 以获取更多信息。
-
创建并向您的集群应用以下自签名
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 -
确保
ClusterIssuer已就绪结果:kubectl get clusterissuer cluster-selfsigned-issuer -o yaml kubectl get clusterissuer knative-selfsigned-issuer -o yamlStatus.Conditions应包含Ready=True。 -
然后,在
config-certmanagerConfigMap 中引用ClusterIssuerkubectl 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 证书链挂载到文件系统(例如,从
Secret或ConfigMap) - 从环境变量读取
- 通过 K8s API 从
Secret/ConfigMap访问
如果无缝重新加载证书对您的客户端很重要,工作负载必须监视 K8s 资源(Secret/ConfigMap)的变化,或者监视文件系统的变化。如果工作负载监视文件系统,重要的是要注意,在 K8s 上使用 ionotify 来捕获变化的 Secrets/ConfigMaps 并不可靠。测试表明,定期轮询并检查文件系统上的证书是否发生变化更可靠。
这里有一些 golang 的示例
- 将证书链保存为文件到指定路径: https://golang.ac.cn/src/crypto/x509/root_linux.go(注意:不重启无法重新加载)
- 通过 K8s API 动态重新加载: https://github.com/knative/serving/blob/main/pkg/activator/certificate/cache.go
- 使用监视进程从文件系统重新加载: https://github.com/knative/serving/blob/main/pkg/queue/certificate/watcher.go
为 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/证书链,直到轮换完成。使用上面的 信任方法,您可以实现完整的链轮换而不中断服务。
- 确保您现有的设置已启动并正在运行。
- 确保所有 Knative Service 都具有相关的证书且未过期。
- 确保您的 CA(和完整证书链)未过期。
- 将现有的和新的 CA(和完整证书链)添加到信任证书链中(手动或通过 trust-manager)。
- 重新配置您的 cert-manager
ClusterIssuers或Issuers以使用新的 CA。 - 等待直到所有证书过期并通过 cert-manager 续订。
- 所有证书现在都由新的 CA 签名。
- 添加一些宽限期,以确保所有组件都已拾取所有更改。
- 从信任证书链中删除旧的 CA。