最新:在TwitterMastodon 获取项目更新。

DNS 验证

使用 DNS 验证签发 ACME 证书

cert-manager 可以使用 ACME 协议从 CA 获取证书。ACME 协议支持各种挑战机制,这些机制用于证明对域名的所有权,以便为该域名签发有效的证书。

其中一种挑战机制是 DNS01。使用 DNS01 挑战,您可以通过证明您控制其 DNS 记录来证明对域名的所有权。这可以通过创建具有特定内容的 TXT 记录来完成,该记录证明您控制域的 DNS 记录。

以下颁发者定义了启用 DNS 验证所需的信息。您可以在 颁发者文档 中了解更多关于颁发者资源的信息。

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
namespace: default
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: user@example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# ACME DNS-01 provider configurations
solvers:
# An empty 'selector' means that this solver matches all domains
- selector: {}
dns01:
cloudDNS:
# The ID of the GCP project
# reference: https://cert-manager.k8s.ac.cn/docs/tutorials/acme/dns-validation/
project: $PROJECT_ID
# This is the secret used to access the service account
serviceAccountSecretRef:
name: clouddns-dns01-solver-svc-acct
key: key.json
# We only use cloudflare to solve challenges for example.org.
# Alternative options such as 'matchLabels' and 'dnsZones' can be specified
# as part of a solver's selector too.
- selector:
dnsNames:
- example.org
dns01:
cloudflare:
email: my-cloudflare-acc@example.com
# !! Remember to create a k8s secret before
# kubectl create secret generic cloudflare-api-key-secret
apiKeySecretRef:
name: cloudflare-api-key-secret
key: api-key

我们已经为 Let's Encrypt 的 预发布环境 指定了 ACME 服务器 URL。预发布环境不会签发受信任的证书,但用于确保验证过程在移至生产环境之前正常工作。Let's Encrypt 的生产环境实施了更严格的 速率限制,因此为了降低您达到这些限制的可能性,强烈建议您从使用预发布环境开始。要移至生产环境,只需创建一个新的颁发者,并将 URL 设置为 https://acme-v02.api.letsencrypt.org/directory

ACME 协议的第一阶段是客户端向 ACME 服务器注册。此阶段包括生成一个非对称密钥对,然后将其与颁发者中指定的电子邮件地址相关联。确保将此电子邮件地址更改为您拥有的有效电子邮件地址。它通常用于在证书即将到期时发送到期通知。生成的私钥存储在名为 letsencrypt-staging 的密钥中。

The dns01 段包含一个 DNS01 提供程序列表,这些提供程序可用于解决 DNS 挑战。我们的颁发者定义了两个提供程序。这使我们可以选择在获取证书时使用哪一个。

有关 DNS 提供程序配置的更多信息,包括支持的提供程序列表,可以在 DNS01 参考文档 中找到。

创建完上面的颁发者后,我们就可以使用它来获取证书。

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com
namespace: default
spec:
secretName: example-com-tls
issuerRef:
name: letsencrypt-staging
dnsNames:
- '*.example.com'
- example.com
- example.org

证书资源描述了我们想要的证书以及获取证书的可能方法。您可以像其他域名一样获取通配符域名的证书。确保在您的 YAML 资源中用星号包裹通配符域名,以避免格式问题。如果您在同一证书上同时指定 example.com*.example.com,则验证过程将花费更长的时间,因为每个域名都必须依次验证。您可以在 文档 中了解有关证书资源的更多信息。如果证书获取成功,生成的密钥对将存储在与证书位于同一命名空间的名为 example-com-tls 的密钥中。

证书将具有 *.example.com 的公用名,并且 主题备用名称 (SAN) 将为 *.example.comexample.comexample.org

在我们的证书中,我们引用了上面的 letsencrypt-staging 颁发者。颁发者必须与证书位于同一命名空间。如果您想引用 ClusterIssuer(颁发者的集群范围版本),则必须在 issuerRef 段中添加 kind: ClusterIssuer

有关 ClusterIssuers 的更多信息,请阅读 颁发者概念

The acme 段定义了我们 ACME 挑战的配置。在这里,我们为 DNS 挑战定义了配置,该配置将用于验证域名所有权。对于 dns01 段中提到的每个域名,cert-manager 将使用引用颁发者中的提供程序凭据来创建名为 _acme-challenge 的 TXT 记录。然后,此记录将由 ACME 服务器验证以签发证书。一旦域名所有权得到验证,所有受 cert-manager 影响的记录都将被清理。

注意:您有责任确保所选提供程序对您的域名具有权威性。

创建完上面的证书后,我们可以使用 kubectl describe 检查证书是否已成功获取。

$ kubectl describe certificate example-com
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CreateOrder 57m cert-manager Created new ACME order, attempting validation...
Normal DomainVerified 55m cert-manager Domain "*.example.com" verified with "dns-01" validation
Normal DomainVerified 55m cert-manager Domain "example.com" verified with "dns-01" validation
Normal DomainVerified 55m cert-manager Domain "example.org" verified with "dns-01" validation
Normal IssueCert 55m cert-manager Issuing certificate...
Normal CertObtained 55m cert-manager Obtained certificate from ACME server
Normal CertIssued 55m cert-manager Certificate issued successfully

您还可以使用 kubectl get secret example-com-tls -o yaml 检查签发是否成功。您应该看到一个 base64 编码的已签署 TLS 密钥对。

一旦我们的证书获得,cert-manager 将定期检查其有效性,并在其即将到期时尝试续订。当证书上的“不早于”字段小于当前时间加 30 天时,cert-manager 会认为证书即将到期。