# Installing Cert Manager

We want to issue free SSL certificates for ingress https resources.

Treafik has a build in integration with Letsencrypt but unfourtunatelly its is not compatible with a HA setup where you have more than one instance of the ingress running (Deployment with replicas > 1 or DaemonSet). Instead of using it, we will use a separate installation of [cert-manager](https://cert-manager.io/next-docs/installation/)

We will also use the DNS chanllenge type with Cloudflare DNS provider.

Instalation
===========

Is simple with helm:

```
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.5.4 --set installCRDs=true
```

  

Now lets create the token for the DNS challenge:

Go to your domain and select "Get your API token"

Got to "Create token" then select Edit zone DNS template

In "Zone Resources" select the DNS zone you want

In "Permissions" select the following

*   Zone - DNS - Edit
*   Zone - Zone - Read

Click on generate token

  

Configuration and Test
======================

Create the cloudflare token:

  

```
apiVersion: v1
 kind: Secret
 metadata:
   name: cloudflare-api-token-secret
   namespace: cert-manager
 type: Opaque
 stringData:
   api-token: token-generate
```

Apply with `kubectl apply -f cloudflare-dns-api-secret.yml` of course change the file name to your secret file.

  

Create the cluster issues for staging and production, files

staging-cluster-issuer.yml

```
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
  namespace: cert-manager
spec:
  acme:
      # You must replace this email address with your own.
      # Let's Encrypt will use this to contact you about expiring
      # certificates, and issues related to your account.
      email: youremail
      server: https://acme-staging-v02.api.letsencrypt.org/directory
      privateKeySecretRef:
        name: staging-issuer-account-key
      solvers:
      - dns01:
          cloudflare:
            email: yourcloudflareemail
            apiTokenSecretRef:
              name: cloudflare-api-token-secret
              key: api-token
```

prod-cluster-issuer.yml

```
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: cert-manager
spec:
  acme:
      # You must replace this email address with your own.
      # Let's Encrypt will use this to contact you about expiring
      # certificates, and issues related to your account.
      email: youremail
      server: https://acme-v02.api.letsencrypt.org/directory
      privateKeySecretRef:
        name: prod-issuer-account-key
      solvers:
      - dns01:
          cloudflare:
            email: yourcloudflareemail
            apiTokenSecretRef:
              name: cloudflare-api-token-secret
              key: api-token
```

Apply this yaml:

```
kubectl apply -f staging-cluster-issuer.yml
kubectl apply -f prod-cluster-issuer.yml
```

Lets test the certification issuer:

  

```
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: test-domain-com
  namespace: cert-manager
spec:
  secretName: test-domain-com
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer
  commonName: test.domain.com
  dnsNames:
  - test.domain.com
```

Edit [test.domain.com](http://test.domain.com) and test-domain-com with your domain

Apply with kubectl apply -f test-certificate.yml

See if its ready:

```
kubectl -n cert-manager get certificate
```

When the certificate gets ready (it should take a minute or two), describe it:

  

```
kubectl -n cert-manager describe certificate test-domain-com
```

Should have something like:

  

```
Name:         test-domain-com
Namespace:    cert-manager
Labels:       <none>
Annotations:  <none>
API Version:  cert-manager.io/v1
Kind:         Certificate
Metadata:
  Creation Timestamp:  2021-10-25T17:08:36Z
  Generation:          1
  Managed Fields:
    API Version:  cert-manager.io/v1
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .:
          f:kubectl.kubernetes.io/last-applied-configuration:
      f:spec:
        .:
        f:commonName:
        f:dnsNames:
        f:issuerRef:
          .:
          f:kind:
          f:name:
        f:secretName:
    Manager:      kubectl-client-side-apply
    Operation:    Update
    Time:         2021-10-25T17:08:36Z
    API Version:  cert-manager.io/v1
    Fields Type:  FieldsV1
    fieldsV1:
      f:status:
        .:
        f:conditions:
        f:notAfter:
        f:notBefore:
        f:renewalTime:
        f:revision:
    Manager:         controller
    Operation:       Update
    Time:            2021-10-25T17:10:03Z
  Resource Version:  1002607
  UID:               8646cd17-50fa-4419-9dcf-184ea2340bb5
Spec:
  Common Name:  test.doamin.com
  Dns Names:
    test.domain.com
  Issuer Ref:
    Kind:       ClusterIssuer
    Name:       letsencrypt-staging
  Secret Name:  test-domain-com
Status:
  Conditions:
    Last Transition Time:  2021-10-25T17:10:03Z
    Message:               Certificate is up to date and has not expired
    Observed Generation:   1
    Reason:                Ready
    Status:                True
    Type:                  Ready
  Not After:               2022-01-23T16:10:01Z
  Not Before:              2021-10-25T16:10:02Z
  Renewal Time:            2021-12-24T16:10:01Z
  Revision:                1
Events:
  Type    Reason     Age   From          Message
  ----    ------     ----  ----          -------
  Normal  Issuing    3m6s  cert-manager  Issuing certificate as Secret does not exist
  Normal  Generated  3m6s  cert-manager  Stored new private key in temporary Secret resource "test-domain-com-zgtqd"
  Normal  Requested  3m6s  cert-manager  Created new CertificateRequest resource "test-domain-com-r78kp"
  Normal  Issuing    99s   cert-manager  The certificate has been successfully issued
```

  

**Cleaning up:**

```
kubectl delete -f test-certificate.yml
kubectl -n cert-manager delete secret test-domain-com
```

For more information on how to issue certificates for your ingress resources see the official documentation [https://cert-manager.io/next-docs/usage/ingress/](https://cert-manager.io/next-docs/usage/ingress/)

A tip is when using traefik IngressRoute we need to issue the certificate outside the ingress, you can see a example in this post [https://www.padok.fr/en/blog/traefik-kubernetes-certmanager](https://www.padok.fr/en/blog/traefik-kubernetes-certmanager)

  

Congratulations, you have a automated, free SSL certification issuer. K8S is awesome!
