From 663d6422fcca2490a9117d3cbc325c71c177b9ea Mon Sep 17 00:00:00 2001 From: xguefer Date: Fri, 22 Aug 2025 18:01:14 +0200 Subject: [PATCH] extraccion de DNS/ revision de ACLs --- {coredns => coredns-demo}/configmap.yaml | 0 {coredns => coredns-demo}/deployment.yaml | 0 coredns-demo/kustomization.yaml | 11 + coredns-demo/namespace.yaml | 4 + .../net-attach-def-admin.yaml | 0 .../net-attach-def-srv.yaml | 0 coredns-demo/readme.md | 168 +++++++++ .../configmap-coredns.yaml | 10 +- .../deploy-coredns.yaml | 2 +- coredns/kustomization.yaml | 9 +- coredns/namespace.yaml | 2 +- coredns/readme.md | 326 ++++++++++-------- {apolo/services => coredns}/svc-coredns.yaml | 2 +- dashboard/ingress/ingress.yaml | 1 + external/configmaps/configmap.yaml | 35 ++ external/deployments/deployment.yaml | 25 ++ external/ingress/firewall.yaml | 28 ++ external/ingress/powervault1.yaml | 28 ++ external/ingress/powervault2.yaml | 28 ++ external/ingress/router.yaml.save | 27 ++ external/kustomization.yaml | 12 + external/namespace.yaml | 5 + external/readme.md | 166 +++++++++ external/services/service.yaml | 11 + guacamole/ingress/ingress.yaml | 1 + ingress-nginx/services/service.yaml | 1 + readme.md | 6 +- rook/ingress/dashboard.yaml | 1 + 28 files changed, 755 insertions(+), 154 deletions(-) rename {coredns => coredns-demo}/configmap.yaml (100%) rename {coredns => coredns-demo}/deployment.yaml (100%) create mode 100644 coredns-demo/kustomization.yaml create mode 100644 coredns-demo/namespace.yaml rename {coredns => coredns-demo}/net-attach-def-admin.yaml (100%) rename {coredns => coredns-demo}/net-attach-def-srv.yaml (100%) create mode 100644 coredns-demo/readme.md rename {apolo/configmaps => coredns}/configmap-coredns.yaml (73%) rename {apolo/deployments => coredns}/deploy-coredns.yaml (98%) rename {apolo/services => coredns}/svc-coredns.yaml (93%) create mode 100644 external/configmaps/configmap.yaml create mode 100644 external/deployments/deployment.yaml create mode 100644 external/ingress/firewall.yaml create mode 100644 external/ingress/powervault1.yaml create mode 100644 external/ingress/powervault2.yaml create mode 100644 external/ingress/router.yaml.save create mode 100644 external/kustomization.yaml create mode 100644 external/namespace.yaml create mode 100644 external/readme.md create mode 100644 external/services/service.yaml diff --git a/coredns/configmap.yaml b/coredns-demo/configmap.yaml similarity index 100% rename from coredns/configmap.yaml rename to coredns-demo/configmap.yaml diff --git a/coredns/deployment.yaml b/coredns-demo/deployment.yaml similarity index 100% rename from coredns/deployment.yaml rename to coredns-demo/deployment.yaml diff --git a/coredns-demo/kustomization.yaml b/coredns-demo/kustomization.yaml new file mode 100644 index 0000000..b20aad6 --- /dev/null +++ b/coredns-demo/kustomization.yaml @@ -0,0 +1,11 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: coredns-multus + +resources: + - namespace.yaml + - configmap.yaml + - deployment.yaml + - net-attach-def-admin.yaml + - net-attach-def-srv.yaml diff --git a/coredns-demo/namespace.yaml b/coredns-demo/namespace.yaml new file mode 100644 index 0000000..c1eefa3 --- /dev/null +++ b/coredns-demo/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: coredns-multus diff --git a/coredns/net-attach-def-admin.yaml b/coredns-demo/net-attach-def-admin.yaml similarity index 100% rename from coredns/net-attach-def-admin.yaml rename to coredns-demo/net-attach-def-admin.yaml diff --git a/coredns/net-attach-def-srv.yaml b/coredns-demo/net-attach-def-srv.yaml similarity index 100% rename from coredns/net-attach-def-srv.yaml rename to coredns-demo/net-attach-def-srv.yaml diff --git a/coredns-demo/readme.md b/coredns-demo/readme.md new file mode 100644 index 0000000..b8dd853 --- /dev/null +++ b/coredns-demo/readme.md @@ -0,0 +1,168 @@ +# CoreDNS con Multus: README de Configuración + +Este documento explica cómo desplegar un pod de CoreDNS en Kubernetes con **Multus CNI** para conectarlo a dos redes físicas (bridges) distintas, asignándole una dirección IP en cada una, y usando `hostNetwork` para exponer el servicio DNS de forma estándar en el host. + +--- + +## Objetivo + +* Desplegar CoreDNS con: + + * IP 192.168.1.100/24 en la red **br-admin** + * IP 192.168.200.100/22 en la red **br-srv** +* Utilizar `hostNetwork: true` para que CoreDNS escuche en el puerto 53 real del host +* Añadir un sidecar de herramientas para inspección de red + +--- + +## ¿Por qué Multus? + +* Kubernetes estándar solo permite una interfaz por pod (la principal). +* Multus permite añadir interfaces **adicionales**, conectando el pod a varias redes físicas (como bridges de Linux). +* En este caso, usamos Multus para asignar a CoreDNS dos IPs fijas en dos bridges diferentes, actuando como DNS en ambas redes. + +--- + +## Componentes principales + +1. **NetworkAttachmentDefinition** para cada bridge físico: + + * `br-admin` (192.168.1.0/24) + * `br-srv` (192.168.200.0/22) +2. **ConfigMap** con el `Corefile` (configuración de CoreDNS) +3. **Pod** con: + + * `hostNetwork: true` + * Anotación Multus para conectar ambas redes + * Sidecar de utilidades (`busybox`) + +--- + +## Paso a paso + +### 1. NetworkAttachmentDefinition + +Define una NetworkAttachmentDefinition por red, ejemplo: + +`br-admin.yaml`: + +```yaml +apiVersion: "k8s.cni.cncf.io/v1" +kind: NetworkAttachmentDefinition +metadata: + name: br-admin + namespace: coredns-multus +spec: + config: '{ + "cniVersion": "0.3.1", + "type": "bridge", + "bridge": "br-admin", + "ipam": { + "type": "static", + "addresses": [ + { + "address": "192.168.1.100/24", + "gateway": "192.168.1.1" + } + ] + } + }' +``` + +`br-srv.yaml` igual, cambiando nombre y dirección IP. + +--- + +### 2. ConfigMap con Corefile + +Ejemplo: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: coredns-config + namespace: coredns-multus +data: + Corefile: | + .:53 { + log + errors + forward . 8.8.8.8 + cache 30 + } +``` + +--- + +### 3. Pod con Multus y sidecar de utilidades + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: coredns-multus + namespace: coredns-multus + annotations: + k8s.v1.cni.cncf.io/networks: | + [ + { "name": "br-admin", "namespace": "coredns-multus" }, + { "name": "br-srv", "namespace": "coredns-multus" } + ] +spec: + hostNetwork: true + containers: + - name: coredns + image: coredns/coredns:1.11.1 + volumeMounts: + - name: config-volume + mountPath: /etc/coredns/Corefile + subPath: Corefile + ports: + - containerPort: 53 + protocol: UDP + - containerPort: 53 + protocol: TCP + - name: tools + image: busybox + command: [ "sleep", "infinity" ] + volumes: + - name: config-volume + configMap: + name: coredns-config + tolerations: + - operator: "Exists" + dnsPolicy: "Default" +``` + +--- +## Comprobación de las interfaces + +Desplegar: +```sh +kubectl apply -k . #<-- (hay un kustomization en la carpeta coredns del repositorio) +``` +--- +## Comprobación de las interfaces + +Para ver las interfaces asignadas por Multus: + +```sh +kubectl -n coredns-multus exec -it coredns-multus -c tools -- ip a +``` + +Deberías ver: + +* La interfaz principal (del host, por `hostNetwork`) +* Una interfaz extra con IP 192.168.1.100 +* Otra interfaz extra con IP 192.168.200.100 + +--- + +## Notas importantes + +* `hostNetwork: true` expone el puerto 53 real en el host. +* La IP principal será la del host, las secundarias las de Multus. +* Puedes poner el pod en modo Deployment para alta disponibilidad, pero solo una instancia por host con `hostNetwork: true`. +* El sidecar puede eliminarse después de la verificación, no es necesario para producción. + diff --git a/apolo/configmaps/configmap-coredns.yaml b/coredns/configmap-coredns.yaml similarity index 73% rename from apolo/configmaps/configmap-coredns.yaml rename to coredns/configmap-coredns.yaml index f4e5657..ff2ec59 100644 --- a/apolo/configmaps/configmap-coredns.yaml +++ b/coredns/configmap-coredns.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: coredns-custom - namespace: apolo + namespace: coredns data: Corefile: | .:53 { @@ -11,6 +11,7 @@ data: health reload hosts { + # === APOLO (GPS tactico) === 192.168.200.10 backend.apolo.c2et.net 192.168.200.10 portal.apolo.c2et.net 192.168.200.10 colossus.apolo.c2et.net @@ -25,6 +26,13 @@ data: 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 diff --git a/apolo/deployments/deploy-coredns.yaml b/coredns/deploy-coredns.yaml similarity index 98% rename from apolo/deployments/deploy-coredns.yaml rename to coredns/deploy-coredns.yaml index da72c4c..1d5d97a 100644 --- a/apolo/deployments/deploy-coredns.yaml +++ b/coredns/deploy-coredns.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: coredns-custom - namespace: apolo + namespace: coredns labels: app: coredns-custom spec: diff --git a/coredns/kustomization.yaml b/coredns/kustomization.yaml index b20aad6..a8a7590 100644 --- a/coredns/kustomization.yaml +++ b/coredns/kustomization.yaml @@ -1,11 +1,10 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -namespace: coredns-multus +namespace: coredns resources: - namespace.yaml - - configmap.yaml - - deployment.yaml - - net-attach-def-admin.yaml - - net-attach-def-srv.yaml + - configmap-coredns.yaml + - deploy-coredns.yaml + - svc-coredns.yaml diff --git a/coredns/namespace.yaml b/coredns/namespace.yaml index c1eefa3..4caff58 100644 --- a/coredns/namespace.yaml +++ b/coredns/namespace.yaml @@ -1,4 +1,4 @@ apiVersion: v1 kind: Namespace metadata: - name: coredns-multus + name: coredns diff --git a/coredns/readme.md b/coredns/readme.md index b8dd853..7ded196 100644 --- a/coredns/readme.md +++ b/coredns/readme.md @@ -1,168 +1,208 @@ -# CoreDNS con Multus: README de Configuración +# CoreDNS dedicado para DNS interno / split‑horizon -Este documento explica cómo desplegar un pod de CoreDNS en Kubernetes con **Multus CNI** para conectarlo a dos redes físicas (bridges) distintas, asignándole una dirección IP en cada una, y usando `hostNetwork` para exponer el servicio DNS de forma estándar en el host. +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`). --- -## Objetivo +## Estructura -* Desplegar CoreDNS con: - - * IP 192.168.1.100/24 en la red **br-admin** - * IP 192.168.200.100/22 en la red **br-srv** -* Utilizar `hostNetwork: true` para que CoreDNS escuche en el puerto 53 real del host -* Añadir un sidecar de herramientas para inspección de red - ---- - -## ¿Por qué Multus? - -* Kubernetes estándar solo permite una interfaz por pod (la principal). -* Multus permite añadir interfaces **adicionales**, conectando el pod a varias redes físicas (como bridges de Linux). -* En este caso, usamos Multus para asignar a CoreDNS dos IPs fijas en dos bridges diferentes, actuando como DNS en ambas redes. - ---- - -## Componentes principales - -1. **NetworkAttachmentDefinition** para cada bridge físico: - - * `br-admin` (192.168.1.0/24) - * `br-srv` (192.168.200.0/22) -2. **ConfigMap** con el `Corefile` (configuración de CoreDNS) -3. **Pod** con: - - * `hostNetwork: true` - * Anotación Multus para conectar ambas redes - * Sidecar de utilidades (`busybox`) - ---- - -## Paso a paso - -### 1. NetworkAttachmentDefinition - -Define una NetworkAttachmentDefinition por red, ejemplo: - -`br-admin.yaml`: - -```yaml -apiVersion: "k8s.cni.cncf.io/v1" -kind: NetworkAttachmentDefinition -metadata: - name: br-admin - namespace: coredns-multus -spec: - config: '{ - "cniVersion": "0.3.1", - "type": "bridge", - "bridge": "br-admin", - "ipam": { - "type": "static", - "addresses": [ - { - "address": "192.168.1.100/24", - "gateway": "192.168.1.1" - } - ] - } - }' ``` - -`br-srv.yaml` igual, cambiando nombre y dirección IP. - ---- - -### 2. ConfigMap con Corefile - -Ejemplo: - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: coredns-config - namespace: coredns-multus -data: - Corefile: | - .:53 { - log - errors - forward . 8.8.8.8 - cache 30 - } +./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 ``` --- -### 3. Pod con Multus y sidecar de utilidades +## Despliegue -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: coredns-multus - namespace: coredns-multus - annotations: - k8s.v1.cni.cncf.io/networks: | - [ - { "name": "br-admin", "namespace": "coredns-multus" }, - { "name": "br-srv", "namespace": "coredns-multus" } - ] -spec: - hostNetwork: true - containers: - - name: coredns - image: coredns/coredns:1.11.1 - volumeMounts: - - name: config-volume - mountPath: /etc/coredns/Corefile - subPath: Corefile - ports: - - containerPort: 53 - protocol: UDP - - containerPort: 53 - protocol: TCP - - name: tools - image: busybox - command: [ "sleep", "infinity" ] - volumes: - - name: config-volume - configMap: - name: coredns-config - tolerations: - - operator: "Exists" - dnsPolicy: "Default" +> 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 ``` --- -## Comprobación de las interfaces -Desplegar: -```sh -kubectl apply -k . #<-- (hay un kustomization en la carpeta coredns del repositorio) -``` ---- -## Comprobación de las interfaces +## Configuración (Corefile) -Para ver las interfaces asignadas por Multus: +El Corefile se define en `configmap-coredns.yaml`: -```sh -kubectl -n coredns-multus exec -it coredns-multus -c tools -- ip a +```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 +} ``` -Deberías ver: +### Puntos clave -* La interfaz principal (del host, por `hostNetwork`) -* Una interfaz extra con IP 192.168.1.100 -* Otra interfaz extra con IP 192.168.200.100 +* **`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. --- -## Notas importantes +## Integración con la VPN (split‑tunnel) -* `hostNetwork: true` expone el puerto 53 real en el host. -* La IP principal será la del host, las secundarias las de Multus. -* Puedes poner el pod en modo Deployment para alta disponibilidad, pero solo una instancia por host con `hostNetwork: true`. -* El sidecar puede eliminarse después de la verificación, no es necesario para producción. +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.). diff --git a/apolo/services/svc-coredns.yaml b/coredns/svc-coredns.yaml similarity index 93% rename from apolo/services/svc-coredns.yaml rename to coredns/svc-coredns.yaml index 51f6f40..2c3a21a 100644 --- a/apolo/services/svc-coredns.yaml +++ b/coredns/svc-coredns.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: name: coredns-custom - namespace: apolo + namespace: coredns spec: type: LoadBalancer loadBalancerIP: 192.168.200.11 diff --git a/dashboard/ingress/ingress.yaml b/dashboard/ingress/ingress.yaml index 9254628..5f6a1fc 100644 --- a/dashboard/ingress/ingress.yaml +++ b/dashboard/ingress/ingress.yaml @@ -7,6 +7,7 @@ metadata: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" # el pod escucha TLS en 8443 nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # redirige http -> https + nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,192.168.0.0/24,10.244.0.0/16,192.168.4.0/24" spec: ingressClassName: nginx tls: diff --git a/external/configmaps/configmap.yaml b/external/configmaps/configmap.yaml new file mode 100644 index 0000000..e73e117 --- /dev/null +++ b/external/configmaps/configmap.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-router-config + namespace: external +data: + router.conf: | + server { + listen 80 default_server; + server_name admin.firewall.c2et.net; + location / { + proxy_pass https://192.168.0.1; + proxy_ssl_verify off; + } + } + + powervault1.conf: | + server { + listen 80; + server_name admin.powervault1.c2et.net; + location / { + proxy_pass https://192.168.0.71; + proxy_ssl_verify off; + } + } + + powervault2.conf: | + server { + listen 80; + server_name admin.powervault2.c2et.net; + location / { + proxy_pass https://192.168.0.74; + proxy_ssl_verify off; + } + } diff --git a/external/deployments/deployment.yaml b/external/deployments/deployment.yaml new file mode 100644 index 0000000..e10c0d0 --- /dev/null +++ b/external/deployments/deployment.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: external-router-proxy + namespace: external +spec: + replicas: 1 + selector: + matchLabels: + app: router-proxy + template: + metadata: + labels: + app: router-proxy + spec: + containers: + - name: nginx + image: nginx:alpine + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/conf.d + volumes: + - name: nginx-config + configMap: + name: nginx-router-config diff --git a/external/ingress/firewall.yaml b/external/ingress/firewall.yaml new file mode 100644 index 0000000..2cabf03 --- /dev/null +++ b/external/ingress/firewall.yaml @@ -0,0 +1,28 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: firewall-ingress + namespace: external + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/backend-protocol: "HTTP" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,192.168.0.0/24,10.244.0.0/16,192.168.4.0/24" +spec: + ingressClassName: nginx + tls: + - hosts: + - admin.firewall.c2et.net + secretName: firewall-tls + rules: + - host: admin.firewall.c2et.net + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: external-router-svc + port: + number: 80 diff --git a/external/ingress/powervault1.yaml b/external/ingress/powervault1.yaml new file mode 100644 index 0000000..fb68d70 --- /dev/null +++ b/external/ingress/powervault1.yaml @@ -0,0 +1,28 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: powervault1-ingress + namespace: external + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/backend-protocol: "HTTP" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,192.168.0.0/24,10.244.0.0/16,192.168.4.0/24" +spec: + ingressClassName: nginx + tls: + - hosts: + - admin.powervault1.c2et.net + secretName: powervault1-tls + rules: + - host: admin.powervault1.c2et.net + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: external-router-svc + port: + number: 80 diff --git a/external/ingress/powervault2.yaml b/external/ingress/powervault2.yaml new file mode 100644 index 0000000..278ca97 --- /dev/null +++ b/external/ingress/powervault2.yaml @@ -0,0 +1,28 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: powervault2-ingress + namespace: external + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/backend-protocol: "HTTP" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,192.168.0.0/24,10.244.0.0/16,192.168.4.0/24" +spec: + ingressClassName: nginx + tls: + - hosts: + - admin.powervault2.c2et.net + secretName: powervault2-tls + rules: + - host: admin.powervault2.c2et.net + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: external-router-svc + port: + number: 80 diff --git a/external/ingress/router.yaml.save b/external/ingress/router.yaml.save new file mode 100644 index 0000000..2aa387f --- /dev/null +++ b/external/ingress/router.yaml.save @@ -0,0 +1,27 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: router-ingress + namespace: external + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/backend-protocol: "HTTP" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" +spec: + ingressClassName: nginx + tls: + - hosts: + - firewall.c2et.net + secretName: router-tls + rules: + - host: firewall.c2et.net + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: external-router-svc + port: + number: 80 diff --git a/external/kustomization.yaml b/external/kustomization.yaml new file mode 100644 index 0000000..d9e4065 --- /dev/null +++ b/external/kustomization.yaml @@ -0,0 +1,12 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - namespace.yaml + - configmaps/configmap.yaml + - deployments/deployment.yaml + - services/service.yaml + - ingress/firewall.yaml + - ingress/powervault1.yaml + - ingress/powervault2.yaml + diff --git a/external/namespace.yaml b/external/namespace.yaml new file mode 100644 index 0000000..d136e54 --- /dev/null +++ b/external/namespace.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: external + diff --git a/external/readme.md b/external/readme.md new file mode 100644 index 0000000..b707a32 --- /dev/null +++ b/external/readme.md @@ -0,0 +1,166 @@ +# 🌐 k8s-external-router + +Este proyecto despliega un proxy inverso en Kubernetes que permite acceder a dispositivos o servicios externos (fuera del clúster) mediante dominios públicos gestionados con TLS, a través de NGINX y cert-manager. + +## 📝 Componentes + +* **Deployment**: contenedor `nginx:alpine` que actúa como proxy. +* **ConfigMap**: define los proxies en archivos `.conf` cargados en `/etc/nginx/conf.d`. +* **Service**: expone el contenedor internamente en el clúster. +* **Ingress**: gestiona el acceso externo con certificados TLS (Let’s Encrypt). + +## 💠 Estructura del proyecto + +```bash +k8s-external/ +├── configmaps/ +│ └── configmap.yaml # Configuración de NGINX +├── deployments/ +│ └── deployment.yaml # Proxy con hostNetwork +├── services/ +│ └── service.yaml # Service interno +├── ingress/ +│ └── router.yaml # Ingress TLS público +``` + +## 🚀 Despliegue + +1. Aplica todos los recursos: + +```bash +kubectl apply -k . +``` + +> Asegúrate de que tu clúster ya tenga: +> +> * `cert-manager` instalado. +> * Un `ClusterIssuer` llamado `letsencrypt-prod`. +> * Un controlador Ingress funcionando (por ejemplo, `nginx`). + +2. Reinicia el deployment para recargar cambios del `ConfigMap`: + +```bash +kubectl rollout restart deployment external-router-proxy -n external +``` + +--- + +## ➕ Añadir un nuevo proxy + +Para añadir un nuevo dominio que apunte a una IP externa: + +### 1. Edita el `ConfigMap` + +```yaml + switch.conf: | + server { + listen 80; + server_name switch.manabo.org; + location / { + proxy_pass https://192.168.0.100; + proxy_ssl_verify off; + } + } +``` + +> Guarda el archivo como `configmaps/configmap.yaml`. + +### 2. Aplica el nuevo `ConfigMap` y reinicia el deployment + +```bash +kubectl apply -f configmaps/configmap.yaml +kubectl rollout restart deployment external-router-proxy -n external +``` + +### 3. Crea un nuevo `Ingress` + +Guarda este archivo en `ingress/switch.yaml`: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: switch-ingress + namespace: external + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" +spec: + ingressClassName: nginx + tls: + - hosts: + - switch.manabo.org + secretName: switch-tls + rules: + - host: switch.manabo.org + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: external-router-svc + port: + number: 80 +``` + +Y aplícalo: + +```bash +kubectl apply -f ingress/switch.yaml +``` + +--- + +## 🔍 Verificación + +* Verifica que el pod proxy esté funcionando: + +```bash +kubectl get pods -n external +``` + +* Verifica que el endpoint externo responde desde dentro del contenedor: + +```bash +kubectl exec -n external deploy/external-router-proxy -- curl -k https://192.168.X.X +``` + +* Verifica que el dominio esté expuesto correctamente: + +```bash +curl -k https://switch.manabo.org +``` + +--- + +## 🔐 Seguridad + +* Los proxys usan certificados TLS automáticos con Let’s Encrypt. +* La verificación de certificados en el `proxy_pass` está desactivada (`proxy_ssl_verify off`) para permitir certificados autofirmados de los dispositivos. + +--- + +## 🗜 Limpieza + +Para eliminar un proxy: + +1. Borra la entrada del `ConfigMap`. +2. Borra el `Ingress` correspondiente: + +```bash +kubectl delete ingress switch-ingress -n external +``` + +3. Vuelve a aplicar y reiniciar: + +```bash +kubectl apply -f configmaps/configmap.yaml +kubectl rollout restart deployment external-router-proxy -n external +``` + +--- + +## ✨ Créditos + +Mantenido por [Xavor](https://manabo.org) — Kubernetes DevOps Homelab. diff --git a/external/services/service.yaml b/external/services/service.yaml new file mode 100644 index 0000000..e6c09ca --- /dev/null +++ b/external/services/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: external-router-svc + namespace: external +spec: + selector: + app: router-proxy + ports: + - port: 80 + targetPort: 80 diff --git a/guacamole/ingress/ingress.yaml b/guacamole/ingress/ingress.yaml index a24493d..4916ad9 100644 --- a/guacamole/ingress/ingress.yaml +++ b/guacamole/ingress/ingress.yaml @@ -9,6 +9,7 @@ metadata: nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/backend-protocol: "HTTP" nginx.ingress.kubernetes.io/enable-websockets: "true" + nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,192.168.0.0/24,10.244.0.0/16,192.168.4.0/24" spec: ingressClassName: nginx tls: diff --git a/ingress-nginx/services/service.yaml b/ingress-nginx/services/service.yaml index 62b2614..63bb082 100644 --- a/ingress-nginx/services/service.yaml +++ b/ingress-nginx/services/service.yaml @@ -6,6 +6,7 @@ metadata: spec: type: LoadBalancer loadBalancerIP: 192.168.0.100 + externalTrafficPolicy: Local selector: app.kubernetes.io/name: ingress-nginx ports: diff --git a/readme.md b/readme.md index 5516c7b..f29e75c 100644 --- a/readme.md +++ b/readme.md @@ -17,10 +17,11 @@ Este repositorio contiene los **manifiestos, scripts y documentación** para des | `vm-windows-demo\readme.md` | Maquina virtual de ejemplo | [Ver](./vm-windows-demo/readme.md) | | `comprobaciones.md` | Checklist y pruebas tras cada paso crítico | [Ver](./comprobaciones.md) | | `script_limpieza.md` | Como hacer un script para eliminar la configuracion de un nodo | [Ver](script_limpieza.md) | -| `coredns\readme.md` | Ejemplo de Multus: CoreDNS | [Ver](./coredns/readme.md) | +| `coredns-demo\readme.md` | Ejemplo de Multus: CoreDNS | [Ver](./coredns-demo/readme.md) | | `storage\readme.md` | Ejemplo de recurso “class”: storage | [Ver](./storage/readme.md) | | `dashboard\readme.md` | Ejemplo con un ingress: k8s dashboard | [Ver](./dashboard/readme.md) | | `wireguard\readme.md` | Manual de instalación de Wireguard | [Ver](./wireguard/readme.md) | +| `coredns\readme.md` | Configuracion del DNS del sistema | [Ver](./coredns/readme.md) | | `apolo\readme.md` | Manual de instalación de Apolo | [Ver](./apolo/readme.md) | | `gitea\readme.md` | Manual de instalación de Gitea | [Ver](./gitea/readme.md) | | `guacamole\readme.md` | Manual de instalación de Guacamole | [Ver](./guacamole/readme.md) | @@ -41,7 +42,8 @@ Este repositorio contiene los **manifiestos, scripts y documentación** para des | `Volumenes persistentes` | ✅ Completado | Rook Ceph a 4 nodos, falta ampliar a 5 nodos |https://ceph.c2et.net/ |admin / Pozuelo12345 | | `Maquinas Virtuales` | ✅ Completado | Desplegado kubevirt, dashboard e isoserver |https://kubevirt.c2et.net/ https://isoserver.c2et.net/ |- | | `Wireguard` | ✅ Completado | Funcionando |https://wireguard.c2et.net/ | Pozuelo12345 | -| `Apolo` | ✅ Completado | Funcionando |https://portal.apolo.c2et.net/ (solo VPN) | admin / 123456 | +| `CoreDNS` | ✅ Completado | Funcionando | | | +| `Apolo` | ✅ Completado | Funcionando |https://portal.apolo.c2et.net/ | admin / 123456 | | `Gitea` | ✅ Completado | Funcionando |https://git.c2et.net/ | | | `Harbor` | ✅ Completado | Funcionando |https://harbor.c2et.net/ | | | `Guacamole` | ✅ Completado | Funcionando |https://heimdall.c2et.net/ | | diff --git a/rook/ingress/dashboard.yaml b/rook/ingress/dashboard.yaml index 06e6d1b..7650b51 100644 --- a/rook/ingress/dashboard.yaml +++ b/rook/ingress/dashboard.yaml @@ -6,6 +6,7 @@ metadata: annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,192.168.0.0/24,10.244.0.0/16,192.168.4.0/24" spec: ingressClassName: nginx tls: