kubernetes - ingress-nginx、cert-manager 和 ingressClassName
问题描述
我最近升级ingress-nginx
到版本 1.0.3。
结果,我kubernetes.io/ingress.class
从我的入口中删除了注释,并.spec.ingressClassName
改为放置。
我正在跑步cert-manager-v1.4.0
。
今天早上我收到一封电子邮件,说我的 Let's Encrypt 证书将在 10 天后过期。我试图弄清楚它有什么问题 - 不能肯定这完全是由于 ingress-nginx 升级造成的。
我删除了CertificateRequest
,看看它是否会自行修复。我得到了一个新Ingress
的挑战,但是:
挑战入口的
kubernetes.io/ingress.class
注释设置正确,即使我的入口有.spec.ingressClassName
- 不知道如何或为什么,但似乎应该没问题。但是,入口控制器没有接收到挑战入口,它说:
ingress class annotation is not equal to the expected by Ingress Controller
我想它只需要.spec.ingressClassName
即使我认为注释也应该工作。
所以我手动设置.spec.ingressClassName
了挑战入口。入口控制器立即看到了它,其余的过程运行顺利,我得到了一个新的证书 - 耶。
在我看来,这种情况会再次发生,所以我需要知道如何:
说服使用而不是
cert-manager
创建挑战入口。也许这在 1.5 或 1.6 中已修复?.spec.ingressClassName
kubernetes.io/ingress.class
说服
ingress-nginx
尊重kubernetes.io/ingress.class
挑战入口的注释。我不知道为什么这不起作用。
解决方案
问题
该问题已通过证书更新解决,无需手动设置spec.ingressClassName
挑战入口即可正常工作(我在旧版本中看到),问题在其他地方。
同样在最后可用(在写作时)cert-manager v1.5.4
挑战入口具有“开箱即用”的正确设置:
spec:
ingressClassName: nginx
---
$ kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
cm-acme-http-solver-szxfg nginx dummy-host ip_address 80 11s
它是如何工作的(概念)
我将描述此过程如何工作的主要步骤,以便在几乎所有情况下都可以直接进行故障排除。我会把 aletsencypt 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 更新证书的正确方法
可以通过删除相应的秘密来更新证书,但是文档说不建议这样做:
删除与证书资源关联的 Secret 资源 不是手动轮换私钥的推荐解决方案。手动轮换私钥的推荐方法是使用以下命令触发证书资源的重新颁发(需要 kubectl cert-manager 插件):
kubectl cert-manager renew cert-1
Kubectl cert-manager
此处描述了命令安装过程以及其他命令和示例。
有用的链接:
推荐阅读
- json - 在 oracle 中解析 json 数组时获取重复项
- javascript - 如何检测每个视频标签以及它是否正在播放?
- javascript - 无法在 HTML 页面上显示 getJson 的结果
- python - 如何在 excel 文档中搜索特定单词,并使用搜索结果构建新列
- python - 无法使用`loc`向`pandas.DataFrame`子类添加行
- .net - 访问 IQueryable 时如何防止实体框架请求两次
- php - Laravel 5.8 - 尝试通过从数据库中提取信息来构建模型
- javascript - 我创建了我的自定义每个函数(数组函数),但这没有按预期工作,
- python-3.x - RuntimeError:matplotlib 不支持生成器作为输入
- python - 如何在 excepts 子句中使用包中的自定义异常?