cert-manager
is an extension for Kubernetes that automates the issuance and renewal of certificates. It allows you to obtain certificates from Let's Encrypt and other certificate authorities (CAs) or use internal root certificates. cert-manager
simplifies certificate management by automatically renewing them before expiration and ensuring secure encryption for services within the cluster. It integrates with Ingress controllers and supports various domain verification methods, making it a convenient tool for automating certificate management in Kubernetes.
To install cert-manager:
To verify the installation, run the following command:
kubectl get pods -n cert-manager
All pods in the cert-manager
namespace should have the status Running
.
To enable cert-manager to issue certificates, you need to create a ClusterIssuer
object, which manages certificates at the cluster level.
Example manifest:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: email@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
Here:
email
– Your email address, required for certificate issuance. Let's Encrypt will send notifications to this address.server
– The URL of Let's Encrypt or another certificate authority.privateKeySecretRef
– The secret that stores the private key.solvers.http01.ingress.class
– The method for verifying domain ownership via HTTP, using the Nginx Ingress controller in this case.If you're using a different Ingress controller, replace nginx
with the appropriate value. For example, for Traefik:
solvers:
- http01:
ingress:
class: traefik
Let's consider an example where cert-manager
is used with resources from our Nginx Ingress setup.
If you followed our guide, you have already set up:
Your services are accessible via:
http://ingress1.example.com/service1
http://ingress1.example.com/service2
http://ingress2.example.com/
Now we need to define a ClusterIssuer
in a file named cluster-issuer.yaml
:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: email@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
Apply the manifest:
kubectl apply -f cluster-issuer.yaml
Next, you need to update the Ingress
resource. Modify the existing Ingress manifest by adding an annotation for cert-manager
and a tls
section.
Updated ingress.yaml
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: ingress-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
rules:
- host: ingress1.example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
tls:
- hosts:
- ingress1.example.com
secretName: ingress-tls
Changes in this manifest:
Added the annotation cert-manager.io/cluster-issuer: letsencrypt-prod
to instruct cert-manager to use the created ClusterIssuer
.
Added the tls
section, specifying the domains for which cert-manager should issue certificates and the secret (ingress-tls
) where they will be stored.
Apply the updated manifest:
kubectl apply -f ingress.yaml
After a short period, cert-manager will issue the certificates and store them in the ingress-tls
secret. To check the certificates, use:
kubectl get secret ingress-tls -n ingress-example -o yaml
If successful, the secret should contain tls.crt
and tls.key
.
Run the following command to test HTTPS connectivity:
curl -v https://ingress1.example.com/service1
If the request completes without errors, the certificates are successfully installed, and the services are running over HTTPS.