Files
kubernetes/coredns
2025-09-04 00:13:39 +02:00
..
2025-09-04 00:13:39 +02:00
2025-09-04 00:13:39 +02:00
2025-08-22 18:01:14 +02:00
2025-09-04 00:13:39 +02:00

CoreDNS dedicado para DNS interno / splithorizon

Este directorio contiene los manifiestos para desplegar un CoreDNS propio (namespace coredns) que sirve como DNS interno para resoluciones splithorizon y control de rutas en la VPN (splittunnel).

Con este CoreDNS:

  • Los FQDN internos (p. ej. portal.apolo.c2et.net) resuelven a la VIP interna 192.168.200.10 cuando el cliente usa el DNS interno 192.168.200.11 → el tráfico va por la VPN/LAN.
  • Los FQDN “externos” (p. ej. admin.firewall.c2et.net) pueden apuntar a la VIP pública 192.168.0.100 desde el mismo DNS interno (útil para pruebas) o gestionarse sólo en el DNS público.
  • El resto de nombres se reenvían a los resolvers del nodo (/etc/resolv.conf).

Estructura

./coredns
├── configmap-coredns.yaml   # Corefile con hosts, forward y cache
├── deploy-coredns.yaml      # Deployment (réplicas, probes y mounts)
├── kustomization.yaml       # Kustomize para aplicar todo el conjunto
├── namespace.yaml           # Namespace dedicado: coredns
└── svc-coredns.yaml         # Service LoadBalancer (UDP/TCP 53) → 192.168.200.11

Despliegue

Requisitos: MetalLB operativo en la red 192.168.200.0/24 para anunciar 192.168.200.11.

# Desde ./kubernetes/coredns
kubectl apply -k .

# Verificar
kubectl -n coredns get all
kubectl -n coredns get svc coredns-custom -o wide  # Debe mostrar External IP: 192.168.200.11
kubectl -n coredns logs deploy/coredns-custom -f    # Comprobar health/errores

Configuración (Corefile)

El Corefile se define en configmap-coredns.yaml:

.:53 {
  log
  errors
  health
  reload
  hosts {
    # === APOLO (GPS táctico) ===
    192.168.200.10 backend.apolo.c2et.net
    192.168.200.10 portal.apolo.c2et.net
    192.168.200.10 colossus.apolo.c2et.net
    192.168.200.13 chat.apolo.c2et.net
    192.168.200.13 muc.chat.apolo.c2et.net
    192.168.200.12 streaming.apolo.c2et.net
    192.168.200.14 meeting.apolo.c2et.net

    # === ARGOS (videovigilancia) ===
    192.168.200.15 mqtt.argos.interna
    192.168.200.16 mediamtx.argos.interna
    192.168.200.10 s3.argos.interna
    192.168.200.10 minio.argos.interna
    192.168.200.10 panel.argos.c2et.net

    # === External ===
    192.168.0.100 admin.firewall.c2et.net
    192.168.0.100 k8s.c2et.net
    192.168.0.100 admin.powervault1.c2et.net
    192.168.0.100 admin.powervault2.c2et.net
    192.168.0.100 ceph.c2et.net

    fallthrough
  }
  forward . /etc/resolv.conf
  cache 120
  # prometheus 0.0.0.0:9153   # (opcional) exportar métricas
}

Puntos clave

  • hosts: mapa de FQDN → IP (A/AAAA estáticos). Añade/edita aquí tus entradas internas.
  • fallthrough: si un nombre no está en hosts, la consulta pasa al siguiente plugin.
  • forward . /etc/resolv.conf: reenvía el resto de consultas a los resolvers del nodo.
  • cache 120: cache de respuestas para mejorar latencia.
  • reload: CoreDNS recarga el Corefile cuando cambia el ConfigMap montado.

Modificar el Corefile ⇒ kubectl -n coredns apply -f configmap-coredns.yaml (CoreDNS recarga solo). Si fuera necesario, un rollout restart del deployment.


Integración con la VPN (splittunnel)

Para que los clientes usen las VIP internas cuando están en la VPN:

  1. Empuja el DNS interno por la VPN:

    • DNS del cliente: 192.168.200.11 (este Service).
    • Asegúrate de que la interfaz de la VPN enruta el DNS interno (por ejemplo con AllowedIPs = 192.168.200.11/32 en WireGuard).
  2. Splithorizon: este CoreDNS responde con IPs internas (192.168.200.x). Si el cliente no usa este DNS, resolverá contra el público y saldrá por Internet (lo cual está bien si quieres que el Ingress lo bloquee por whitelist).

  3. Ingressnginx (contexto relacionado):

    • Services del controller con externalTrafficPolicy: Local para preservar IP origen.

    • Anotación de whitelist en los Ingress de apps: sólo redes permitidas (LAN/VPN), por ejemplo:

      nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,192.168.0.0/24,192.168.4.0/24"
      
    • Evitar abrir 10.244.0.0/16. Si tu gateway VPN es un Pod y el Ingress ve IP de Pod, permitir sólo su /32 o mover la VPN a hostNetwork: true para usar IP estable del nodo.


Operación

Escalado y HA

  • deploy-coredns.yaml fija replicas: 2 con probes de liveness/readiness.
  • El Service LoadBalancer (UDP/TCP 53) anuncia 192.168.200.11 vía MetalLB.

Actualizar entradas

  1. Edita configmap-coredns.yaml (bloque hosts).
  2. kubectl -n coredns apply -f configmap-coredns.yaml.
  3. Verifica con consultas (ver abajo).

Reinicio controlado (si lo precisas)

kubectl -n coredns rollout restart deploy/coredns-custom
kubectl -n coredns rollout status deploy/coredns-custom

Métricas (opcional)

  • Descomenta la línea prometheus 0.0.0.0:9153 y expón un ServiceMonitor si usas Prometheus.

Pruebas y verificación

Resolución directa contra CoreDNS interno

# Desde un cliente en VPN/LAN
nslookup portal.apolo.c2et.net 192.168.200.11
nslookup admin.firewall.c2et.net 192.168.200.11

# o con dig
dig +short portal.apolo.c2et.net @192.168.200.11

Resultado esperado: portal.apolo.c2et.net192.168.200.10.

Camino por la VIP interna (SNI correcto)

curl -I https://portal.apolo.c2et.net \
  --resolve portal.apolo.c2et.net:443:192.168.200.10

Logs de CoreDNS e Ingress

# CoreDNS
kubectl -n coredns logs deploy/coredns-custom -f | grep -iE "error|timeout"

# Ingress (para ver IP origen preservada)
kubectl -n ingress-nginx logs -l app.kubernetes.io/name=ingress-nginx --tail=100

Mantenimiento y buenas prácticas

  • Versiona cambios en hosts y acompaña con una nota de por qué se enruta cada FQDN a cada VIP.
  • Mantén separadas las entradas internas (192.168.200.x) y las externas (192.168.0.100) para claridad.
  • Si la VPN está en Pods y rota IPs, considera moverla a hostNetwork: true o asignarle IP estática (Multus) para whitelistear un /32 estable en Ingress.
  • Revisa periódicamente que MetalLB siga anunciando 192.168.200.11 y que no haya conflictos ARP en la red.

Comandos útiles

# Aplicar todo
kubectl apply -k .

# Ver estado
kubectl -n coredns get pods -o wide
kubectl -n coredns get svc coredns-custom -o wide

# Probar resolución desde un Pod del clúster
kubectl -n coredns run -it --rm dnsutils --image=ghcr.io/k8s-at-home/dnsutils:latest -- sh -lc \
  "dig portal.apolo.c2et.net @192.168.200.11 +short"

Notas

  • Este CoreDNS no sustituye al CoreDNS del clúster para kubeservices; su objetivo es servir nombres internos de la organización y controlar el camino de acceso (VPN/LAN vs. Internet).
  • Si necesitas TTLs personalizados en respuestas estáticas, puedes extender el bloque hosts con opciones (TTL, etc.).