我们在GKE中使用ingress-nginx控制器公开了十几个服务。
为了在同一域名上正确路由流量,我们需要使用重写目标规则。
自2019年推出以来,这些服务在没有任何维护的情况下运行良好,直到最近;当cert-manager突然停止更新"让我们加密"证书时,我们"解决了"。这是通过暂时删除"tls"节,强制我们的客户端使用HTTP版本。
之后,我们删除了所有cert-manager试图从头开始设置的痕迹。
现在,cert-manager正在创建证书签名请求,生成一个acme http求解器pod并将其添加到入口,但是在访问其url时,我可以看到它返回一个空响应,而不是预期的令牌。
这与rewrite-target注释有关,它把acme挑战的路由弄得一团糟。最让我困惑的是,这以前是行得通的。(这是由前雇员设置的)
不幸的是,禁用rewrite-target不是一个选项,因为它会阻止路由正常工作。
使用dns01将无法工作,因为我们的ISP不支持编程式更改DNS记录。
是否有一种方法可以使此工作而不禁用重写目标?
注:以下是Github上报告的一些类似案例:
- https://github.com/cert-manager/cert-manager/issues/2826
- https://github.com/cert-manager/cert-manager/issues/286
- https://github.com/cert-manager/cert-manager/issues/487
都没用
下面是我的ClusterIssuer
的定义apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: mail@domain.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx
请共享您正在使用的群集发行者或问题。
ingressClass
如果ingressClass字段时,
cert-manager
将创建新入口资源,以便将流量路由到acmesolver
pod,负责响应ACME挑战验证请求。
Ref: https://cert-manager.io/v0.12-docs/configuration/acme/http01/#ingressclass
大多数情况下,如果DNS或HTTP工作正常,我们不会看到HTTP求解器挑战它并被删除。
另外,确保你的入口没有ssl重定向注释,这也可能是证书背后的一个原因。没有生成
您是否尝试检查证书管理器的其他对象,如订单和证书状态请求?kubectl describe challenge
你得到404
吗?如果您连续尝试,可能会有机会达到让我们加密请求生成证书的速率限制。
故障排除:https://cert-manager.io/docs/faq/troubleshooting/#troubleshooting-a-failed-certificate-request
如果这对任何人有帮助的话,我花了一天的时间才解决了这个问题。
解决方案是创建一个不重写的备用入口。最初的入口是这样的。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: reward-ingress-https
namespace: prod
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: public
tls:
- hosts:
- home.myhome.net
secretName: my-secret
rules:
- host: "home.myhome.net"
http:
paths:
- pathType: Prefix
path: /reward(/|$)(.*)
backend:
service:
name: reward-service
port:
number: 7777
为了确保这不会干扰letsencrypt发出的请求,我创建了另一个入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: acme-ingress
namespace: prod
annotations:
cert-manager.io/cluster-issuer: prod-issuer
acme.cert-manager.io/http01-edit-in-place: "true"
spec:
ingressClassName: public
rules:
- host: "home.myhome.net"
http:
paths:
- pathType: Prefix
path: /.well-known/acme-challenge/
backend:
service:
name: cert-manager
port:
number: 8089
配置http01
类型的Issuer时,默认的serviceType为NodePort
。这意味着,它甚至不会通过入口控制器。来自文档:
默认情况下,当您不设置HTTP01或将serviceType设置为空字符串时,将使用NodePort类型。通常不需要更改。
我不确定其余的设置看起来像什么,但http01
导致acme服务器发出HTTP请求(不是https)。你需要确保你的nginx有http(80)的监听器。它遵循重定向,所以你可以监听http并将所有流量重定向到https,这是合法的和工作的。
cert-manager创建ingress
资源用于验证。它引导交通进入临时隔离区。这个入口有它自己的一套规则,你可以使用这个设置来控制它。您可以尝试禁用或修改此资源上的重写目标。
请分享相关的nginx和cert-manager日志,这可能有助于调试或了解问题所在。