Code Monkey home page Code Monkey logo

k8s-letsencrypt's Introduction

Let's Encrypt for Kubernetes: The "Hard" Way

This repo shows you how to manage Let's Encrypt certificates in your Kubernetes cluster without the use of automation. Normally, you should be fine using something like cert-manager or Traefik to automatically manage your certs. However, when these tools fail it's good to have a backup plan to keep your certificates up to date. That's where this repo comes in.

Note: The following instructions are for using the http validation method. If you prefer to use the DNS method, you can skip the acme-challenge service creation and path routing steps.

How to Use This Repo

You can either use the two provided yaml files as-is in your cluster, or, if you'd like to have more control and customization, build the admin Docker image yourself and tweak the yaml files according to your needs.

The following sections show how to use this code:

HTTP Method Validation

The following sections describe how to create your certs using the HTTP Method.

Step 1 (Optional): Build the Admin Image

The Admin pod is just a Debian image with certbot and kubectl pre-installed. If you trust my work, you can go ahead and use the public Docker Hub image I have published at nabsul/k8s-admin:v002. But to be honest, you really shouldn't trust Docker images from strangers. For this reason, I personally recommend building the admin image yourself:

You can also build the docker image yourself using the included Dockerfile, or even deploy a base image and manually install certbot and kubectl once you log in. If you go this route you'll need to tweak the image field at the end of the admin.yaml accordingly.

Step 2: Deploy the admin Image and acme-challenge Service

The Admin pod will need permissions to create certificates. The admin.yaml file deploys the pod and grants it access to manage secrets in your cluster. To create the admin pod, simply run:

kubectl apply -f admin.yaml

The acme-challenge service is just a plain nginx pod. We will be routing requests to the /.well-known/acme-challenge path to this pod for the validation step needed to create Let's Encrypt certificates. The service can be created with the following command:

kubectl apply -f acme-challenge.yaml

Step 3: Route Path to the acme-challenge Service

You'll need to route requests to the /.well-known/acme-challenge path to the acme-challenge service. To do this, go to your Ingress definition and add the following as the first entry in your paths section:

      - path: /.well-known/acme-challenge
        pathType: Prefix
        backend:
          serviceName: acme-challenge
          servicePort: 80

For example, your complete ingress file should look like this:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tet-ingress
spec:
  tls:
  - hosts:
    - mytest.test
    secretName: test-tls
  rules:
  - host: mytest.test
    http:
      paths:
      - path: /.well-known/acme-challenge
        pathType: Prefix
        backend:
          serviceName: acme-challenge
          servicePort: 80
      - backend:
          serviceName: hello-world
          servicePort: 80

Step 4: Run CertBot

Now we'll log into the admin pod to create our certificate:

kubectl exec -it k8s-admin -- bash

You should now see the Debian bash prompt of the admin pod. You can now start the process of issuing the certificate with the following command:

certbot certonly --manual --preferred-challenges http -d [mydomain.com]

You will have to provide your email address and agree to some terms. You will then be asked to create a file with content like this:

Create a file containing just this data:

2RzV_b85lAE2wPn_Nf-UJzdVkxPjxgw8_6oEtPpV6ls.ABCABC_1dedKwm_TsyyDkbIsd76jnfrn5a_XrwkPkHU

And make it available on your web server at this URL:

http://[your-domain]/.well-known/acme-challenge/ABSABV_b85lAE2wPn_Nf-UJzdVkxPjxgw8_6oEtPpV6ls

Leave this window/tab open and move on to the next step:

Step 5: Copy Code to the acme-challenge Service

In a new shell window/tab you'll need to log into your nginx service.

kubectl exec -it acme-challenge -- bash

We'll now navigate to the html content directory and create a couple of empty directories:

cd /usr/share/nginx/html/
mkdir .well-known
cd .well-known
mkdir acme-challenge
cd acme-challenge

Finally, we'll create the file that was requested in the previous step. For example:

echo 2RzV_b85lAE2wPn_Nf-UJzdVkxPjxgw8_6oEtPpV6ls.ABCABC_1dedKwm_TsyyDkbIsd76jnfrn5a_XrwkPkHU > ABSABV_b85lAE2wPn_Nf-UJzdVkxPjxgw8_6oEtPpV6ls

Step 6: Create a Kubernetes Secret

Now we will return to the first window/tab and press "enter" to continue. If everything was done correctly, it should report a success message like so:

Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/[your-domain]/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/[your-domain]/privkey.pem
   Your cert will expire on 2021-01-21. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"

We will navigate to the directory shown above:

cd /etc/letsencrypt/live/[your-domain]

And finally, we'll create our ssl cert in Kubernetes with the following command. If the secret already exists, you'll first need to delete it. You can skip the delete command if it doesn't already exist:

kubectl delete secret [your-cert-name]
kubectl create secret tls [your-cert-name] --cert=fullchain.pem --key=privkey.pem

Step 7: Clean Up

You don't need to keep the admin pod running after you've issued your certificates. To delete the admin pod and acme-challenge service, you can run the following two commands:

kubectl delete -f admin.yaml
kubectl delete -f acme-challenge.yaml

You can also remove the .well-known path entry from the Ingress configuration.

DNS Validation Method

I won't go into as much detail for the DNS method. It's very similar to the HTTP method except:

  • No need to deploy the acme-challenge service
  • No need to add the /.well-known/acme-challenge path to the ingress configuration
  • Use --preferred-challenges dns in the certbot command instead of --preferred-challenges http
  • Instead of creating a file in the nginx pod, you'll create a txt entry in your domain configuration

k8s-letsencrypt's People

Contributors

nabsul avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.