Como publicar Kubernetes con External DNS, MetalLB y Traefik.

Kubernetes con External DNS, MetalLB y Traefik nos van a servir para que las aplicaciones web (en un entorno o no de microservicios) se publiquen, ya que los requisitos básicos son resolver por DNS el nombre del equipo y la ruta web que lleva a la aplicación.

El gran mapa

Como publicar Kubernetes con External DNS, MetalLB y Traefik. 1

Tras los pasos realizados en K3s: Kubernetes más simple y Helm v3 para desplegar PowerDNS sobre Kubernetes vamos a darle forma a una solución Kubernetes más completa para que pueda publicar servicios bajo su propio dominio y ruta y que a su vez sea accesible desde el exterior. Y siempre usando los mínimos recursos en esta tarea.

MetalLB

MetalLB que nos permitirá emular la potencia de los balanceadores de los entornos Cloud, los requisitos de está solución son una versión de Kubernetes 1.13 o superior, que no exista otro balanceador de red operativo y que el controlador de red esté soportado en la lista indicada en https://metallb.universe.tf/installation/network-addons/, debemos tener en cuenta que K3s incluye flannel que está soportado y que en el caso de otros como Weave se requieren una serie de modificaciones.

Para instalar MetalLB solo es necesario aplicar el archivo “yaml” que despliega todos los elementos:

$ sudo kubectl apply -f "https://raw.githubusercontent.com/danderson/metallb/master/manifests/metallb.yaml"

Y para activar MetalLB le creamos una configuración (archivo pool.xml) que tendrá la forma:

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: my-ip-space
      protocol: layer2
      addresses:
      - 192.168.8.240/28

Que al aplicar con k3s kubectl apply -f pool.yml configurará MetalLB para que en el caso de que existan servicios con loadBalancer utilicen una de las IPs definidas en el rango especificado (en este caso 192.168.9.240/28).

MetalLB es una gran ventaja sobre otros tipos de soluciones locales, ya que no requiere del uso de SDN (como es el caso de Kubernetes sobre VMware NSX) o de servidores específicos para la publicación (como el caso de OpenShift, que ademas de SDN requiere de maquinas especificas para publicar servicios).

Traefik

Traefik es un servicio enrutador con múltiples características como son:

  • Enrutador Edge
  • Descubrimientos de servicios
  • Balanceador de carga en capa 7
  • Terminador TLS y soporte Let’s Encrypt (ACME)
  • Dispone de un Kubernetes Ingress Controller
  • Dispone de un CRD IngressRoute
  • Permite Canary Deployments
  • Trazas, métricas y registro

Con K3s se despliega de forma automática Traefik al iniciar el nodo master, en el caso de Kubernetes se va a hacer a través de Helm y para la configuración necesitamos un archivo yaml como el siguiente:

dashboard:
  enabled: "true"
  domain: "traefik-dashboard.DOMINIO"
  auth:
    basic:
      admin: $apr1$zjjGWKW4$W2JIcu4m26WzOzzESDF0W/
rbac:
  enabled: "true"
ssl:
  enabled: "true"
  mtls:
    enabled: "true"
    optional: "true"
  generateTLS: "true"
kubernetes:
  ingressEndpoint:
    publishedService: "kube-system/traefik"
metrics:
  prometheus:
    enabled: "true"

Esta configuración es muy parecida a la que despliega K3s y a la hemos añadido el dashboard donde podremos revisar el estado de las rutas y servicios configurados. Hay varios puntos importantes:

  • rbac: Configura los permisos en Kubernetes necesarios para su funcionamiento.
  • dashboard: La consola de estado de Traefik, necesita que se configure al menos autenticación para el acceso en este caso es básica, usuario admin, clave: admin.
  • ssl: En el caso de un entorno de producción se configura una capa SSL con certificados válidos, en nuestro caso al ser un entorno de prueba serán autogenerados, seleccionamos además el soporte mtls (mutual tls) para seguridad extremo a extremo con los servicios que estarán detrás de Traefik.
  • kubernetes: Configuración especifica para indicar que servicio es por el que se publicarán los ingress, puede ser un LoadBalancer o un NodePort. De está manera es como Traefik se convierte en un enrutador.

Para ejecutar el Chart con Helm 3 hacemos:

cat <<EOF |helm install -f - -n kube-system traefik stable/traefik
dashboard:
  enabled: "true"
  domain: "traefik-dashboard.DOMINIO"
  auth:
    basic:
      admin: $apr1$zjjGWKW4$W2JIcu4m26WzOzzESDF0W/
rbac:
  enabled: "true"
ssl:
  enabled: "true"
  mtls:
    enabled: "true"
    optional: "true"
  generateTLS: "true"
kubernetes:
  ingressEndpoint:
    publishedService: "kube-system/traefik"
metrics:
  prometheus:
    enabled: "true"
EOF

Y como en nuestro caso el servicio es un LoadBalancer comprobamos que ha cogido correctamente la IP:

#kubectl -n kube-system get service -A
NAMESPACE     NAME                TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                     AGE
...
kube-system   traefik             LoadBalancer   10.110.144.104   192.168.8.240   80:30026/TCP,443:30951/TCP,8080:31031/TCP   11s
kube-system   traefik-dashboard   ClusterIP      10.101.84.221    <none>          80/TCP                                      11s

Las capacidades de Traefik son bastante impresionantes, por lo que recomendamos revisar su documentación en https://docs.traefik.io/

Kubernetes con External DNS

Como publicar Kubernetes con External DNS, MetalLB y Traefik. 2

External-DNS es una característica en incubación que nos va a permitir configurar un servidor DNS (en nuestro caso PowerDNS) para que este disponga de recursos DNS para los Ingress y los Services utilizados. Para instalar External-DNS hacemos uso también de Helm

Suponemos que el namespace external-dns ya ha sido creado anteriormente y es donde PowerDNS está desplegado.

cat <<EOF |helm install -f - -n external-dns external-dns stable/external-dns
provider: "pdns"
pdns:
  apiUrl: "http://powerdns-service-api.external-dns.svc.DOMINIO"
  apiPort: 8081
  apiKey: "APIKEY"
txtOwnerId: "external-dns"
domainFilters:
  - "DOMINIO"
logLevel: "info"
interval: "10s"
rbac:
  create: "true"
EOF

APIKEY es la clave de acceso a la API de PowerDNS configurada en su despliegue, apiUrl debe apuntar al servicio que expone dicha API y el “provider” configurado es “pdns”.

Probando todo junto

Para ver como Kubernetes con External DNS, PowerDNS, Traefik y MetalLB funcionan juntos se puede crear el entorno indicado en Kubernetes: Crear un entorno mínimo para demos o en K3s: Kubernetes más simple y aplicar Helm v3 para desplegar PowerDNS sobre Kubernetes ademas de los pasos anteriores, para comprobar el acceso a External-DNS debemos configurar la IP obtenida con kubectl -n external-dns get service powerdns-service-dns:

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE 
powerdns-service-dns   LoadBalancer   10.43.193.114   192.168.8.241   53:30581/UDP   6d3h

Que tenemos que configurar en el cliente DNS del equipo (por ejemplo en /etc/resolv.conf) y podremos acceder a las rutas configuradas en traefik, como por ejemplo el dashboard en https://traefik,DOMINIO/dashboard

Como publicar Kubernetes con External DNS, MetalLB y Traefik. 3

Y el servicio de administración de PowerDNS es accesible en https://powerdns-admin.DOMINIO y veremos todos los recursos publicados por external-dns que son los extraídos de los ingress y que tendrán la IP del servicio LoadBalancer de Traefik.

Como publicar Kubernetes con External DNS, MetalLB y Traefik. 4

Tras acceder, procedemos a desplegar un nuevo servicio como k8dash:

kubectl apply -f https://raw.githubusercontent.com/herbrandson/k8dash/master/kubernetes-k8dash.yaml

Y para acceder al mismo creamos el siguiente Ingress

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: k8dash
  namespace: kube-system
spec:
  rules:
  - host: k8dash.DOMINIO
    http:
      paths:
      - backend:
          serviceName: k8dash
          servicePort: 80
        path: /

Al aplicarlo debemos encontrar en Traefik este nuevo host:

Como publicar Kubernetes con External DNS, MetalLB y Traefik. 5

Y debemos de tener la capacidad de acceder al servicio con la URL ya que la resolución DNS debe ser correcta:

Como publicar Kubernetes con External DNS, MetalLB y Traefik. 6
Volver arriba