Cert Manager Application Process for SSL Certificate and Related Concepts - II
This article was last updated on: July 24, 2024 am
Chinese and English comparison table
English | English - K8S CRD | Chinese | Notes |
---|---|---|---|
certificates | Certificate |
Certificate | certificates.cert-manager.io/v1 |
certificate issuers | Issuer |
Certificate issuer | issuers.cert-manager.io |
ClusterIssuer |
Cluster Certificate Issuer | clusterissuers.cert-manager.io |
|
certificate request | CertificateRequest |
Certificate Request | certificaterequests.cert-manager.io |
order | Order |
(Certificate) Order | orders.acme.cert-manager.io |
challenge | Challenge |
(Certificate) Challenge | challenges.acme.cert-manager.io |
SelfSigned | Self-signed | A type of cert-manager Issuer | |
CA | Certificate Authority | Short for Certificate Authority; A type of cert-manager Issuer |
|
Vault | Vault | A type of cert-manager Issuer, the Hashicorp Vault | |
Venafi | Venafi Online certificate processing services, currently not used much | ||
External | External | A type of cert-manager Issuer | |
ACME | Automated Certificate Management Environment | Abbreviation for Automated Certificate Management Environment; cert-manager Issuer, including HTTP01 and DNS01 |
The book continues from the previous one, let’s take a look at cert-manager’s certificate application and renewal process.
Request an SSL certificate process
This image shows the name of the ACME/Let’s Encrypt Issuer usedcert-1
The lifecycle of the certificate:
HTTP01 mode
cert-manager can be used from use ACME The CA of the protocol obtains the certificate. The ACME protocol supports various challenge mechanisms for proving ownership of a domain name in order to issue a valid certificate for that domain name.
One such challenge mechanism is the HTTP01 challenge. With the HTTP01 challenge, you can prove ownership of a particular domain by ensuring that that the domain exists in that domain. If you are able to publish a given file under a given path, you can assume that you control the domain.
First, configure HTTP01 Issuer, See above
https://acme-v02.api.letsencrypt.org/directory
This is the production environment for Let’s Encrypt. Corresponding,Staging environment The URL is:https://acme-staging-v02.api.letsencrypt.org/directory
The staging environment does not issue trusted certificates, but it is used to ensure that the validation process works before moving to production. Let’s Encrypt’s production environment imposes stricter restrictions Rate limiting, so to reduce your chances of hitting these limits, it is highly recommended to start with a staging environment.
The first phase of the ACME protocol is the registration of the customer with the ACME server. This stage involves generating an asymmetric key pair and then associating it with the email address specified in the sender (🐾 I didn’t fill in the email address here). Make sure to change this email address to a valid address of your own. It is typically used to send expiration notifications when your certificate is about to be renewed. The generated private key is stored in a secret called ‘letsencrypt-staging’. Examples are as follows:
1 |
|
We must provide one or more Solvers to handle the ACME challenge. In this case, we want to use HTTP validation, so we specify onehttp01
Issuer - rancher
。 We can choose to map different domains to use different solver configurations.
Once we have created the aforementioned issuer, we can use it to obtain certificates.
The certificate resource describes the certificates we need and the possible methods we can use to obtain them. If the certificate is successfully obtained, the resulting key pair is stored in a named namespace in the same namespace as the certificatetls-rancher-ingress
of Secret.
The dnsname of the certificate israncher.e-whisper.com
.
📝Notes
If the above yaml is deleted
dnsNames
, to be replaced withcommonName: e-whisper.com
,Subject Alternative Name(SAN) will bee-whisper.com
andwww.e-whisper.com
。
In our certificate, we refer to the aboverancher
Issuer。 The issuer must be in the same namespace as the certificate. If you want to quoteClusterIssuer
, which is a cluster-wide Issuer that you must addkind:ClusterIssuer
arrive issuerRef
section.
acme
The section defines the configuration of the ACME challenge. Here we define the configuration of the HTTP01 challenge, which will be used to verify domain ownership. For verification http01
For ownership of each domain mentioned in the section, cert-manager will create a pod, SVC, and Ingress, exposing an HTTP endpoint that satisfies the HTTP01 challenge.
http01
sectioningress
andingressClass
Fields can be used to control how cert-manager interacts with Ingress resources.
- If specified
ingress
field, then in the same NameSpace as the certificate, an Ingress resource with the same name must already exist, it will be modified just to add the appropriate rules to solve the challenge. This field is useful for ingress controllers and other controllers that assign a public IP address to each ingress resource. Without human intervention, creating a new Ingress resource will cause any challenge to fail. - If specified
ingressClass
field, which creates a new entry resource with a randomly generated name to solve the challenge. This new resource will have a comment whose key iskubernetes.io/ingress.class
value set toingressClass
of field. This applies to NGINX ingress controllers, etc. - If neither is specified, new Ingress resources will be created with randomly generated names, but they will not have ingressClass annotations set.
- If both are specified, then
ingress
Fields will be prioritized.
Once domain ownership is verified, any affected cert-manager resources will be cleaned up or deleted.
🐾 note:
It is your responsibility to point each domain name to the correct IP address of your ingress controller. (Even if you configure DNS records, you still have to do it yourself.) )
After creating the aforementioned certificate, we can use itkubectl describe
Check if it has been successfully obtained.
1 |
|
You can also use itkubectl get secret tls-rancher-ingress -o yaml
to check if the release was successful. You should see a base64-encoded TLS key pair.
Once we have obtained the certificate, cert-manager will periodically check its validity and try to renew it when it is close to expiration. When on the certificate Not After
When the field is less than the current time plus 30 days, cert-manager considers the certificate close to expiration.
Certificate renewal
My certificate has been applied for before, and the process log records updated a few days ago are as follows (you can refer to the aboveCertificate lifecycleLook):
I0507 13:39:31.141402 1 trigger_controller.go:181] cert-manager/certificates-trigger "msg"="Certificate must be re-issued" "key"="cattle-system/tls-rancher-ingress" "message"="Renewing certificate as renewal was scheduled at 2022-05-07 13:39:31 +0000 UTC" "reason"="Renewing"
I0507 13:39:31.143437 1 conditions.go:201] Setting lastTransitionTime for Certificate "tls-rancher-ingress" condition "Issuing" to 2022-05-07 13:39:31.142484989 +0000 UTC m=+186628.212145824
I0507 13:39:31.807902 1 controller.go:161] cert-manager/certificates-key-manager "msg"="re-queuing item due to optimistic locking on resource" "key"="cattle-system/tls-rancher-ingress" "error"="Operation cannot be fulfilled on certificates.cert-manager.io \"tls-rancher-ingress\": the object has been modified; please apply your changes to the latest version and try again"
I0507 13:39:31.928746 1 conditions.go:261] Setting lastTransitionTime for CertificateRequest "tls-rancher-ingress-5j9mm" condition "Approved" to 2022-05-07 13:39:31.927475704 +0000 UTC m=+186628.997136533
I0507 13:39:32.181390 1 conditions.go:261] Setting lastTransitionTime for CertificateRequest "tls-rancher-ingress-5j9mm" condition "Ready" to 2022-05-07 13:39:32.181379458 +0000 UTC m=+186629.251040270
I0507 13:39:32.263457 1 controller.go:161] cert-manager/certificaterequests-issuer-acme "msg"="re-queuing item due to optimistic locking on resource" "key"="cattle-system/tls-rancher-ingress-5j9mm" "error"="Operation cannot be fulfilled on certificaterequests.cert-manager.io \"tls-rancher-ingress-5j9mm\": the object has been modified; please apply your changes to the latest version and try again"
I0507 13:39:41.306332 1 pod.go:71] cert-manager/challenges/http01/ensurePod "msg"="creating HTTP01 challenge solver pod" "dnsName"="rancher.e-whisper.com" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
I0507 13:39:41.621639 1 pod.go:59] cert-manager/challenges/http01/selfCheck/http01/ensurePod "msg"="found one existing HTTP01 solver pod" "dnsName"="rancher.e-whisper.com" "related_resource_kind"="Pod" "related_resource_name"="cm-acme-http-solver-pglxk" "related_resource_namespace"="cattle-system" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
I0507 13:39:41.621784 1 service.go:43] cert-manager/challenges/http01/selfCheck/http01/ensureService "msg"="found one existing HTTP01 solver Service for challenge resource" "dnsName"="rancher.e-whisper.com" "related_resource_kind"="Service" "related_resource_name"="cm-acme-http-solver-xsqkb" "related_resource_namespace"="cattle-system" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
E0507 13:39:41.837584 1 sync.go:186] cert-manager/challenges "msg"="propagation check failed" "error"="wrong status code '404', expected '200'" "dnsName"="rancher.e-whisper.com" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
I0507 13:39:42.027681 1 pod.go:59] cert-manager/challenges/http01/selfCheck/http01/ensurePod "msg"="found one existing HTTP01 solver pod" "dnsName"="rancher.e-whisper.com" "related_resource_kind"="Pod" "related_resource_name"="cm-acme-http-solver-pglxk" "related_resource_namespace"="cattle-system" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
I0507 13:39:42.027757 1 service.go:43] cert-manager/challenges/http01/selfCheck/http01/ensureService "msg"="found one existing HTTP01 solver Service for challenge resource" "dnsName"="rancher.e-whisper.com" "related_resource_kind"="Service" "related_resource_name"="cm-acme-http-solver-xsqkb" "related_resource_namespace"="cattle-system" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
I0507 13:39:42.027811 1 ingress.go:110] cert-manager/challenges/http01/selfCheck/http01/ensureIngress "msg"="multiple challenge solver ingresses found for challenge. cleaning up all existing ingresses." "dnsName"="rancher.e-whisper.com" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
E0507 13:39:42.076190 1 controller.go:102] ingress 'cattle-system/cm-acme-http-solver-knwm8' in work queue no longer exists
E0507 13:39:42.100492 1 controller.go:102] ingress 'cattle-system/cm-acme-http-solver-59gvf' in work queue no longer exists
E0507 13:39:42.101020 1 sync.go:186] cert-manager/challenges "msg"="propagation check failed" "error"="multiple existing challenge solver ingresses found and cleaned up. retrying challenge sync" "dnsName"="rancher.e-whisper.com" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
...
E0507 13:40:22.187779 1 sync.go:386] cert-manager/challenges/acceptChallenge "msg"="error waiting for authorization" "error"="context deadline exceeded" "dnsName"="rancher.e-whisper.com" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
E0507 13:40:22.188198 1 controller.go:163] cert-manager/challenges "msg"="re-queuing item due to error processing" "error"="context deadline exceeded" "key"="cattle-system/tls-rancher-ingress-5j9mm-2528720963-983401508"
I0507 13:40:27.188948 1 pod.go:59] cert-manager/challenges/http01/selfCheck/http01/ensurePod "msg"="found one existing HTTP01 solver pod" "dnsName"="rancher.e-whisper.com" "related_resource_kind"="Pod" "related_resource_name"="cm-acme-http-solver-pglxk" "related_resource_namespace"="cattle-system" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
I0507 13:40:27.190011 1 service.go:43] cert-manager/challenges/http01/selfCheck/http01/ensureService "msg"="found one existing HTTP01 solver Service for challenge resource" "dnsName"="rancher.e-whisper.com" "related_resource_kind"="Service" "related_resource_name"="cm-acme-http-solver-xsqkb" "related_resource_namespace"="cattle-system" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
I0507 13:40:27.190749 1 ingress.go:98] cert-manager/challenges/http01/selfCheck/http01/ensureIngress "msg"="found one existing HTTP01 solver ingress" "dnsName"="rancher.e-whisper.com" "related_resource_kind"="Ingress" "related_resource_name"="cm-acme-http-solver-cmp2c" "related_resource_namespace"="cattle-system" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508" "resource_namespace"="cattle-system" "resource_version"="v1" "type"="HTTP-01"
E0507 13:40:38.478817 1 controller.go:102] ingress 'cattle-system/cm-acme-http-solver-cmp2c' in work queue no longer exists
I0507 13:40:39.806118 1 acme.go:209] cert-manager/certificaterequests-issuer-acme/sign "msg"="certificate issued" "related_resource_kind"="Order" "related_resource_name"="tls-rancher-ingress-5j9mm-2528720963" "related_resource_namespace"="cattle-system" "related_resource_version"="v1" "resource_kind"="CertificateRequest" "resource_name"="tls-rancher-ingress-5j9mm" "resource_namespace"="cattle-system" "resource_version"="v1"
I0507 13:40:39.809106 1 conditions.go:250] Found status change for CertificateRequest "tls-rancher-ingress-5j9mm" condition "Ready": "False" -> "True"; setting lastTransitionTime to 2022-05-07 13:40:39.809091738 +0000 UTC m=+186696.878752561
I0507 13:40:40.068059 1 controller.go:161] cert-manager/certificates-issuing "msg"="re-queuing item due to optimistic locking on resource" "key"="cattle-system/tls-rancher-ingress" "error"="Operation cannot be fulfilled on certificates.cert-manager.io \"tls-rancher-ingress\": the object has been modified; please apply your changes to the latest version and try again"
I0507 13:40:40.168307 1 controller.go:161] cert-manager/certificates-key-manager "msg"="re-queuing item due to optimistic locking on resource" "key"="cattle-system/tls-rancher-ingress" "error"="Operation cannot be fulfilled on certificates.cert-manager.io \"tls-rancher-ingress\": the object has been modified; please apply your changes to the latest version and try again"
E0507 13:40:41.298717 1 sync.go:70] cert-manager/orders "msg"="failed to update status" "error"=null "resource_kind"="Order" "resource_name"="tls-rancher-ingress-5j9mm-2528720963" "resource_namespace"="cattle-system" "resource_version"="v1"
I0507 13:40:41.299059 1 controller.go:161] cert-manager/orders "msg"="re-queuing item due to optimistic locking on resource" "key"="cattle-system/tls-rancher-ingress-5j9mm-2528720963" "error"="Operation cannot be fulfilled on orders.acme.cert-manager.io \"tls-rancher-ingress-5j9mm-2528720963\": the object has been modified; please apply your changes to the latest version and try again"
E0507 13:40:41.331531 1 controller.go:211] cert-manager/challenges "msg"="challenge in work queue no longer exists" "error"="challenge.acme.cert-manager.io \"tls-rancher-ingress-5j9mm-2528720963-983401508\" not found"
-
cert-manager/certificates-trigger
Trigger certificate renew(Certificate
There is one in itrenewalTime
field records the time) -
tls-rancher-ingress
The status of the certificate changes to"Issuing"
-
A new one is created
CertificateRequest
-tls-rancher-ingress-5j9mm
, the status changes to"Approved"
, The specific content is as follows:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53apiVersion: cert-manager.io/v1
kind: CertificateRequest
metadata:
annotations:
cert-manager.io/certificate-name: tls-rancher-ingress
cert-manager.io/certificate-revision: '2'
cert-manager.io/private-key-secret-name: tls-rancher-ingress-nttqs
creationTimestamp: '2022-05-07T13:39:31Z'
generateName: tls-rancher-ingress-
generation: 1
name: tls-rancher-ingress-5j9mm
namespace: cattle-system
ownerReferences:
- apiVersion: cert-manager.io/v1
blockOwnerDeletion: true
controller: true
kind: Certificate
name: tls-rancher-ingress
resourceVersion: '20868343'
status:
certificate: >-
...
conditions:
- lastTransitionTime: '2022-05-07T13:39:31Z'
message: Certificate request has been approved by cert-manager.io
reason: cert-manager.io
status: 'True'
type: Approved
- lastTransitionTime: '2022-05-07T13:40:39Z'
message: Certificate fetched from issuer successfully
reason: Issued
status: 'True'
type: Ready
spec:
extra:
authentication.kubernetes.io/pod-name:
- cert-manager-6d6bb4f487-525q9
authentication.kubernetes.io/pod-uid:
- 857565c8-b05c-4114-8e94-14960476f90e
groups:
- system:serviceaccounts
- system:serviceaccounts:cert-manager
- system:authenticated
issuerRef:
group: cert-manager.io
kind: Issuer
name: rancher
request: >-
<-----BEGIN CERTIFICATE REQUEST-----... 的 base64 编码>
usages:
- digital signature
- key encipherment
username: system:serviceaccount:cert-manager:cert-manager -
CertificateRequest
-tls-rancher-ingress-5j9mm
, the status changes to"Ready"
-
Create an HTTP01 challenge solver pod -
"resource_kind"="Challenge" "resource_name"="tls-rancher-ingress-5j9mm-2528720963-983401508"
-
The first few challenges failed, 404:
"msg"="propagation check failed" "error"="wrong status code '404', expected '200'"
-
After many times, it finally succeeded:
"msg"="certificate issued" "related_resource_kind"="Order"
(After starting renew, the creation is complete.)CertificateRequest
Start creatingOrder
)Found status change for CertificateRequest "tls-rancher-ingress-5j9mm" condition "Ready": "False" -> "True"; setting lastTransitionTime to 2022-05-07 13:40:39.809091738 +0000 UTC m=+186696.878752561
After success,Challenge
deleted,Order
The status changes to valid
As follows:
1 |
|
ultimately Certificate
The status is also updated, and the new certificate is updated into the corresponding secret. As follows:
1 |
|
DNS01 mode
cert-manager can be used from use ACME The CA of the protocol obtains the certificate. The ACME protocol supports various challenge mechanisms for proving ownership of a domain name in order to issue a valid certificate for that domain name.
One such challenge mechanism is DNS01. With the DNS01 challenge, you can prove ownership of a domain name by proving that you control its DNS records. This is achieved by creating a TXT record with specific content that proves that you have control over the DNS records for that domain.
Previous Issuer Defines some of the necessary information to enable DNS validation. Also specify Let’s Encrypt’s production environment:https://acme-v02.api.letsencrypt.org/directory
dns01
The field contains a list of DNS01 providers that can be used to resolve DNS challenges. Here I only define a provider for the webhook implementation - dnspod.
As long as we have created the aforementioned issuer, we can use it to obtain a certificate:
1 |
|
The certificate CRD describes the certificates we need and the possible methods we can use to obtain them. You can get a certificate for a wildcard domain just like any other domain name. Be sure to wrap wildcard domain names with asterisks in your YAML resources to avoid formatting issues. Here I specify both on the same certificatee-whisper.com
and*.e-whisper.com
, then the verification time will be slightly longer, because each domain name must be verified one by one.
🤔 Thinking:
My wildcard certificate, which started to be updated on 2022.4.30, and then was not updated successfully until 2022.5.8, I don’t know if it’s because of this.
If the certificate is successfully obtained, the resulting key pair is stored in a named namespace in the same namespace as the certificateewhisper-crt-secret
of Secret.
The common name of the certificate is *.e-whisper.com
。
In our certificate, we refer to the abovednspod
ClusterIssuer, in which case the Issuer can not be in the same namespace as the certificate.
acme
The section defines the configuration of our ACME challenge. Here we define the configuration of the DNS challenge, which will be used to verify domain ownership. aboutdns01
For each domain name mentioned in the section, cert-manager will be created with a certificate that is referenced to the provider of the issue_acme-challenge
TXT record. This record will be validated by the ACME server in order to issue the certificate. Once domain ownership is verified, any records affected by cert-manager will be sanitized.
DNS server I use DNSPod, here to create TXT record as follows:
2022-05-08 19:05:39: (<my-public-ip>) 删除记录 TXT 记录 默认 线路 _acme-challenge 值 mfaEFIBPUFzh1ub7Ek05v-bN-fwsdfwdfwdfwedw (1117684179) Uin:<my-uin> Real Client IP:<my-public-ip> API FROM:YUNAPI
2022-05-08 19:04:27: (<my-public-ip>) 添加 TXT 记录 默认 线路 _acme-challenge 值 mfaEFIBPUFzh1ub7Ek05v-bN-fwsdfwdfwdfwedw (1117684179) Uin:<my-uin> Real Client IP:<my-public-ip> API FROM:YUNAPI
2022-05-08 19:04:26: (<my-public-ip>) 删除记录 TXT 记录 默认 线路 _acme-challenge 值 cVxv2s9P_UvThEB2DLcZxfwdfwdfwdwds8Ogv_k (1117683586) Uin:<my-uin> Real Client IP:<my-public-ip> API FROM:YUNAPI
2022-05-08 19:03:12: (<my-public-ip>) 添加 TXT 记录 默认 线路 _acme-challenge 值 cVxv2s9P_UvThEB2DLcZxfwdfwdfwdwds8Ogv_k (1117683586) Uin:<my-uin> Real Client IP:<my-public-ip> API FROM:YUNAPI
2022-05-08 18:04:21: (<my-public-ip>) 删除记录 TXT 记录 默认 线路 _acme-challenge 值 QYLKuSmlK6aWmD64hhExOwdfwdfwdfwdcwdk5bfRCLAI (1117656075) Uin:<my-uin> Real Client IP:<my-public-ip> API FROM:YUNAPI
2022-05-08 18:03:07: (<my-public-ip>) 添加 TXT 记录 默认 线路 _acme-challenge 值 QYLKuSmlK6aWmD64hhExOwdfwdfwdfwdcwdk5bfRCLAI (1117656075) Uin:<my-uin> Real Client IP:<my-public-ip> API FROM:YUNAPI
Other aspects are similar to HTTP01, and I won’t go into too much detail here.
Here, the cert-manager plugin developed by <imroc.cc> - cert-manager-webhook-dnspod is used.
Refer to it This article configures the DNSPOD cert-manager webhook
Combined with the above process, let’s take a look The concept of cert-manager