HTTP 验证
使用 HTTP 验证颁发 ACME 证书
cert-manager 可用于使用 ACME 协议从 CA 获取证书。ACME 协议支持各种挑战机制,这些机制用于证明域所有权,以便可以为该域颁发有效证书。
其中一种挑战机制是 HTTP01 挑战。使用 HTTP01 挑战,您可以通过确保域上存在特定文件来证明对域的所有权。如果您可以将给定文件发布到给定路径下,则假设您控制该域。
以下颁发者定义了启用 HTTP 验证所需的信息。您可以在颁发者文档中详细了解颁发者资源。
apiVersion: cert-manager.io/v1kind: Issuermetadata:name: letsencrypt-stagingnamespace: defaultspec:acme:# The ACME server URLserver: https://acme-staging-v02.api.letsencrypt.org/directory# Email address used for ACME registrationemail: user@example.com# Name of a secret used to store the ACME account private keyprivateKeySecretRef:name: letsencrypt-staging# Enable the HTTP-01 challenge providersolvers:# An empty 'selector' means that this solver matches all domains- selector: {}http01:ingress:ingressClassName: nginx
我们已为 Let's Encrypt 的 暂存环境指定了 ACME 服务器 URL。暂存环境不会颁发可信证书,但用于确保验证过程在迁移到生产环境之前正常运行。Let's Encrypt 的生产环境施加了更严格的 速率限制,因此为了减少您遇到这些限制的可能性,强烈建议您先使用暂存环境。要迁移到生产环境,只需创建一个新的颁发者,并将 URL 设置为 https://acme-v02.api.letsencrypt.org/directory
。
ACME 协议的第一阶段是客户端向 ACME 服务器注册。此阶段包括生成一个非对称密钥对,然后将其与颁发者中指定的电子邮件地址相关联。确保将此电子邮件地址更改为有效的您拥有的电子邮件地址。它通常用于在您的证书即将到期时发送到期通知。生成的私钥存储在名为 letsencrypt-staging
的 Secret 中。
我们必须提供一个或多个求解器来处理 ACME 挑战。在本例中,我们希望使用 HTTP 验证,因此我们指定了一个 http01
求解器。我们可以选择将不同的域映射到不同的求解器配置。
创建上述颁发者后,我们可以使用它来获取证书。
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: example-comnamespace: defaultspec:secretName: example-com-tlsissuerRef:name: letsencrypt-stagingcommonName: example.comdnsNames:- www.example.com
证书资源描述了我们想要的证书以及可以用于获取证书的可能方法。您可以在文档中详细了解证书资源。如果证书成功获取,生成的密钥对将存储在与证书位于同一命名空间中的名为 example-com-tls
的 secret 中。
证书将具有 example.com
的通用名称,并且 主题备用名称 (SAN) 将是 example.com
和 www.example.com
。请注意,只有这些 SAN 将被 TLS 客户端接受。
在我们的证书中,我们引用了上面提到的 letsencrypt-staging
颁发者。颁发者必须与证书位于同一命名空间。如果您想引用一个 ClusterIssuer
(它是颁发者的集群范围版本),您必须将 kind: ClusterIssuer
添加到 issuerRef
节。
有关 ClusterIssuers
的更多信息,请阅读 ClusterIssuer
文档。
acme
节定义了我们 ACME 挑战的配置。这里我们定义了 HTTP01 挑战的配置,它将用于验证域所有权。为了验证 http01
节中提到的每个域的所有权,cert-manager 将创建一个 Pod、服务和 Ingress,这些资源会公开一个满足 HTTP01 挑战的 HTTP 端点。
ingressClassName
、class
和 name
字段可以在 http01
节中用于控制 cert-manager 如何与 Ingress 资源交互。
-
如果指定了
ingressClassName
字段,将创建一个具有随机生成名称的新 ingress 资源,以解决挑战。这个新的资源将具有值为ingressClassName
字段值的ingressClassName
字段。这是配置应使用哪个 Ingress 控制器 的推荐方法。这适用于 NGINX Ingress 控制器。 -
如果指定了
class
字段,将创建一个具有随机生成名称的新 ingress 资源,以解决挑战。这个新的资源将具有一个带键为kubernetes.io/ingress.class
且值为class
字段值的注释。只有当 不支持ingressClassName
字段 的 ingress-gce 时,才推荐使用此字段。 -
如果指定了
name
字段,则必须在与证书位于同一命名空间中,且具有相同名称的 Ingress 资源已经存在,并且它将仅修改以添加解决挑战的适当规则。此字段对于 Google Cloud Loadbalancer Ingress 控制器以及许多其他为每个 Ingress 资源分配单个公共 IP 地址的控制器很有用。如果没有手动干预,创建新的 Ingress 资源会导致任何挑战失败。 -
如果两者都没有指定,则将使用随机生成的名称创建新的 Ingress 资源,但它们不会设置 ingress 类注释。
-
如果两者都指定,则
ingress
字段将优先。
验证域所有权后,任何受 cert-manager 影响的资源都将被清理或删除。
注意:将每个域名指向 Ingress 控制器的正确 IP 地址是您的责任。
创建上述证书后,我们可以使用 kubectl describe
检查它是否已成功获取。
$ kubectl describe certificate example-comEvents: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 "http-01" validationNormal DomainVerified 55m cert-manager Domain "www.example.com" verified with "http-01" validationNormal IssueCert 55m cert-manager Issuing certificate...Normal CertObtained 55m cert-manager Obtained certificate from ACME serverNormal CertIssued 55m cert-manager Certificate issued successfully
您还可以使用 kubectl get secret example-com-tls -o yaml
检查颁发是否成功。您应该会看到一个 base64 编码的已签名的 TLS 密钥对。
获取证书后,cert-manager 将定期检查其有效性,并在证书即将到期时尝试续期。当证书上的“不迟于”字段小于当前时间加上 30 天时,cert-manager 认为证书即将到期。