Cert-manager.io adds certificates and certificate issuers as resource types in Kubernetes clusters, and can simplify the process of obtaining, renewing, and using those certificates. You can use Cert-manager.io to request certificates from Certificate Enrollment Gateway using the ACMEv2 protocol.
The instructions in this example use Cert-manager.io installed in a Kubernetes cluster using Helm. Other methods of configuring and deploying Cert-manager.io are available, but are not documented in this guide.
Configuring Cert-manager.io for Certificate Enrollment Gateway with ACMEv2
The following procedures configure Cert-manager.io to request and receive certificates using DNS-01 and HTTP-01 validation. Configuring Cert-manager.io requires configuring a series of YAML files, then applying those files to Cert-manager.io. After applying the files, Cert-manager.io will automatically request the files from Certificate Enrollment Gateway.
For HTTP-01 validation, the following example uses Cert-manager.io's ingress-shim features. In this example, you will create a dummy back-end service (echo), and then an Ingress. The Ingress routes traffic into the cluster, and requests TLS certificates for the services to which it is routing.
For this example, you will create the following files:
dns-issuer.yaml
, to define the DNS issuer for DNS-01 validation.dns-cert.yaml
, to define the DNS certificate for DNS-01 validation.http-issuer.yaml
, to define the HTTP issuer for HTTP-01 validation.echo.yaml
, to define the echo (dummy back-end) service for HTTP-01 validation.
In this example, the echo service is a dummy back-end to show how to secure an existing service on the Kubernetes cluster.http-ingress.yaml
, to define the Ingress for HTTP-01 validation.
To create the YAML files for Cert-manager.io
Create a new file named
dns-issuer.yaml
with the following contents. Read the comments and modify the content as required.---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: test-dns
namespace: default
spec:
dnsNames:
#NOTE: This only works if the DNS ClusterIssuer has permission to update "example.com" records
- dns.example.com
secretName: test-dns
issuerRef:
name: ceg-issuer-dns
kind: ClusterIssuer
Create a new file named
dns-cert.yaml
with the following contents. Read the comments and modify the content as required.---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: test-dns
namespace: default
spec:
dnsNames:
#NOTE: This only works if the DNS ClusterIssuer has permission to update "example.com" records
- dns.example.com
secretName: test-dns
issuerRef:
name: ceg-issuer-dns
kind: ClusterIssuer
Create a new file named
http-issuer.yaml
with the following contents. Read the comments and modify the content as required.---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: ceg-issuer-http
namespace: cert-manager
spec:
acme:
# Uncomment the following line to allow insecure TLS connections.
#skipTLSVerify: true
# The ACME server URL
server: https://cegserver.example.com/acme/tenant1/example_ca1/
privatessl_tls_client/directory
# Email address used for ACME registration
email: certmanager@example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: ceg-acme-account-key-http
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: traefik
Create a new file named
echo.yaml
with the following contents.---
apiVersion: v1
kind: Service
metadata:
name: echo
spec:
ports:
- port: 80
targetPort: 5678
selector:
app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo
spec:
selector:
matchLabels:
app: echo
replicas: 1
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: hashicorp/http-echo
args:
- "-text=echo"
ports:
- containerPort: 5678
Create a new file named
http-ingress.yaml
with the following contents. Read the comments and modify the content as required.---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo1-traefik-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
cert-manager.io/cluster-issuer: ceg-issuer-http
spec:
tls:
- hosts:
# Change the hostname here to the one you want a TLS Certificate for.
# NOTE: CEG's must resolve the following hostname to cert-manager.io's IP Address.
- echo1.example.com
secretName: echo-tls
rules:
# The following host must match the host in the "tls" section a few lines up.
- host: echo1.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: echo
port:
number: 80
To apply the YAML files to Kubernetes and request certificates
Apply the files with the following commands.
kubectl apply -f dns-issuer.yaml
kubectl apply -f dns-cert.yaml
kubectl apply -f http-issuer.yaml
kubectl apply -f http-echo.yaml
kubectl apply -f http-ingress.yaml
- After applying the files, Cert-manager.io has been configured to request two different certificates over two different ClusterIssuers, one certificate for DNS-01 validation, and one certificate for HTTP-01 validation. The certificates will automatically be requested by Cert-manager.io.
To view the status of all cert-manger.io ACMEv2 objects, enter the following command:
kubectl get Issuers,ClusterIssuers,Certificates,CertificateRequests,Orders,Challenges --all-namespaces
Deploying Kubernetes and Cert-manager.io
This section describes how to deploy a single-node Kubernetes, and then how to deploy Cert-manager.io into it.
To deploy Kubernetes and Cert-manager.io
Install K3s Lightweight Kubernetes by running the following commands:
curl -sfL https://get.k3s.io | sh –
export PATH=$PATH:/user/local/bin
- Enable the use of kubectl permanently, by ensuring that
/usr/local/bin
appears as part of thePATH
environment variable in the~/.bash_profile
file. Install Helm by running the following commands:
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
echo "export KUBECONFIG=/etc/rancher/k3s/k3s.yaml" >> ~/.bash_profile
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
Add the Cert-manager.io repository to Helm by running the following commands:
helm repo add jetstack https://charts.jetstack.io
helm repo update
Install Cert-manager.io using Helm by entering the following command:
helm upgrade -i -n cert-manager cert-manager jetstack/cert-manager --set installCRDs=true --create-namespace --version v1.6.0-beta.0 --wait
(Secure HTTP Only) If you want to use Cert-manager.io with trusted HTTPS connections, then you must add the TLS CA certificate chain into the cluster.Create a
private-ca-bundle.pem
file.This file contain a concatenation of all PEM certificates in the CA certificate chain, starting with the issuing CA first and ending with the root CA last. For example:
-----BEGIN CERTIFICATE-----
MIIF0TCCA7mgAwIBAgIQCy...
...
V8HUOts=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFUDCCAzigAwIBAgIQRv...
...
XLy202FpMk40JO31gqbnDOusrY8=
-----END CERTIFICATE-----
Create a config-map from the
private-ca-bundle.pem
file by running the following command:kubectl create configmap private-ca-bundle -n cert-manager --from-file=private-ca-bundle.pem
Update the Cert-manager.io deployment to use the config-map using Helm, by running the following command:
helm upgrade -i -n cert-manager cert-manager jetstack/cert-manager \
--version v1.6.0-beta.0 \
--set installCRDs=true \
--set volumes[0].name=ca-certs,volumes[0].configMap.name=private-ca-bundle \
--set volumeMounts[0].name=ca-certs,volumeMounts[0].mountPath=/etc/ssl/certs \
--wait --wait-for-jobs
You have now deployed a single-node Kubernetes cluster and installed Cert-manager.io. Certificate Enrollment Gateway’s TLS certificate chain is also trusted at the Cert-manager.io namespace, cluster, and operating system levels. The certificate chain still needs to be configured at the pod level.
Preparing Linux for HTTPS (optional)
This section is required only if the Kubernetes cluster that will host Cert-manager.io will use a trusted HTTPS connection to connect to Certificate Enrollment. If you will not use a trusted HTTPS connection, you can skip this section. You must complete this step before deploying the Kubernetes cluster.
To configure Linux to trust a CA certificate chain, complete the following steps.
To configure Linux to trust a CA certificate chain
- Transfer Certificate Enrollment Gateway's trust certificate chain (from the issuing CA certificate to the root CA certificate) to the Linux server that will host Cert-manager.io. The certificate files must be in PEM format.
- Log in to the Linux server that will host Cert-manager.io.
Copy the certificates (trust chain) into the following directory:
/etc/pki/ca-trust/source/anchors
Enter the following command to update the file permissions for
ca-bundle.crt
so everyone can read the file:sudo chmod +r ./ca-bundle.crt
Run the following command to update the
ca-bundle.crt
file at the operating system level:sudo update-ca-trust extract
Verify that the certificates were added to the following file:
/etc/pki/tls/certs/ca-bundle.crt
Cert-manager.io prerequisites
To use Cert-manager.io with Certificate Enrollment Gateway:
- If you will use secure HTTPS with Cert-manager.io, copy Certificate Enrollment Gateway’s TLS certificate chain to the server that will host Cert-manager.io.
- For HTTP-01 validation, the DNS server must resolve the requested DNS name to the IP address of the server hosting Cert-manager.io.
- For DNS-01 validation, nonsecure and secure dynamic updates must be enabled for the domain for which Cert-manager.io is requesting certificates.
- Obtain the ACMEv2 enrollment URL used to request a certificate from Certificate Enrollment Gateway. For details, see ACMEv2 enrollment URL. You need this URL later when configuring Cert-manager.io.