Icono del sitio Disaster Project

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

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:

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:

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:

Salir de la versión móvil