【问题标题】:ingress-nginx, cert-manager and ingressClassNameingress-nginx、cert-manager 和 ingressClassName
【发布时间】:2021-12-02 12:54:21
【问题描述】:

我最近将ingress-nginx 升级到了 1.0.3 版。

因此,我从 ingress 中删除了 kubernetes.io/ingress.class 注释,并改为使用 .spec.ingressClassName

我正在运行cert-manager-v1.4.0

今天早上我收到一封电子邮件,说我的 Let's Encrypt 证书将在 10 天后过期。我试图弄清楚它出了什么问题 - 不能肯定这完全是由于 ingress-nginx 升级造成的。

我删除了CertificateRequest,看看它是否会自行修复。我收到了一个新的Ingress 挑战,但是:

  1. 挑战入口正确设置了 kubernetes.io/ingress.class 注释,尽管我的入口改为 .spec.ingressClassName - 不知道如何或为什么,但似乎应该没问题。

  2. 但是,入口控制器没有接收到挑战入口,它说:

ingress class annotation is not equal to the expected by Ingress Controller

我想它只需要.spec.ingressClassName,尽管我认为注释应该也可以工作。

所以我在挑战入口手动设置.spec.ingressClassName。入口控制器立即看到了它,其余过程运行顺利,我得到了一个新证书 - 耶。

在我看来,这种情况会再次发生,所以我需要知道如何:

  1. 说服cert-manager 使用.spec.ingressClassName 而不是kubernetes.io/ingress.class 创建挑战入口。也许这在 1.5 或 1.6 中已修复?

  2. 说服ingress-nginx 尊重挑战入口的kubernetes.io/ingress.class 注释。我不知道为什么这不起作用。

【问题讨论】:

  • 你是从哪个版本升级 ingress 的?所以我安装在 GKE 集群 ingress-nginx 1.0.4 + cert-manager v.1.4.0 上,我无法重现这种行为,一旦它由于不同的错误而被卡住,我看到我的 challenge ingress 没有 @987654343 @ 指定,但是在修复另一个错误后,证书已成功颁发。如果您可以再次复制此错误,请分享此链 certificate -> certificate request -> order -> challenge 以查看卡住的位置和原因。
  • @moonkotte:我是从0.48.1升级的。由于这是一个非生产系统,我不介意在cert-manager 决定更新证书之前尝试重现此故障。如何手动触发续订过程以查看是否发生这种情况?删除Certificate? Secret?
  • 我也测试了nginx 的不同版本,从1.0.0 开始,ingressClass 已包含在内(我通过helm 安装/升级/降级所有内容)。要重新启动整个过程,删除secret就足够了,这样证书将保持不变,新的certificateRequest和其他链将被创建
  • 另外,在文档中找到了证书续订的正确方法 - check this out
  • @moonkotte - 很高兴知道。试了一下,它成功了。一定是升级失败之前的一些较旧的订单/挑战。我希望是最好的,这似乎有效。感谢您的帮助!

标签: kubernetes cert-manager ingress-nginx


【解决方案1】:

问题

该问题已通过证书更新解决,无需在挑战入口中手动设置 spec.ingressClassName 即可正常工作(我在旧版本中看到),问题出在其他地方。

还有最后可用的(在撰写本文时)cert-manager v1.5.4challenge ingress 具有“开箱即用”的正确设置:

spec:
  ingressClassName: nginx
---
$ kubectl get ing
NAME                        CLASS    HOSTS            ADDRESS         PORTS     AGE
cm-acme-http-solver-szxfg   nginx    dummy-host       ip_address      80        11s

工作原理(概念)

我将描述此过程的主要步骤,以便在几乎所有情况下都可以直接进行故障排除。我会把letsencypt staging 当作issuer

当请求创建certificate 时,有一个链,issuer 遵循该链来完成(所有资源都有所有者 - 链中的前一个资源):

main ingress resource -> certificate -> certificaterequest -> order -> challenge -> challenge ingress

知道了这一点,如果出现问题,你可以顺着链下去,使用kubectl describe命令找到问题出现的地方。

疑难解答示例

我故意在 .spec.tls.hosts 的入口中添加了一个错误的域并应用了它。下面是链的外观(所有名称都是唯一的!):

查看证书:

$ kubectl get cert
NAME                     READY   SECRET                          AGE
lets-secret-test-2       False   lets-secret-test-2              15m

描述我们感兴趣的certificate(你可以注意到我改变了域名,已经有秘密了):

$ kubectl describe cert lets-secret-test-2
Events:
  Type    Reason     Age   From          Message
  ----    ------     ----  ----          -------
  Normal  Issuing    16m   cert-manager  Existing issued Secret is not up to date for spec: [spec.commonName spec.dnsNames]
  Normal  Reused     16m   cert-manager  Reusing private key stored in existing Secret resource "lets-secret-test-2"
  Normal  Requested  16m   cert-manager  Created new CertificateRequest resource "lets-secret-test-2-pvb25"

这里没什么可疑的,继续前进。

$ kubectl get certificaterequest
NAME                           APPROVED   DENIED   READY   ISSUER                REQUESTOR                                         AGE
lets-secret-test-2-pvb25       True                False   letsencrypt-staging   system:serviceaccount:cert-manager:cert-manager   19m

描述certificaterequest

$ kubectl describe certificaterequest lets-secret-test-2-pvb25
Events:
  Type    Reason           Age   From          Message
  ----    ------           ----  ----          -------
  Normal  cert-manager.io  19m   cert-manager  Certificate request has been approved by cert-manager.io
  Normal  OrderCreated     19m   cert-manager  Created Order resource default/lets-secret-test-2-pvb25-2336849393

再次,一切看起来都很好,没有错误,前进到order

$ kubectl get order
NAME                                  STATE     AGE
lets-secret-test-2-pvb25-2336849393   pending   21m

上面写着pending,更接近:

$ kubectl describe order lets-secret-test-2-pvb25-2336849393

Events:
  Type    Reason   Age   From          Message
  ----    ------   ----  ----          -------
  Normal  Created  21m   cert-manager  Created Challenge resource "lets-secret-test-2-pvb25-2336849393-3788447910" for domain "dummy-domain"

Challenge 可能会有所启发,继续前进:

$ kubectl get challenge
NAME                                             STATE     DOMAIN           AGE
lets-secret-test-2-pvb25-2336849393-3788447910   pending   dummy-domain   23m

描述:

$ kubectl describe challenge lets-secret-test-2-pvb25-2336849393-3788447910

检查status

Status:
  Presented:   true
  Processing:  true
  Reason:      Waiting for HTTP-01 challenge propagation: failed to perform self check GET request 'http://dummy-domain/.well-known/acme-challenge/xxxxyyyyzzzzz': Get "http://dummy-domain/.well-known/acme-challenge/xxxxyyyyzzzzz": dial tcp: lookup dummy-domain on xx.yy.zz.ww:53: no such host
  State:       pending

现在很明显domain有问题,值得检查一下:

发现并修正了“错误”:

$ kubectl apply -f ingress.yaml
ingress.networking.k8s.io/ingress configured

证书是ready!

$ kubectl get cert
NAME                     READY   SECRET                          AGE
lets-secret-test-2       True    lets-secret-test-2              26m

使用 cert-manager 更新证书的正确方法

可以通过删除相应的秘密来更新证书,但是documentation says it's not recommended

删除与证书资源关联的 Secret 资源是 不推荐的解决方案用于手动轮换私钥。这 推荐的手动轮换私钥的方法是触发 使用以下命令重新颁发证书资源 (需要 kubectl cert-manager 插件):

kubectl cert-manager renew cert-1

Kubectl cert-manager命令安装过程描述here以及其他命令和示例。

有用的链接:

【讨论】:

    猜你喜欢
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 2020-10-25
    • 2019-07-27
    • 2020-03-12
    相关资源
    最近更新 更多