Traefik 2 con Cloudflare y Let's Encrypt

Kubernetes 1 de may. de 2020

En un tutorial anterior os enseñaba como usar Traefik como proxy inverso con generación automática de certificados con Let's Encrypt.

Traefik 2 como ingress de Kubernetes
En este tutorial os voy a explicar como instalar Traefik v2 como ingress devuestro cluster de Kubernetes. Además de instalar Traefik v2, lo configuraremos para que nos redireccione todoel tráfico http a https y nos genere los certificados automáticamente conletsencrypt. El tutorial estará divid…

Hoy os voy a enseñar a modificar la instalación de Traefik para que Let's Encrypt use el proveedor DNS Cloudflare para validar los certificados.


Antes de empezar

Este post es solo para los que tienen los DNS de su(s) dominio(s) administrados a través de Cloudflare. Es completamente gratuito y lo recomiendo al 100%, no he tenido ningún problema y te permite añadir mucha más flexibilidad a tus dominios.

Cloudflare | Web Performance & Security
Log in to Cloudflare to access our scalable and easy-to-use security and performance platform. Enable enterprise class speed and protection to keep your app safe and available around the globe.

Instalación

Tendremos que sustituir este archivo en el post mencionado arriba.

Deployment.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-traefik
spec:
  capacity:
    storage: 2Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: storage-nfs
  mountOptions:
    - nfsvers=4.1
  nfs:
    path: /mnt/SSD/kubernetes/traefik-prod
    server: 10.0.4.20
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  finalizers:
  - kubernetes.io/pvc-protection
  labels:
    app: traefik-ingress-lb
  name: pvc-traefik
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
  storageClassName: storage-nfs
  volumeName: pv-traefik
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: traefik-ingress-controller
  labels:
    k8s-app: traefik-ingress-lb
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - image: traefik:v2.2
        name: traefik-ingress-lb
        imagePullPolicy: Always
        volumeMounts:
          - mountPath: "/cert/"
            name: cert
        resources:
          requests:
            cpu: 120m
            memory: 80Mi
        env:
            - name: CF_API_EMAIL
              value: [email protected]
            - name: CF_API_KEY
              valueFrom:
                secretKeyRef:
                  name: cloudflare-credentials
                  key: globalApiKey
        args:
          #- --log.level=DEBUG
          - --api.insecure
          - --serversTransport.insecureSkipVerify=true
          - --accesslog
          - --providers.kubernetescrd
          - --entrypoints.web.address=:80
          - --entrypoints.websecure.address=:443
          - --entrypoints.udpep.address=:9000/udp
          - --entrypoints.tcpep.address=:8000
          - [email protected]
          - --certificatesresolvers.default.acme.storage=/cert/acme.json
          - --certificatesResolvers.default.acme.dnsChallenge=true
          - --certificatesResolvers.default.acme.dnsChallenge.provider=cloudflare
          - --certificatesResolvers.default.acme.dnsChallenge.delayBeforeCheck=30
          # Please note that this is the staging Let's Encrypt server.
          # Once you get things working, you should remove that whole line altogether.
          # - --certificatesresolvers.default.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
          # Production Let's Encrypt server.
          - --certificatesresolvers.default.acme.caserver=https://acme-v02.api.letsencrypt.org/directory
      volumes:
      - name: cert
        persistentVolumeClaim:
          claimName: pvc-traefik
---

apiVersion: v1
kind: Service
metadata:
  name: traefik
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app: traefik
  ports:
    - protocol: TCP
      port: 80
      name: web
      targetPort: 80
    - protocol: TCP
      port: 443
      name: websecure
      targetPort: 443
    - protocol: TCP
      port: 8080
      name: admin
      targetPort: 8080
    - protocol: TCP
      port: 8000
      name: tcpep
      targetPort: 8000

---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: cloudflare-credentials
  namespace: default
data:
  globalApiKey: GLOBAL_API_KEY_EN_BASE64
---
apiVersion: v1
kind: Service
metadata:
  name: traefikudp
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app: traefik
  ports:
    - protocol: UDP
      port: 9000
      name: udpep
      targetPort: 9000
Esto es la instalación de Traefik en si con su dashboard

Para obtener la clave API de nuestro Cloudflare, tenemos que ir a nuestro perfil, API Tokens y copiar la clave Global API Key.

Deberemos sustituir [email protected] por nuestro email de Cloudflare y GLOBAL_API_KEY_EN_BASE64 por nuestra Global API Key convertida a Base64. Para convertirla podemos hacerlo usando un conversor online (no lo recomiendo) o bien en Linux:

echo 'aqui vuestra global api key' | base64
Lo que retorne el terminal será la clave ya en Base64

Una vez hecho esto, hacemos:

kubectl apply -f Deployment.yaml

Y ya estaría, ya tendríamos Cloudflare validando las peticiones de Let's Encrypt, y dado que usamos verificación DNS para validar los dominios en vez de TLS como en el tutorial anterior, Let's Encrypt nos permitirá crear certificados SSL del tipo wildcard.

Etiquetas

Carlos Mora Clavero

Soy un estudiante al que le gusta aprender cosas nuevas en sus ratos libres sobre sistemas, hardware, programación, etc.