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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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

  1. 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
  2. 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.
  3. 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

  1. Install K3s Lightweight Kubernetes by running the following commands:

    curl -sfL https://get.k3s.io | sh –
    export PATH=$PATH:/user/local/bin
  2. Enable the use of kubectl permanently, by ensuring that /usr/local/bin appears as part of the PATH environment variable in the ~/.bash_profile file.
  3. 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
  4. Add the Cert-manager.io repository to Helm by running the following commands:

    helm repo add jetstack https://charts.jetstack.io
    helm repo update
  5. 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
  6. (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.

    1. 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-----
    2. 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
    3. 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

  1. 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.
  2. Log in to the Linux server that will host Cert-manager.io.
  3. Copy the certificates (trust chain) into the following directory:

    /etc/pki/ca-trust/source/anchors
  4. 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
  5. Run the following command to update the ca-bundle.crt file at the operating system level:

    sudo update-ca-trust extract
  6. 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.