Hace unos días noté algo extraño en mi homelab: los dominios internos como grafana.chocolandiadc.local o homeassistant.chocolandiadc.local dejaron de resolver. Los sitios públicos funcionaban perfectamente, pero mis servicios locales eran inaccesibles.
Mi Setup
Tengo un cluster K3s corriendo en mi homelab con Pi-hole desplegado como el DNS principal de la red. Mi router eero está configurado para usar Pi-hole como DNS primario, lo que significa que todas las consultas DNS de mis ~40 dispositivos pasan por el eero antes de llegar a Pi-hole.

El Síntoma
El síntoma era confuso: podía navegar a Google, YouTube, cualquier sitio público sin problemas. Pero cuando intentaba acceder a grafana.chocolandiadc.local, el navegador mostraba DNS_PROBE_FINISHED_NXDOMAIN.
Lo que estaba pasando era esto:
sequenceDiagram
participant D as Dispositivo
participant E as eero Router
participant P as Pi-hole (Primario)
participant S as DNS Secundario (8.8.8.8)
D->>E: Query: grafana.chocolandiadc.local
E->>P: Forward query
P--xE: REFUSED (rate-limited)
Note over E: Pi-hole rechazó la query.<br/>Fallback a DNS secundario.
E->>S: Query: grafana.chocolandiadc.local
S-->>E: NXDOMAIN (no existe)
E-->>D: NXDOMAIN
Note over D: ❌ No puede resolver<br/>dominios internosEl eero, al recibir REFUSED de Pi-hole, hacía fallback a su DNS secundario (8.8.8.8). Pero Google DNS no conoce mis dominios internos .chocolandiadc.local, así que respondía NXDOMAIN. Los dominios públicos funcionaban porque el DNS secundario sí podía resolverlos.
El Problema Real
Al revisar los logs de Pi-hole, encontré los warnings que explicaban todo:
[DNSMASQ_WARN] Maximum number of concurrent DNS queries reached (150)
[RATE_LIMIT] Client 192.168.4.1 has been rate-limited
(current config allows up to 1000 queries in 60 seconds)
Pi-hole estaba viendo todas las queries de mi red como si vinieran de un solo cliente (192.168.4.1 - el eero). Cuando mis 40 dispositivos generaban más de 1000 queries en un minuto (lo cual es completamente normal con Smart TVs, IoT, etc.), Pi-hole bloqueaba al eero, causando el fallback al DNS secundario.
La Investigación
Configuración Default de Pi-hole v6
Pi-hole v6 trajo cambios significativos en cómo se configura. El viejo archivo pihole-FTL.conf ya no existe, y las opciones de configuración ahora usan un formato diferente.
Revisé los valores default:
Parámetro Valor Default Problema
─────────────────────────────────────────────────────────────────────────
dns.rateLimit.count 1000 Muy bajo para router forwarder
dns.rateLimit.interval 60 (segundos)
dns-forward-max 150 Muy bajo para 40+ dispositivos
dns.rateLimit.exempt NO EXISTE Pi-hole v6 eliminó esta opciónEl Descubrimiento sobre Pi-hole v6
Descubrí algo importante: Pi-hole v6 eliminó la opción de eximir IPs específicas del rate-limiting. En versiones anteriores existía una opción para agregar IPs a una lista de excepciones, pero en v6 esto ya no está disponible.
La solución entonces era aumentar los límites lo suficiente para manejar el tráfico agregado de toda la red.
La Solución
Mi Pi-hole corre en Kubernetes gestionado con OpenTofu (fork de Terraform). La configuración se hace mediante variables de entorno con el prefijo FTLCONF_.
Variables de Entorno para Pi-hole v6
Aquí está el detalle importante que me costó encontrar: Pi-hole v6 usa un formato específico para las variables de entorno:
Configuración Variable de Entorno
─────────────────────────────────────────────────────────────────────────
dns.rateLimit.count → FTLCONF_dns_rateLimit_count
dns.rateLimit.interval → FTLCONF_dns_rateLimit_interval
misc.dnsmasq_lines → FTLCONF_misc_dnsmasq_linesNótese que se usa _ (underscore) para separar los niveles de configuración, no . (punto).
Los Cambios en Terraform
Agregué tres nuevas variables a mi módulo de Pi-hole:
variable "dns_max_concurrent_queries" {
description = "Max concurrent DNS queries via dnsmasq dns-forward-max"
type = number
default = 150
}
variable "dns_rate_limit_count" {
description = "Max queries from a single client within the interval"
type = number
default = 1000
}
variable "dns_rate_limit_interval" {
description = "Rate limit time interval in seconds"
type = number
default = 60
}Y las variables de entorno en el deployment:
env {
name = "FTLCONF_dns_rateLimit_count"
value = tostring(var.dns_rate_limit_count)
}
env {
name = "FTLCONF_dns_rateLimit_interval"
value = tostring(var.dns_rate_limit_interval)
}
dynamic "env" {
for_each = var.dns_max_concurrent_queries > 150 ? [1] : []
content {
name = "FTLCONF_misc_dnsmasq_lines"
value = "dns-forward-max=${var.dns_max_concurrent_queries}"
}
}Los Valores Finales
Parámetro Antes Después Justificación
─────────────────────────────────────────────────────────────────────────
dns.rateLimit.count 1000 10000 166 queries/seg
dns.rateLimit.interval 60 60 Sin cambios
dns-forward-max 150 1000 Soporta picos de 40+
dispositivos
Problema Bonus: MinIO Storage Full
Durante el proceso de aplicar estos cambios, me encontré con que mi backend de OpenTofu (MinIO corriendo en el mismo cluster) estaba al 100% de capacidad. Los backups de Velero con Kopia estaban consumiendo los 50GB del PVC.
La solución fue simple: expandir el PVC de Longhorn:
$ kubectl patch pvc minio-data -n minio \
-p '{"spec":{"resources":{"requests":{"storage":"300Gi"}}}}'Longhorn maneja la expansión online, así que el filesystem creció automáticamente sin necesidad de reiniciar el pod.
Lecciones Aprendidas
- Los síntomas pueden ser engañosos: "DNS público funciona, DNS interno no" me hizo pensar inicialmente en un problema de configuración de Pi-hole. El problema real era rate-limiting + fallback del router.
- El rate-limiting per-client no funciona bien con routers como DNS forwarders: Cuando todo el tráfico aparece como un solo cliente, los límites default son insuficientes.
- Pi-hole v6 cambió significativamente: La configuración migró de
pihole-FTL.confa variables de entornoFTLCONF_*, y algunas opciones comorateLimitExemptfueron eliminadas. - El formato de las variables importa: En Pi-hole v6,
dns.rateLimit.countse convierte enFTLCONF_dns_rateLimit_count(underscores, no puntos). - Monitorea tu storage: Los backups pueden crecer silenciosamente hasta llenar el disco. Longhorn hace trivial expandir PVCs online.
Referencias
- Pi-hole v6 Configuration Documentation
- Pi-hole v6 Upgrade Guide
- Discusión sobre max concurrent queries en Pi-hole v6
Este artículo documenta mi experiencia optimizando Pi-hole v6 corriendo en K3s con MetalLB. Tu configuración puede variar dependiendo de tu arquitectura de red.