As HTTPS becomes increasingly popular, most websites have begun to upgrade from HTTP to HTTPS. To use HTTPS, you need to apply for a certificate from an authority and pay a certain cost. The more certificates you apply for, the higher the cost will be. cert-manager is a powerful certificate management tool for Kubernetes. You can use cert-manager based on the ACME protocol and Let's Encrypt to issue free certificates and have certificates automatically renewed. In this way, you can use certificates permanently for free.
After being deployed to a Kubernetes cluster, cert-manager queries custom CRD resources that it supports. You can create CRD resources to instruct cert-manager to issue certificates and automatically renew certificates, as shown in the figure below:
Issuer/ClusterIssuer: indicates the method used by cert-manager to issue certificates. This document mainly describes the ACME method for issuing free certificates.
Issuer differs from ClusterIssuer in that Issuer can only be used to issue certificates under your own namespace, whereas ClusterIssuer can be used to issue certificates under any namespace.
Certificate: is used to pass the domain name certificate information, the configuration required for issuing a certificate, and Issuer/ClusterIssuer references to cert-manager.
Let’s Encrypt uses the ACME protocol to verify the ownership of a domain name. After successful verification, a free certificate is automatically issued. The free certificate is valid for only 90 days, so verification needs to be performed again to renew the certificate before the certificate expires. cert-manager supports automatic renewal of certificates, which allows you to use certificates permanently for free. You can verify the ownership of a certificate by using two methods: HTTP-01 and DNS-01. For more information on the verification process, see How It Works.
HTTP-01 verification adds a temporary location for the HTTP service to which a domain name is directed. This method is only applicable to issuing a certificate for services that use open ingress traffic and does not support wildcard certificates.
For example, Let’s Encrypt sends an HTTP request to
YOUR_DOMAIN indicates the domain name to be verified, and
TOKEN indicates a file placed by the ACME client. In this case, the ACME client is cert-manager. You can modify or create ingress rules to add temporary verification paths and direct them to the service that provides
TOKEN. Let’s Encrypt will then verify whether
TOKEN meets the expectation. If the verification succeeds, a certificate is issued.
DNS-01 verification uses the API Key provided by DNS providers to obtain users’ DNS control permissions. This method does not require the use of an ingress and supports wildcard certificates.
After Let’s Encrypt provides a token to the ACME client, the ACME client
\(cert-manager\) will create a TXT record derived from the token and the account key, and then place the record in
_acme-challenge.<YOUR_DOMAIN>. Let’s Encrypt will then query the record in the DNS system. Once a matching item is found, a certificate is issued.
The HTTP-01 methods features simple configuration and extensive applicability. Different DNS providers can use the same configuration method. The disadvantages of this method are that it relies on ingress resources, is applicable only to services that support open ingress traffic, and does not support wildcard certificates.
The advantages of DNS-01 are that it does not rely on ingress resources and supports wildcard domain names. Its disadvantages are that different DNS providers have different configuration methods, and cert-manager Issuer does not support too many different DNS providers. However, you can deploy the cert-manager-enabled webhook service to extend Issuer in order to support more DNS providers, such as DNSPod and Alibaba DNS. For more information on supported providers, see the webhook list.
This document uses the recommended
DNS-01 method, which offers comprehensive features with few restrictions.
Usually, you can use YAML to install cert-manager in your cluster with one click. For more information, see this document on the official website: Installing with regular manifests.
The official image used by cert-manager can be pulled from
quay.io. Alternatively, you can run the following command to use the image synchronized to the mainland China CCR for one-click installation:
This method requires that the cluster version is 1.16 or later.
kubectl apply --validate=false -f https://raw.githubusercontent.com/TencentCloudContainerTeam/manifest/master/cert-manager/cert-manager.yaml
Log in to a DNS provider backend system, configure the DNS A record of the domain name, and direct it to the opened IP address of the real server that needs the certificate. To do this, see the figure below, where Cloudflare is used as an example.
HTTP-01 validation can be performed by using Ingress. Cert-manager will automatically modify the Ingress or add an Ingress to expose the temporary HTTP path needed for validation. When HTTP-01 validation is configured for Issuer, if the
name of an Ingress is specified, the specified Ingress will be modified to expose the HTTP path needed for validation. If
class is specified, an Ingress will be added automatically. You can refer to the following Example.
Each ingress provided by TKE corresponds to a CLB. If you use an existing ingress provided by TKE to open services while using the HTTP-01 verification method, you can only adopt the automatic ingress modification mode, but not the automatic ingress addition mode. For automatically added ingresses, other CLBs will be automatically created, causing the opened IP address inconsistent with the ingress of the real server. In this case, Let's Encrypt fails to find the temporary path needed for verification in the service ingress, which results in verification failure and the failure to issue a certificate. If you use a user-created ingress, for example, by deploying Nginx Ingress on TKE, and ingresses in the same ingress class share the same CLB, the automatic ingress addition mode is supported.
If you use an ingress provided by TKE to open a service, you cannot use cert-manager to issue and manage free certificates. This is because certificates are referenced in Certificate Management and are not managed in Kubernetes.
If you deploy Nginx Ingress on TKE and the ingress of the real server is
prod/web, you can create an Issuer by referring to the following sample code:
apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: letsencrypt-http01 namespace: prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-http01-account-key solvers: - http01: ingress: name: web # Specifies the name of the ingress for automatic modification.
When you use an Issuer to issue a certificate, cert-manager will automatically create an ingress and automatically modify
prod/web of the ingress to open the temporary path needed for verification. See the following sample code for automatic ingress addition:
apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: letsencrypt-http01 namespace: prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-http01-account-key solvers: - http01: ingress: class: nginx # Specifies the ingress class of the automatically created ingress.
After successfully creating an Issuer, refer to the following sample code to create a certificate and reference the Issuer to issue the certificate:
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: test-mydomain-com namespace: prod spec: dnsNames: - test.mydomain.com # Indicates the domain name for issuing a certificate. issuerRef: kind: Issuer name: letsencrypt-http01 # References Issuer and indicates the HTTP-01 method is used for verification. secretName: test-mydomain-com-tls # The issued certificate will be saved in this Secret.
If you choose to use the DNS-01 verification method, you must select a DNS provider. cert-manager provides built-in support for DNS providers. For the detailed list and usage, see Supported DNS01 providers. If you need to use a DNS provider other than those on the list, refer to the following two schemes:
On the backend system of the DNS provider, configure a custom nameserver and direct it to the address of a nameserver that can manage other DNS providers’ domain names, such as Cloudflare. You can log in to the backend of Cloudflare to view the specific address, as shown in the figure below:
You can configure a custom nameserver for namecheap, as shown in the figure below:
Finally, when configuring the Issuer and specifying the DNS-01 verification method, add the Cloudflare information.
You can use the cert-manager webhook to extend the list of DNS providers supported in cert-manager DNS-01 verification. This scheme has been implemented for many third parties, such as DNSPod and Alibaba DNS, that are widely used in mainland China. For more information on the webhook list and its usage, see Webhook.
Complete the following steps to issue a certificate for Cloudflare:
- If you need to create a ClusterIssuer, create the Secret in the namespace to which cert-manager belongs.
- If you need to create an Issuer, create the Secret in the namespace to which the Issuer belongs.
apiVersion: v1 kind: Secret metadata: name: cloudflare-api-token-secret namespace: cert-manager type: Opaque stringData: api-token: <API Token> # Paste the token here without Base64 encryption.
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-dns01 spec: acme: privateKeySecretRef: name: letsencrypt-dns01 server: https://acme-v02.api.letsencrypt.org/directory solvers: - dns01: cloudflare: email: firstname.lastname@example.org # Replace it with your Cloudflare email account. API token authentication is optional, but API key authentication is required. apiTokenSecretRef: key: api-token name: cloudflare-api-token-secret # References the Secret that stores the Cloudflare authentication information.
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: test-mydomain-com namespace: default spec: dnsNames: - test.mydomain.com # Indicates the domain name for issuing a certificate. issuerRef: kind: ClusterIssuer name: letsencrypt-dns01 # References ClusterIssuer and indicates that the DNS-01 method is used for verification. secretName: test-mydomain-com-tls # The issued certificate will be stored in this Secret.
After creating a certificate, you can run the kubectl command to check whether the certificate has been issued successfully.
$ kubectl get certificate -n prod NAME READY SECRET AGE test-mydomain-com True test-mydomain-com-tls 1m
False: indicates that the certificate failed to be issued. You can run the
describecommand to check the event and analyze the failure cause.
$ kubectl describe certificate test-mydomain-com -n prod
True: indicates that the certificate was issued successfully. In this case, the certificate will be stored in the specified Secret, for example,
default/test-mydomain-com-tls. You can run kubectl to view the certificate, where
tls.crtindicates the certificate, and
tls.keyindicates the key.
$ kubectl get secret test-mydomain-com-tls -n default ... data: tls.crt: <cert> tls.key: <private key>
You can mount the certificate to the app that needs it or directly reference the Secret in an ingress that you created. The following shows a sample YAML file:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: test-ingress annotations: kubernetes.io/Ingress.class: nginx spec: rules: - host: test.mydomain.com http: paths: - path: /web backend: serviceName: web servicePort: 80 tls: hosts: - test.mydomain.com secretName: test-mydomain-com-tls