配置 Knative cert-manager 集成¶
Knative Serving 依赖于一个桥接组件来使用 cert-manager 进行自动证书配置。如果您打算使用此功能,则需要启用 Knative cert-manager 集成。
先决条件¶
以下必须安装在您的 Knative 集群上
- Knative Serving.
cert-manager
版本1.0.0
或更高版本。
警告
确保您已安装 cert-manager。否则,Serving 控制器将无法正常启动。
颁发者配置¶
Knative cert-manager 集成定义了对 cert-manager 颁发者 的三个引用,用于为 三个 Knative Serving 加密功能 配置不同的 CA
issuerRef
: 用于入口的外部域证书的颁发者。clusterLocalIssuerRef
: 用于入口的集群本地域证书的颁发者。systemInternalIssuerRef
: 用于 Knative 内部组件使用的系统内部 TLS 证书的证书的颁发者。
以下示例使用自签名 ClusterIssuer
,并且 Knative cert-manager 集成将该 ClusterIssuer
用于所有三个配置。由于这 **不应在生产环境中使用**(并且不支持在不停止服务的情况下轮换 CA),因此您应该考虑哪个 CA 应该用于每个用例以及如何将信任分配给调用加密服务的客户端。对于 Knative 系统组件,Knative 提供了一种方法来指定应该被信任的 CA 捆绑包(下面将详细介绍)。
没有关于如何构建此结构的通用答案,这里有一个示例说明其可能的外观
功能 | 证书颁发机构 | 通过以下方式信任 |
---|---|---|
外部域 TLS | Let's encrypt | 浏览器客户端已经拥有 Let's encrypt 链,所有根 CA 将由 DevOps 团队添加到公司范围的 Docker 基础镜像中。 |
集群本地域 TLS | 集群运营商提供的 CA | CA 由 DevOps 团队管理,并将添加到公司范围的 Docker 基础镜像中。 |
系统内部 TLS | 自签名 Cert-Manager ClusterIssuer |
CA 将由 cert-manager 填充。DevOps 团队将使用 trust-manager 将 CA 分发到 Knative 系统组件。 |
颁发者选择¶
一般来说,您可以参考 cert-manager 文档。对于以下方面有示例可用
重要事项
请注意,并非所有颁发者类型都适用于每个 Knative 功能。
cluster-local-domain-tls
需要能够为集群本地域(如 myapp.<namespace>
、myapp.<namespace>.svc
和 myapp.<namespace>.svc.cluster.local
)签名证书。CA 通常在集群之外,因此无法通过 ACME 协议(DNS01/HTTP01)进行验证。您可以使用允许创建这些证书的颁发者(例如,CA 颁发者)。
system-internal-tls
需要能够为 Knative 验证的特定 SAN 签名。定义的 SAN 集合是
kn-routing
kn-user-<namespace>
(是每个创建了/将创建 Knative 服务的命名空间) data-plane.knative.dev
由于这也不可能通过 ACME 协议(DNS01/HTTP01)完成,因此您需要配置允许创建这些证书的颁发者(例如,CA 颁发者)。
配置颁发者¶
警告
自签名集群颁发者不应在生产环境中使用,请参阅上面的 颁发者配置 以了解更多信息。
-
创建并应用以下自签名
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 yaml
Status.Conditions
应包含Ready=True
。 -
然后在
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 服务的客户端都需要信任 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)的更改或监视文件系统。如果工作负载正在监视文件系统,重要的是要注意,使用 ionotify
来捕获正在更改的 Secret/ConfigMap 在 K8s 上不太可靠。测试表明,定期轮询并检查文件系统上的证书以查看更改更可靠。
以下是一些 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 服务的命名空间
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 服务都具有相关的证书,并且没有过期。
- 确保您的 CA(和完整链)没有过期。
- 将现有的和新的 CA(以及完整链)添加到信任捆绑包中(手动或通过信任管理器)。
- 重新配置您的 cert-manager
ClusterIssuers
或Issuers
以使用新的 CA。 - 等待所有证书过期并由 cert-manager 续订。
- 所有证书现在都由新的 CA 签署。
- 添加一些宽限期以确保所有组件都接收到了所有更改。
- 从信任捆绑包中删除旧的 CA。