新:获取项目更新在推特Mastodon

HTTP01

📌 本页面重点介绍如何解决 ACME HTTP-01 挑战。如果您正在寻找有关如何通过注释 Ingress 或 Gateway 资源来自动创建证书资源的信息,请参阅 保护 Ingress 资源保护 Gateway 资源

cert-manager 使用您现有的 Ingress 或 Gateway 配置来解决 HTTP01 挑战。

配置 HTTP01 Ingress 解決方案

本页面包含有关 Issuer 资源的 HTTP01 挑战解决器配置中可用的不同选项的详细信息。有关配置 ACME 发行者及其 API 格式的更多信息,请阅读 ACME 发行者 文档。

您可以在 Let's Encrypt 挑战类型页面 上了解有关 HTTP01 挑战类型的工作原理。

以下是一个简单的 HTTP01 ACME 发行者的示例,其中包含更多配置选项

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: example-issuer
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: example-issuer-account-key
solvers:
- http01:
ingress:
ingressClassName: nginx

选项

HTTP01 Issuer 支持许多其他选项。有关可用选项范围的完整详细信息,请阅读 参考文档

ingressClassName

📌 字段 ingressClassName 是在 cert-manager 1.12 中添加的。

如果指定了 ingressClassName 字段,cert-manager 将创建新的 Ingress 资源,以便将流量路由到负责响应 ACME 挑战验证请求的 acmesolver pod。

这是配置 Ingress 控制器推荐的方式。大多数 Ingress 控制器都支持 ingressClassName,ingress-gce 是一个值得注意的例外(根据页面 配置 Ingress 以进行外部负载平衡)。

class

如果指定了 class 字段,将创建一个具有随机生成名称的新 Ingress 资源以解决挑战。此新资源将具有带有键 kubernetes.io/ingress.class 的注释,其值设置为 class 字段的值。

此字段仅推荐与 ingress-gce 一起使用。ingress-gce 不支持 ingressClassName 字段

name

如果指定了 name 字段,cert-manager 将编辑命名的 ingress 资源以解决 HTTP01 挑战。

这对于与诸如 ingress-gce 等 ingress 控制器兼容非常有用,这些控制器为创建的每个 Ingress 资源使用唯一的 IP 地址。

当使用为所有 ingress 资源公开单个 IP 的 ingress 控制器时,应避免此模式,因为它可能导致与某些特定于 ingress 控制器注释的兼容性问题。

如果未指定 classingressClassName,并且也未指定 name,cert-manager 将默认创建 *新的* Ingress 资源,但 *不会* 在这些资源上设置 ingress 类,这意味着您集群中安装的 *所有* ingress 控制器都将为挑战解决器提供服务,可能会产生额外成本。

serviceType

在极少数情况下,可能无法/不希望使用 NodePort 作为 HTTP01 挑战响应服务的类型,例如由于 Kubernetes 限制限制。要定义在挑战响应期间要使用的 Kubernetes 服务类型,请指定以下 HTTP01 配置

http01:
ingress:
# Valid values are ClusterIP and NodePort
serviceType: ClusterIP

默认情况下,当您未设置 HTTP01 或将 serviceType 设置为空字符串时,将使用类型 NodePort。通常情况下,不需要更改此设置。

podTemplate

您可能希望更改或添加解决器 pod 的标签和注释。这些可以在 podTemplate 下的 metadata 字段下配置。

同样,您可以通过在 podTemplatespec 字段下配置来设置解决器 pod 的 nodeSelector、容差和亲和力。无法编辑其他 spec 字段。

以下是如何配置模板的示例

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ...
spec:
acme:
server: ...
privateKeySecretRef:
name: ...
solvers:
- http01:
ingress:
podTemplate:
metadata:
labels:
foo: "bar"
env: "prod"
spec:
nodeSelector:
bar: baz

添加的标签和注释将合并到 cert-manager 默认值之上,覆盖具有相同键的条目。

podTemplate 中不存在其他字段。

ingressTemplate

可以将标签和注释添加到解决器 ingress 资源。当您在整个集群中管理多个 Ingress 控制器并且希望确保正确的控制器将拾取并公开解决器(以便解决即将到来的挑战)时,这非常有用。这些可以在 ingressTemplate 下的 metadata 字段下配置

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ...
spec:
acme:
server: ...
privateKeySecretRef:
name: ...
solvers:
- http01:
ingress:
ingressTemplate:
metadata:
labels:
foo: "bar"
annotations:
"nginx.ingress.kubernetes.io/whitelist-source-range": "0.0.0.0/0,::/0"
"nginx.org/mergeable-ingress-type": "minion"
"traefik.ingress.kubernetes.io/frontend-entry-points": "http"

添加的标签和注释将合并到 cert-manager 默认值之上,覆盖具有相同键的条目。

无法编辑 ingress 的其他字段。

配置 HTTP-01 Gateway API 解决方案

功能状态:cert-manager 1.15 [beta]

Gateway 和 HTTPRoute 资源是 Gateway API 的一部分,Gateway API 是您在 Kubernetes 集群上安装的一组 CRD,它们提供了比 Ingress API 更好的功能。

📌 此功能需要安装 Gateway API 包 并向 cert-manager 控制器传递额外的标志。

要安装 v1.5.1 Gateway API 包(Gateway CRD 和 webhook),请运行以下命令

kubectl apply -f "https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml"

要在 cert-manager 中启用此功能,请打开 GatewayAPI 功能门

  • 如果您使用的是 Helm

    helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager \
    --set "extraArgs={--enable-gateway-api}"
  • 如果您使用的是原始 cert-manager 清单,请将以下标志添加到 cert-manager 控制器 Deployment 中

    args:
    - --enable-gateway-api

Gateway API CRD 应该在 cert-manager 启动之前安装,或者 cert-manager Deployment 应该在安装 Gateway API CRD 后重新启动。这很重要,因为一些 cert-manager 组件只在启动时执行 Gateway API 检查。您可以使用以下命令重新启动 cert-manager

kubectl rollout restart deployment cert-manager -n cert-manager

🚧 cert-manager 1.14+ 已在 v1 Kubernetes Gateway API 上进行测试。它也应该与 v1beta1 和 v1alpha2 一起使用,因为有资源转换,但尚未对其进行测试。

Gateway API HTTPRoute HTTP-01 解决器使用给定的标签创建临时 HTTPRoute。这些标签必须与包含端口 80 上监听器的 Gateway 相匹配。

以下是一个使用 Gateway API 的 HTTP-01 ACME Issuer 示例

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt
namespace: default
spec:
acme:
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- name: traefik
namespace: traefik
kind: Gateway

Issuer 依赖于集群中现有的 Gateway。cert-manager 不会编辑 Gateway 资源。

例如,以下 Gateway 将允许 Issuer 解决挑战

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: traefik
namespace: traefik
spec:
gatewayClassName: traefik
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All

在上面的示例中,Gateway 是专门为解决 HTTP-01 挑战而创建的,但您也可以选择重复使用您现有的 Gateway,只要它在端口 80 上有一个监听器即可。

您的颁发者上的 标签 可能引用了位于不同命名空间的网关,只要网关的端口 80 监听器配置为 from: All。请注意,证书仍然将在与颁发者相同的命名空间中创建,这意味着您将无法在上面提到的网关中引用此密钥。

当上述颁发者呈现证书时,cert-manager 会创建临时 HTTPRoute。例如,使用以下证书

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-tls
namespace: default
spec:
issuerRef:
name: letsencrypt
dnsNames:
- example.net

您将看到 HTTPRoute 出现

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: cm-acme-http-solver-gdhvg
namespace: default
spec:
parentRefs:
- name: traefik
namespace: traefik
kind: Gateway
hostnames:
- example.net
rules:
- backendRefs:
- port: 8089
name: cm-acme-http-solver-gdhvg
weight: 1
matches:
- path:
type: Exact
value: /.well-known/acme-challenge/YadC4gaAzqEPU1Yea0D2MrzvNRWiBCtUizCtpiRQZqI

证书签发后,HTTPRoute 会被删除。

标签

这些标签被复制到 cert-manager 为解决 HTTP-01 挑战而创建的临时 HTTPRoute 中。这些标签必须与集群上的其中一个网关资源匹配。匹配的网关在端口 80 上有一个监听器。

请注意,当标签与集群上的任何网关不匹配时,cert-manager 将创建临时 HTTPRoute 挑战,并且不会发生任何事情。

serviceType

此字段与 http01.ingress.serviceType 的含义相同。

为 HTTP-01 求解器传播检查设置名称服务器

cert-manager 将在尝试 HTT01 挑战之前执行可达性测试。默认情况下,cert-manager 将使用从 /etc/resolv.conf 获取的递归名称服务器来查询挑战 URL。

如果不需要这样做(例如使用分层 DNS),cert-manager 控制器会公开一个标志,允许您更改此行为

--acme-http01-solver-nameservers 由逗号分隔的字符串,其中包含 cert-manager 应该查询的递归名称服务器的主机和端口。

示例用法

--acme-http01-solver-nameservers="8.8.8.8:53,1.1.1.1:53"

如果您使用的是 cert-manager helm 图表,您可以通过 .Values.extraArgs 设置递归名称服务器,或者在 helm install/upgrade 时使用 --set 命令进行设置

--set 'extraArgs={--acme-http01-solver-nameservers=8.8.8.8:53\,1.1.1.1:53}'