kubernetes - ingress-nginx、cert-manager 和 ingressClassName

标签 kubernetes cert-manager ingress-nginx

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

因此,我从入口中删除了 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. 但是,入口 Controller 并未接收到挑战入口,它表示:

入口类注释不等于入口 Controller 的预期

我猜它只需要 .spec.ingressClassName 即使我认为注释也应该起作用。

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

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

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

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

最佳答案

问题

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

此外,最后一个可用的(在撰写本文时)cert-manager v1.5.4 挑战 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 作为发行人

当请求创建证书时,会出现一条链,颁发者将遵循该链来完成(所有资源都有所有者 - 链中的先前资源):

主要入口资源 -> 证书 -> 证书请求 -> 订单 -> 挑战 -> 挑战入口

知道了这一点,如果出现问题,您可以沿着链向下查找并使用 kubectl describe 命令查找问题出现的位置。

故障排除示例

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

查看证书:

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

描述我们感兴趣的证书(您可以注意到我更改了域,已经有 secret ):

$ 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

描述证书请求:

$ 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

再次,一切看起来都很好,没有错误,继续进行订单:

$ 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"

挑战可能会揭示一些前进的线索:

$ 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:
  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

现在很明显出了问题,值得检查一下:

发现并修复了“错误”:

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

证书已准备就绪!

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

使用 cert-manager 续订证书的正确方法

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

Deleting the Secret resource associated with a Certificate resource is not a recommended solution for manually rotating the private key. The recommended way to manually rotate the private key is to trigger the reissuance of the Certificate resource with the following command (requires the kubectl cert-manager plugin):

kubectl cert-manager renew cert-1

Kubectl cert-manager命令安装流程说明here以及其他命令和示例。

有用的链接:

关于kubernetes - ingress-nginx、cert-manager 和 ingressClassName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69565736/

相关文章:

kubernetes - 有没有办法在 Kubernetes 中处理 SIP、RTP、DIAMETER、M3UA 流量?

azure - Kubernetes 证书管理器在颁发者更改后不更新证书

ubuntu - 无法在 Ubuntu 18.04 上使用 ingress-nginx 进行路由

google-kubernetes-engine - GCP - 具有网络端点组 NEG 的区域 GKE 集群(具有 HTTP LoadBalancer 和 Cloud Armor)

python - 如何使用 Kubernetes python 客户端库部署 Knative 服务

kubernetes - 为什么我的 Tarantool Cartridge 有时会从路由器实例检索数据?

docker - 无法在kubernetes v1中生成服务帐户 token

ssl - Rancher - 对 ingress.local 有效

kubernetes - Cert-Manager dns01挑战订单待处理