actualizacion domingo

This commit is contained in:
2025-05-04 09:09:43 +00:00
parent 8ed2a07946
commit a4078ea882
26 changed files with 650 additions and 17 deletions

View File

@ -0,0 +1,16 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: dynu-updater
namespace: dynu-updater
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: dynu-updater
image: xavor/dynu-ip-client:2.1
imagePullPolicy: Always
restartPolicy: OnFailure

View File

@ -0,0 +1,3 @@
resources:
- namespace.yaml
- cronjob.yaml

View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: dynu-updater

119
k8s-dynu-updater/readme.md Normal file
View File

@ -0,0 +1,119 @@
# Dynu IP Updater en Kubernetes
Este proyecto despliega un cliente de Dynu personalizado como `CronJob` y `Job` en un clúster K3s/Kubernetes. Su función es mantener actualizada la dirección IP pública de un grupo de dominios gestionados en Dynu usando su API.
---
## 🚀 Características
* Imagen Docker ligera basada en Alpine.
* Actualiza la IP pública mediante peticiones HTTP a la API de Dynu.
* Guarda la IP anterior para evitar actualizaciones innecesarias.
* Ejecutado periódicamente mediante `CronJob` (cada 5 minutos).
* Puede ejecutarse manualmente mediante un `Job`.
* Los logs de ejecución se almacenan y pueden consultarse con `kubectl logs`.
---
## 🚜 Estructura de archivos
```
.
k8s-dynu-updater/
├── cronjob.yaml # CronJob de Kubernetes
├── job-manual.yaml # Job manual para pruebas
├── kustomization.yaml # Kustomize para despliegue
├── namespace.yaml # Namespace aislado para el updater
```
La imagen Docker utilizada se crea con el script `update.sh` incrustado, que:
1. Detecta la IP pública actual.
2. Comprueba si ha cambiado desde la última ejecución.
3. Llama a la API de Dynu con usuario, grupo y contraseña hash MD5.
---
## 📂 Despliegue
1. Aplicar los manifiestos:
```bash
cd k8s-dynu-updater
kubectl apply -k .
```
2. Comprobar el estado:
```bash
kubectl get pods -n dynu-updater
```
---
## ✅ Ejecución manual
Para probar el script sin esperar al cron:
```bash
kubectl apply -f job-manual.yaml
kubectl logs -n dynu-updater job/dynu-updater-manual
```
---
## ⚖️ Configuración del script
El script embebido en la imagen Docker:
```bash
USERNAME="xavor"
PASSWORD="M@nabo2025"
GROUP="ManaboValencia"
```
> La contraseña se convierte a hash MD5 antes de enviarla.
---
## 🚨 Seguridad
* La contraseña se envía como hash MD5.
* Se recomienda usar un "IP Update Password" diferente del de cuenta.
* Puedes montar `Secret` en Kubernetes para no incluir credenciales directamente en la imagen.
---
## 🔍 Logs en Dynu
Dynu registra las actualizaciones entrantes. Puedes ver líneas como:
```
/nic/update?username=xavor&group=manabovalencia&myip=62.15.155.254&myipv6=no&password=***** Good
```
Esto confirma que el pod ha funcionado correctamente.
---
## 🔍 Referencias
* Dynu IP Update Protocol: [https://www.dynu.com/DynamicDNS/IP-Update-Protocol](https://www.dynu.com/DynamicDNS/IP-Update-Protocol)
* API: `https://api.dynu.com/nic/update`
* Cliente basado en `curl` y `cron` en Alpine Linux
---
## 📅 Mantenimiento
* Se puede adaptar a otros grupos (por ejemplo: `ManaboTorrevieja`).
* Si se quiere logs persistentes, se puede montar un volumen.
* Si se quiere gestionar con ArgoCD, agregarlo como `Application`.
---
## 📄 Autor
Xavor (2025)
Este cliente se ha probado en K3s y Dynu, actualizando correctamente el grupo `ManaboValencia`.

View File

@ -12,7 +12,7 @@ spec:
ingressClassName: nginx
tls:
- hosts:
- espocrm.avgc.org
- espocrm.avgx.org
secretName: espocrm-tls
rules:
- host: espocrm.avgx.org

View File

@ -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 router.manabo.org;
location / {
proxy_pass https://192.168.1.1;
proxy_ssl_verify off;
}
}
ilo1.conf: |
server {
listen 80;
server_name ilo1.manabo.org;
location / {
proxy_pass https://192.168.0.4;
proxy_ssl_verify off;
}
}
ilo2.conf: |
server {
listen 80;
server_name ilo2.manabo.org;
location / {
proxy_pass https://192.168.0.5;
proxy_ssl_verify off;
}
}

View File

@ -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

View File

@ -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:
- router.manabo.org
secretName: router-tls
rules:
- host: router.manabo.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: external-router-svc
port:
number: 80

View File

@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- configmaps/configmap.yaml
- deployments/deployment.yaml
- services/service.yaml
- ingress/router.yaml

View File

@ -0,0 +1,5 @@
apiVersion: v1
kind: Namespace
metadata:
name: external

166
k8s-external/readme.md Normal file
View File

@ -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 (Lets 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 Lets 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.

View File

@ -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

View File

@ -0,0 +1,29 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: frigate-config
namespace: frigate
data:
config.yml: |
mqtt:
host: mqtt.c2et.com
user: frigate
password: muyseguro
detectors:
coral:
type: edgetpu
device: pci
cameras:
cam1:
ffmpeg:
inputs:
- path: rtsp://cam1.local/stream1
roles:
- detect
detect:
width: 1280
height: 720
fps: 5

View File

@ -0,0 +1,38 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: frigate
namespace: frigate
spec:
replicas: 1
selector:
matchLabels:
app: frigate
template:
metadata:
labels:
app: frigate
spec:
containers:
- name: frigate
image: blakeblackshear/frigate:stable
securityContext:
privileged: true
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media/frigate
- name: configmap-config
mountPath: /config/config.yml
subPath: config.yml
volumes:
- name: config
persistentVolumeClaim:
claimName: frigate-config
- name: media
persistentVolumeClaim:
claimName: frigate-media
- name: configmap-config
configMap:
name: frigate-config

View File

@ -0,0 +1,25 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frigate
namespace: frigate
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
rules:
- host: frigate.c2et.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frigate
port:
number: 5000
tls:
- hosts:
- frigate.c2et.com
secretName: frigate-tls

View File

@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- configmaps/configmap.yaml
- deployments/deployment.yaml
- ingress/ingress.yaml
- pvc/config-pvc.yaml
- pvc/media-pvc.yaml
- services/service.yaml

View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: frigate

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: frigate-config
namespace: frigate
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: frigate-media
namespace: frigate
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: frigate
namespace: frigate
spec:
type: ClusterIP
ports:
- port: 5000
targetPort: 5000
protocol: TCP
name: http
selector:
app: frigate

View File

@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dynu-updater
namespace: argocd
spec:
project: default
source:
repoURL: 'https://git.manabo.org/xavor/k8s-dynu-updater.git'
targetRevision: HEAD
path: .
destination:
server: 'https://kubernetes.default.svc'
namespace: dynu-updater
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: external
namespace: argocd
spec:
project: default
source:
repoURL: 'http://192.168.1.10:30300/xavor/k8s-external.git'
targetRevision: HEAD
path: .
destination:
server: 'https://kubernetes.default.svc'
namespace: external
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@ -0,0 +1,18 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: nextcloud-custom-config
namespace: nextcloud
data:
custom.config.php: |
<?php
$CONFIG = array (
'trusted_proxies' => ['10.42.0.0/16'],
'overwritehost' => 'nextcloud.manabo.org',
'overwriteprotocol' => 'https',
'overwrite.cli.url' => 'https://nextcloud.manabo.org',
'forwarded_for_headers' => ['HTTP_X_FORWARDED_FOR'],
'default_phone_region' => 'ES',
'maintenance_window_start' => 3,
'memcache.local' => '\\OC\\Memcache\\APCu',
);

View File

@ -14,7 +14,7 @@ spec:
spec:
containers:
- name: nextcloud
image: nextcloud:27
image: nextcloud:31
env:
- name: MYSQL_PASSWORD
value: nextcloud
@ -29,7 +29,13 @@ spec:
volumeMounts:
- mountPath: /var/www/html
name: nextcloud-storage
- mountPath: /var/www/html/config/custom.config.php
name: custom-config
subPath: custom.config.php
volumes:
- name: nextcloud-storage
persistentVolumeClaim:
claimName: nextcloud-pvc
claimName: nextcloud-pvc
- name: custom-config
configMap:
name: nextcloud-custom-config

View File

@ -6,20 +6,23 @@ metadata:
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/x-forwarded-prefix: "/"
spec:
ingressClassName: nginx
tls:
- hosts:
- nextcloud.manabo.org
secretName: nextcloud-tls
- hosts:
- nextcloud.manabo.org
secretName: nextcloud-tls
rules:
- host: nextcloud.manabo.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nextcloud
port:
number: 80
- host: nextcloud.manabo.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nextcloud
port:
number: 80

View File

@ -2,10 +2,11 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- configmap/nextcloud-custom-config.yaml
- deployments/mariadb.yaml
- deployments/nextcloud.yaml
- services/mariadb.yaml
- services/nextcloud.yaml
- pvc/mariadb-pvc.yaml
- pvc/nextcloud-pvc.yaml
- ingress/ingress.yaml
- ingress/ingress.yaml