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.
Table of Contents
El gran mapa

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:
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

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

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.

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:

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