# CoreDNS dedicado para DNS interno / split‑horizon Este directorio contiene los manifiestos para desplegar un **CoreDNS propio** (namespace `coredns`) que sirve como **DNS interno** para resoluciones split‑horizon y control de rutas en la VPN (split‑tunnel). 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`. ```bash # 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`: ```coredns .: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 (split‑tunnel) 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. **Split‑horizon**: 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. **Ingress‑nginx** (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: ```yaml 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) ```bash 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 ```bash # 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.net` → `192.168.200.10`. ### Camino por la VIP interna (SNI correcto) ```bash curl -I https://portal.apolo.c2et.net \ --resolve portal.apolo.c2et.net:443:192.168.200.10 ``` ### Logs de CoreDNS e Ingress ```bash # 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 ```bash # 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 kube‑services; 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.).