Skip to content

Instantly share code, notes, and snippets.

@pythonhacker
Last active November 1, 2024 12:55
Show Gist options
  • Save pythonhacker/86c40478da075b821fb27fb5ae45ea9d to your computer and use it in GitHub Desktop.
Save pythonhacker/86c40478da075b821fb27fb5ae45ea9d to your computer and use it in GitHub Desktop.
Ingress Setup for K3S with TLS (letsencrypt)

Comprehensive Guide: Adding SSL Certification to Your k3s Cluster

Hello there! Today, we're diving deep into the process of adding SSL certification to services deployed on a k3s cluster. By the end of this guide, you'll be able to securely serve your services over HTTPS, enhancing the security of your applications.

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Installing cert-manager
  4. Creating an Issuer or ClusterIssuer
  5. Creating an Ingress Resource
  6. Configuring DNS
  7. Verifying Certificate Issuance
  8. Accessing Your Service
  9. Troubleshooting and Tips
  10. Advanced Topics
  11. Conclusion

k3s is a lightweight Kubernetes distribution that's widely used in edge computing, IoT devices, CI environments, and more. Security is crucial for all applications, and encrypted communication via SSL/TLS certificates is essential. In this guide, we'll walk you through the process of automatically issuing and managing SSL certificates for services deployed on your k3s cluster using cert-manager and Let's Encrypt.

Before we begin, make sure you have the following:

  • A running k3s cluster
  • The kubectl command-line tool installed and configured
  • Administrative access to your cluster
  • A valid domain name
  • Access to your domain's DNS settings
  • Basic understanding of Kubernetes concepts

cert-manager is a powerful tool for automatically provisioning and managing SSL/TLS certificates within Kubernetes clusters.

  1. Install cert-manager by running the following command:
kubectl apply -f <https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml>
  1. Wait for the installation to complete. You can check the status with:
kubectl get pods -n cert-manager

The installation is complete when all pods are in the 'Running' state.

An Issuer represents an entity that can issue certificates. We'll use Let's Encrypt to obtain free SSL certificates.

  1. Create a file named letsencrypt-prod.yaml with the following content:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: <https://acme-v02.api.letsencrypt.org/directory>
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: traefik
  1. Apply the file:
kubectl apply -f letsencrypt-prod.yaml

Note: Replace [email protected] with your actual email address.

An Ingress manages external access to services in a cluster, typically HTTP and HTTPS routes.

  1. Create a file named ingress.yaml with the following content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: svc1-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    kubernetes.io/ingress.class: "traefik"
spec:
  tls:
  - hosts:
    - your-domain.com
    secretName: svc1-tls
  rules:
  - host: your-domain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc1
            port:
              number: 80
  1. Apply the file:
kubectl apply -f ingress.yaml

Note: Replace your-domain.com with your actual domain name.

For SSL certification, your domain must point to your cluster's public IP address.

  1. Find your cluster's public IP address:
kubectl get svc traefik -n kube-system
  1. In your DNS provider's management page, create an A record linking your domain to this IP address.

cert-manager will automatically request and receive the certificate.

  1. Check the certificate status:
kubectl get certificate -n default
  1. For more detailed information:
kubectl describe certificate svc1-tls

Once everything is set up, you should be able to access your service securely via https://your-domain.com in your browser.

  • If you're having issues with certificate issuance, check the challenge status with kubectl get challenges -n default.
  • Let's Encrypt recommends testing in their staging environment before using the production environment. Use https://acme-staging-v02.api.letsencrypt.org/directory as the server field in your Issuer for staging.
  • k3s uses Traefik as the default Ingress Controller. If you're using a different Ingress Controller, your configuration may vary.
  • Ensure ports 80 (HTTP) and 443 (HTTPS) are open in your firewall settings.
  • Certificate renewal is automatic, but it's good practice to periodically check the status with kubectl get certificate -n default.

Certificate Rotation

cert-manager automatically handles certificate rotation, but understanding the process can be helpful:

  1. cert-manager checks the expiration date of certificates daily.
  2. If a certificate is nearing expiration (usually 30 days before), cert-manager initiates the renewal process.
  3. A new certificate is obtained without downtime, using the same private key.
  4. The new certificate replaces the old one in the Kubernetes secret.

Multiple Domains

You can secure multiple domains or subdomains with a single certificate. Modify your Ingress resource like this:

spec:
  tls:
  - hosts:
    - your-domain.com
    - www.your-domain.com
    - api.your-domain.com
    secretName: multi-domain-tls
  rules:
  - host: your-domain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: main-service
            port:
              number: 80
  - host: www.your-domain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: main-service
            port:
              number: 80
  - host: api.your-domain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080

Rate Limiting

Let's Encrypt has rate limits to prevent abuse. For production, you're limited to 50 certificates per registered domain per week. Plan accordingly and use the staging environment for testing.

Monitoring

To ensure your certificates are always valid, consider setting up monitoring:

  1. Use Prometheus to scrape cert-manager metrics.
  2. Set up alerts for certificates nearing expiration or failed renewals.
  3. Integrate with your existing monitoring stack (e.g., Grafana) for visualization.

By following this guide, you should have successfully added SSL certification to your k3s cluster. Your services can now be accessed securely over HTTPS. Remember that SSL/TLS certificates provide crucial security functions including data encryption, integrity verification, and establishing trust.

Keep in mind that security is an ongoing process. Regularly update your systems, follow security best practices, and stay vigilant against new threats.

If you have any questions or need further clarification on any part of this process, feel free to leave a comment below. Happy and secure k3s usage!

Reference

https://www.notion.so/Comprehensive-Guide-Adding-SSL-Certification-to-Your-k3s-Cluster-11ffd437022f806a9cc6e5a71bfad431?pvs=21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment