Primer commit

This commit is contained in:
2025-04-27 00:26:25 +00:00
commit 6884e2e379
93 changed files with 3478 additions and 0 deletions

109
docs/arquitectura.md Normal file
View File

@ -0,0 +1,109 @@
# 🏗️ Arquitectura del clúster K3s
Este documento describe la arquitectura del clúster Kubernetes desplegado con K3s, su distribución de roles, y los componentes principales.
---
## 🧱 Nodos y roles
### 🖥️ tartaro (192.168.1.7)
- Rol: Control plane principal
- Prioridad Keepalived: MASTER
- Ejecuta:
- K3s (cluster-init)
- Ingress Controller
- cert-manager
- Gitea
- Argo CD
- App of Apps
- Guacamole
- KubeVirt Operator
- VS Code Server
- Servicios principales del clúster
---
### 🖥️ styx (192.168.1.8)
- Rol: Segundo nodo control plane
- Prioridad Keepalived: BACKUP
- Ejecuta:
- K3s (join al control plane)
- Ingress Controller (DaemonSet)
- Réplicas de servicios distribuidos
- Nodo tolerante a caída del master
---
### 🖥️ niflheim (192.168.1.10)
- Rol: Nodo dedicado a almacenamiento y tareas pesadas
- Taint: `storage=only:NoSchedule`
- Ejecuta:
- K3s (con taint para evitar pods no relacionados)
- ZFS + NFS server
- NFS client provisioner
- Volúmenes persistentes para el resto del clúster
- ISO server (para KubeVirt)
- Posibles futuras tareas de backup, observabilidad, etc.
---
## 🔁 Alta disponibilidad
Se implementa con:
- **Bonding de red**: Interfaz `bond0` en todos los nodos.
- **IP virtual (192.168.1.9)** gestionada por `keepalived`.
- Redirección de puertos 80/443 desde el router a esta IP.
- Ingress Controller desplegado como `DaemonSet` para disponibilidad inmediata en todos los nodos.
---
## 🧱 Almacenamiento
- **Backend principal**: ZFS pool `k8spool/k8s` montado en `/mnt/storage/k8s` (en niflheim).
- **NFS server** exporta este almacenamiento a todos los nodos.
- **nfs-subdir-external-provisioner** permite provisión dinámica de volúmenes desde Kubernetes.
---
## 🔐 TLS e Ingress
- **cert-manager** gestiona certificados con Let's Encrypt.
- **Ingress-NGINX** funciona como controlador de entrada.
- TLS completamente automatizado.
- Ingress de cada aplicación define el hostname correspondiente.
---
## 🌀 GitOps
- **Gitea** aloja todos los manifiestos como repositorios individuales.
- **Argo CD** sincroniza automáticamente los repositorios con el clúster.
- **App of Apps** en `k8s-master` gestiona la orquestación general.
---
## 🖥️ Virtualización
- **KubeVirt** permite ejecutar VMs dentro de Kubernetes.
- **CDI (Containerized Data Importer)** permite importar imágenes ISO.
- **ISO Server** expone imágenes desde NFS o HTTP.
- **Guacamole** permite acceso remoto vía navegador a VMs (VNC, RDP, SSH).
---
## 🔧 Herramientas de soporte
- **VS Code Server** accesible por navegador para edición remota en el clúster.
- **Scripts auxiliares** en la carpeta `docs/` para gestión de repositorios.
---
## 🧪 Recomendaciones
- Etiquetar nodos con `kubectl label node <node> <key>=<value>`
- Usar `taints` para separar roles claramente
- Separar StorageClass por aplicación si se desea control granular
- Automatizar despliegue con Argo CD y sincronización automática
---

60
docs/direccionamiento.md Normal file
View File

@ -0,0 +1,60 @@
# ⚔️ Valhalla Cluster - Homelab Personal (Infraestructura Actual)
## 📊 Tabla de Direccionamiento y VLANes
### 🌐 Segmentación por VLANes
| VLAN | Rango IP | Nombre | Uso principal |
|:-----|:-------------------|:-------------------|:--------------|
| VLAN 1 | 192.168.1.0/24 | Administración y acceso exterior | Gestión de infraestructura, acceso a Kubernetes, tráfico externo |
| VLAN 30 | 192.168.3.0/24 | Almacenamiento | Tráfico dedicado de almacenamiento NFS (sobre volúmenes ZFS replicados) |
| VLAN 40 | 192.168.4.0/24 | Tráfico Interno Kubernetes | Comunicación interna entre nodos Kubernetes (API Server, etcd, servicios internos) |
---
## 📡 Diseño de Red y Resolución de Nombres
- **Puerta de enlace principal**: 192.168.1.1 (Router Ubiquiti).
- **DNS interno**: CoreDNS desplegado en Kubernetes.
- **DNS externos**: Cloudflare (1.1.1.1) y Google (8.8.8.8).
- **Almacenamiento**: Exportado vía NFS desde Niflheim (ZFS RAID10), replicado a futuro hacia Gehena mediante `zfs send/receive`.
- **Alta Disponibilidad de Almacenamiento**: IP flotante `192.168.3.10` en VLAN 30 gestionada por Keepalived.
- **Alta Disponibilidad del Control Plane**: IP flotante `192.168.1.9` en VLAN 1 gestionada por Keepalived.
---
## 🧭 Tabla de Direccionamiento por Dispositivo
## 🧭 Tabla de Direccionamiento por Dispositivo
| Dispositivo | VLAN 1 (Admin/Acceso) | VLAN 30 (Storage) | VLAN 40 (Internode) | Observaciones |
|:----------------------------|:----------------------|:------------------|:--------------------|:--------------|
| Router Ubiquiti | 192.168.1.1 | — | — | Puerta de enlace principal |
| Switch QNAP 10GbE | 192.168.1.2 | — | — | Switch principal de 10Gbps |
| Switch MikroTik | 192.168.1.3 | — | — | Switch auxiliar / expansión |
| iLO de Niflheim | 192.168.1.4 | — | — | Gestión remota de servidor |
| iLO de Gehena | 192.168.1.5 | — | — | Gestión remota futuro nodo |
| IP Virtual Keepalived CP | 192.168.1.10 | — | — | IP flotante Kubernetes Control Plane |
| IP Virtual Keepalived Storage | — | 192.168.3.10 (planificado) | — | IP flotante almacenamiento NFS |
| Tartaro (Nodo Kubernetes) | 192.168.1.11 | 192.168.3.1 | 192.168.4.1 | Nodo K3s |
| Styx (Nodo Kubernetes) | 192.168.1.12 | 192.168.3.2 | 192.168.4.2 | Nodo K3s |
| Niflheim (Storage principal) | 192.168.1.13 | 192.168.3.3 | 192.168.4.3 | Nodo NFS + Provisioner K3s |
| Gehena (Futuro) | 192.168.1.14 (planificado) | 192.168.3.4 (planificado) | 192.168.4.4 (planificado) | Segundo nodo de almacenamiento |
| Respaldo Tartaro | 192.168.1.20 | — | — | Conexión alternativa de emergencia |
| Respaldo Styx | 192.168.1.21 | — | — | Conexión alternativa de emergencia |
| Respaldo Niflheim | 192.168.1.22 | — | — | Conexión alternativa de emergencia |
| Respaldo Gehena | 192.168.1.23 (planificado) | — | — | Conexión alternativa de emergencia |
---
## 🔒 Conclusiones
- **Separación total de tráfico**: tráfico de usuario/API Server, almacenamiento, y comunicación interna de nodos segregados en VLANs independientes.
- **Alta disponibilidad** en almacenamiento y control plane mediante Keepalived.
- **IP de emergencia configurada** en interfaces físicas sueltas (`enp87s0`) para Tartaro, Styx y Niflheim, asegurando acceso fuera del bonding en caso de fallo.
- **Almacenamiento NFS montado sobre ZFS RAID10 replicable** a futuro, asegurando integridad de datos y resiliencia de infraestructura.
- Preparado para expansión multi-site mediante VPN y replicación cruzada de almacenamiento.
---

469
docs/guia-instalacion.md Normal file
View File

@ -0,0 +1,469 @@
# 📘 Guía de instalación del clúster K3s - Valhalla Cluster
## 1. Instalar el sistema operativo
En los tres servidores:
- Configurar **bond0** como interfaz principal.
- Crear un **bridge `br0`** sobre `bond0` para tráfico sin NAT de VLAN 1 (administración y acceso).
- Montar **VLAN 30 (almacenamiento)** y **VLAN 40 (internode)**.
- Configurar **una interfaz de respaldo** (`enp88s0`, `eno1`, etc.) con IP secundaria en VLAN 1.
### Asignación de IPs principales:
| Nodo | VLAN 1 (Administración) | VLAN 30 (Storage) | VLAN 40 (Internode) |
|:-----------|:------------------------|:------------------|:--------------------|
| tartaro | 192.168.1.11 | 192.168.3.1 | 192.168.4.1 |
| styx | 192.168.1.12 | 192.168.3.2 | 192.168.4.2 |
| niflheim | 192.168.1.13 | 192.168.3.3 | 192.168.4.3 |
---
## 📄 Netplan para cada servidor
### Tartaro (`/etc/netplan/00-installer-config.yaml`):
```yaml
network:
version: 2
ethernets:
enp2s0f0np0: {}
enp2s0f1np1: {}
enp88s0:
addresses:
- "192.168.1.8/24"
bonds:
bond0:
interfaces:
- enp2s0f0np0
- enp2s0f1np1
parameters:
mode: "802.3ad"
lacp-rate: "fast"
transmit-hash-policy: "layer3+4"
vlans:
bond0.30:
id: 30
link: bond0
addresses:
- "192.168.3.1/24"
bond0.40:
id: 40
link: bond0
addresses:
- "192.168.4.1/24"
bridges:
br0:
interfaces:
- bond0
addresses:
- "192.168.1.11/24"
nameservers:
addresses:
- 192.168.1.1
- 1.1.1.1
- 8.8.8.8
search: []
routes:
- to: "default"
via: "192.168.1.1"
```
---
### Styx (`/etc/netplan/00-installer-config.yaml`):
```yaml
network:
version: 2
ethernets:
enp2s0f0np0: {}
enp2s0f1np1: {}
enp88s0:
addresses:
- "192.168.1.21/24"
bonds:
bond0:
interfaces:
- enp2s0f0np0
- enp2s0f1np1
parameters:
mode: "802.3ad"
lacp-rate: "fast"
transmit-hash-policy: "layer3+4"
vlans:
bond0.30:
id: 30
link: bond0
addresses:
- "192.168.3.2/24"
bond0.40:
id: 40
link: bond0
addresses:
- "192.168.4.2/24"
bridges:
br0:
interfaces:
- bond0
addresses:
- "192.168.1.12/24"
nameservers:
addresses:
- 192.168.1.1
- 1.1.1.1
- 8.8.8.8
search: []
routes:
- to: "default"
via: "192.168.1.1"
```
---
### Niflheim (`/etc/netplan/00-installer-config.yaml`):
```yaml
network:
version: 2
ethernets:
ens1f0: {}
ens1f1: {}
eno1:
addresses:
- "192.168.1.22/24"
bonds:
bond0:
interfaces:
- ens1f0
- ens1f1
parameters:
mode: "802.3ad"
lacp-rate: "fast"
transmit-hash-policy: "layer3+4"
vlans:
bond0.30:
id: 30
link: bond0
addresses:
- "192.168.3.3/24"
bond0.40:
id: 40
link: bond0
addresses:
- "192.168.4.3/24"
bridges:
br0:
interfaces:
- bond0
addresses:
- "192.168.1.13/24"
nameservers:
addresses:
- 192.168.1.1
- 1.1.1.1
- 8.8.8.8
search: []
routes:
- to: "default"
via: "192.168.1.1"
```
---
## 2. Preparación básica
En **todos los servidores**:
```bash
sudo apt update && sudo apt upgrade -y
sudo apt install -y keepalived nfs-common
```
> Asegúrate de tener los manifiestos clonados desde Gitea o preparados localmente antes de empezar.
---
## 2. Preparación básica
En **todos los servidores**:
```bash
sudo apt update && sudo apt upgrade -y
sudo apt install -y keepalived nfs-common
```
> Asegúrate de tener los manifiestos clonados desde Gitea o preparados localmente antes de empezar.
---
### Configuración de ZFS en `niflheim`
1. Instalar ZFS:
sudo apt install -y zfsutils-linux
2. Crear el pool ZFS con los 4 discos Toshiba (RAID10 con 2 espejos):
sudo zpool create -o ashift=12 k8spool \
mirror /dev/sda /dev/sdb \
mirror /dev/sdc /dev/sde
3. Crear dataset:
sudo zfs create k8spool/k8s
sudo zfs set mountpoint=/mnt/storage/k8s k8spool/k8s
sudo zfs set compression=lz4 k8spool/k8s
sudo chown nobody:nogroup /mnt/storage/k8s
4. Verificar:
sudo zpool status
sudo zfs list
sudo zfs get compression k8spool/k8s
---
## 3. Configuración de Keepalived
En tartaro (MASTER):
`sudo nano /etc/keepalived/keepalived.conf`
vrrp_instance VI_1 {
state MASTER
interface br0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 42manabo42
}
virtual_ipaddress {
192.168.1.10/24
}
}
En styx (BACKUP):
`sudo nano /etc/keepalived/keepalived.conf`
vrrp_instance VI_1 {
state BACKUP
interface br0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 42manabo42
}
virtual_ipaddress {
192.168.1.10/24
}
}
Después en ambos:
sudo systemctl enable keepalived
sudo systemctl start keepalived
## 4. Instalar K3s
En `tartaro` (control plane principal):
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--cluster-init --disable traefik \
--node-name tartaro \
--node-ip 192.168.4.1 \
--advertise-address 192.168.4.1 \
--tls-san 192.168.1.10 \
--tls-san 192.168.1.11 \
--write-kubeconfig-mode 644" sh -
Obtener token:
sudo cat /var/lib/rancher/k3s/server/node-token
En `styx` (segundo nodo):
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --disable traefik \
--node-name styx \
--node-ip 192.168.4.2 \
--advertise-address 192.168.4.2 \
--tls-san 192.168.1.10 \
--tls-san 192.168.1.12" \
K3S_URL=https://192.168.1.10:6443 \
K3S_TOKEN="token" \
sh -
En `niflheim` (control plane adicional, dedicado exclusivamente a almacenamiento):
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --disable traefik \
--node-name niflheim \
--node-ip 192.168.4.3 \
--advertise-address 192.168.4.3 \
--tls-san 192.168.1.10 \
--tls-san 192.168.1.13 \
--node-taint storage=only:NoSchedule" \
K3S_URL=https://192.168.1.10:6443 \
K3S_TOKEN="token" \
sh -
### Verificar estado del clúster
Desde tartaro (o con el kubeconfig copiado):
kubectl get nodes
En styx, niflheim para permitir acceso al kubeconfig:
sudo chmod 644 /etc/rancher/k3s/k3s.yaml
## 5. Instalar driver de almacenamiento.
En **Tartaro** (o en el nodo donde previamente hayamos clonado los repositorios):
cd ~/k3s/k8s-storage/
kubectl apply -k .
Comprobar:
kubectl get pods -n nfs-provisioner
## 6. Desplegar sistema automatizado de Ingress
### Redirección de puertos desde el router
- Hay que hacer port forwarding de puertos externos 80 y 443 a la IP virtual de Keepalived (192.168.1.9)
- El `NodePort` está configurado en el manifiesto como:
- 30080 → 80 (HTTP)
- 30443 → 443 (HTTPS)
- Por lo tanto la redireccion sera:
- de 80 a 192.168.1.9:30080
- de 443 a 192.168.1.9:30443
>Si necesitamos ver los puertos en uso podemos listarlos por la via rapida con el comando:
kubectl get svc --all-namespaces -o jsonpath="{range .items[*]}{.metadata.namespace}:{.metadata.name} → {.spec.ports[*].nodePort}{'\n'}{end}" | grep -v "→ $"
### Desplegar cert-manager
cd ~/k3s/k8s-cert-manager/
kubectl apply -f namespace.yaml
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
kubectl apply -f clusterissuer-staging.yaml
kubectl apply -f clusterissuer-prod.yaml
### Desplegar ingress-controller
cd ~/k3s/k8s-ingress-controller/
kubectl apply -k .
## 7. Desplegar Gitea manualmente
### En Tartaro (o en el nodo donde hayas copiado los repositorios)
cd ~/k3s/k8s-gitea/
kubectl apply -k .
Comprueba que los pods estén en estado `Running`:
kubectl get pods -n gitea -w
>Con acceso ya a gitea, seria el momento de crear todos los repositorios remotos. Es una buena idea apoyarnos en [git-publish](herramienta%20git-publish.md).
>Si tambien te has hartado de teclear git-publish, tambien tenemos un script para ti: [publicar-todos](herramienta%20publicar-todos.md)
## 8. Instalar ArgoCD
### En Tartaro (o donde tengamos los manifiestos locales clonados de Gitea)
cd ~/k3s/k8s-argocd/
kubectl apply -f namespace.yaml
# Instalar ArgoCD desde manifiesto oficial (26000 líneas aprox)
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl apply -f services/argocd.yaml
kubectl apply -f ingress/ingress.yaml
### Acceder
>Crear acceso en NPM es lo mas adecuado.
Se puede obtener la contraseña de admin con:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo
### Crear la App of Apps
En la interfaz web:
1. Name: app-of-apps (todo en minúsculas)
2. Project: default
3. Repository URL: el repositorio k8s-master en Gitea: https://git.manabo.org/xavor/k8s-master.git
4. Path: apps
5. Cluster URL: https://kubernetes.default.svc
6. Namespace: argocd
7. Sync policy: automática
8. Marca las casillas: `AUTO-CREATE NAMESPACE` `PRUNE` `SELF HEAL` `DIRECTORY RECURSE`
## 9. Instalar KubeVirt
export KUBEVIRT_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)
kubectl create namespace kubevirt
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-operator.yaml
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-cr.yaml
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml
export CDI_VERSION=$(curl -s https://api.github.com/repos/kubevirt/containerized-data-importer/releases/latest | grep tag_name | cut -d '"' -f 4)
kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-operator.yaml
kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/${CDI_VERSION}/cdi-cr.yaml
### Comprobar despliegue
kubectl get pods -n kubevirt
### Instalar virtctl (herramienta de cliente)
export KUBEVIRT_VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/virtctl-${KUBEVIRT_VERSION}-linux-amd64
chmod +x virtctl
sudo mv virtctl /usr/local/bin/
### 9.1 Configurar Multus y las redes virtuales
En cada nodo:
sudo rm -f /etc/cni/net.d/*
sudo find /etc/cni/net.d/ -type f -exec rm {} \;
sudo cp /var/lib/rancher/k3s/agent/etc/cni/net.d/10-flannel.conflist /etc/cni/net.d/
y en tartaro (o cualquier nodo)
kubectl -n kube-system delete pod -l app=multus
## 10. Desplegar servidor HTTP para ISOs (KubeVirt ISO Server)
cd ~/k3s/k8s-kubevirt-isoserver/
kubectl apply -k .
## 11. Desplegar Apache Guacamole
cd ~/k3s/k8s-guacamole/
kubectl apply -k .
>⚠️ Es necesario inyectar manualmente el esquema SQL de la base de datos tras el despliegue.
## Inyectar full-schema.sql
cd ~/k3s/k8s-guacamole/
kubectl cp full-schema.sql -n guacamole \
$(kubectl get pod -n guacamole -l app=mysql -o jsonpath="{.items[0].metadata.name}"):/full-schema.sql
kubectl exec -n guacamole deploy/mysql -- \
bash -c "mysql -u root -pguacroot guacamole_db < /full-schema.sql"
## Comprobación
kubectl exec -n guacamole deploy/mysql -it -- \
mysql -uguacuser -pguacpass -D guacamole_db -e \
"SELECT name FROM guacamole_entity WHERE type='USER';"
>Usuario/pass por defecto: ```guacadmin/guacadmin```

View File

@ -0,0 +1,52 @@
# git-bajartodos
📥 Descarga (`git pull`) los últimos cambios de todos los repositorios `k8s-*`.
## ¿Qué hace?
Este script entra en cada carpeta que empieza por `k8s-` y ejecuta `git pull`, trayendo los cambios remotos a tu copia local.
## 1. Crea el script
Copia este contenido en ~/bin/git-publish (crea la carpeta ~/bin si no existe):
#!/bin/bash
for dir in k8s-*; do
if [ -d "$dir/.git" ]; then
echo "📦 Entrando en $dir"
cd "$dir"
git pull
cd ..
fi
done
Hazlo ejecutable:
chmod +x ~/bin/git-bajartodos
## 2. Añade ~/bin a tu PATH si no lo tienes
Edita ~/.bashrc (o ~/.zshrc si usas Zsh) y añade:
export PATH="$HOME/bin:$PATH"
Y recarga:
source ~/.bashrc
## Uso
./git-bajartodos
## Requisitos
- Tener acceso al remoto (vía SSH o HTTPS).
- No tener conflictos sin resolver en el repositorio local.
## Ejemplo de salida
📦 Entrando en k8s-npm
Already up to date.
## Notas
- Si hay conflictos al hacer `pull`, Git te lo indicará y deberás resolverlos manualmente.
- Este script no sube nada, solo sincroniza **desde** el remoto. Para subir cambios locales, usa `git-subirtodos`.

View File

@ -0,0 +1,45 @@
# 🛠Creacion de herramienta git-childremove
Git-childremove es una herramienta para eliminar los git de las carpetas hijas
## 1. Crea el script
Copia este contenido en ~/bin/git-publish (crea la carpeta ~/bin si no existe):
#!/bin/bash
set -e
ENV_FILE="${HOME}/.gitpublish.env"
if [ ! -f "$ENV_FILE" ]; then
echo "Falta archivo .env en $ENV_FILE"
exit 1# 🛠Creacion de herramienta git-publish
Git-publish es una herramienta para automatizar la creacion y publicacion de repositorios
## 1. Crea el script
Copia este contenido en ~/bin/git-publish (crea la carpeta ~/bin si no existe):
#!/bin/bash
echo "🔍 Buscando carpetas .git en subdirectorios..."
find . -mindepth 2 -type d -name ".git" | while read gitdir; do
echo "🗑️ Eliminando $gitdir"
rm -rf "$gitdir"
done
echo "✅ Todas las carpetas .git han sido eliminadas."
Hazlo ejecutable:
chmod +x ~/bin/git-childremove
## 2. Añade ~/bin a tu PATH si no lo tienes
Edita ~/.bashrc (o ~/.zshrc si usas Zsh) y añade:
export PATH="$HOME/bin:$PATH"
Y recarga:
source ~/.bashrc

View File

@ -0,0 +1,79 @@
# 🛠Creacion de herramienta git-publish
Git-publish es una herramienta para automatizar la creacion y publicacion de repositorios
## 1. Crea el script
Copia este contenido en ~/bin/git-publish (crea la carpeta ~/bin si no existe):
#!/bin/bash
set -e
ENV_FILE="${HOME}/.gitpublish.env"
if [ ! -f "$ENV_FILE" ]; then
echo "Falta archivo .env en $ENV_FILE"
exit 1
fi
source "$ENV_FILE"
REPO_NAME=$(basename "$(pwd)")
REPO_DESC="${1:-Repositorio publicado desde script}"
API_URL="$GITEA_URL/api/v1/user/repos"
echo "Inicializando git..."
git init
git checkout -b main 2>/dev/null || git checkout main
git add .
git commit -m "Primer commit" || echo "(commit ya hecho)"
echo "Creando repo remoto $REPO_NAME en Gitea..."
REPO_EXISTS=$(curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_URL/api/v1/repos/$GITEA_USER/$REPO_NAME" | jq -r '.id // empty')
if [ -z "$REPO_EXISTS" ]; then
curl -s -X POST "$API_URL" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"name\": \"$REPO_NAME\", \"description\": \"$REPO_DESC\", \"private\": false}" \
> /dev/null
echo "Repositorio remoto creado."
else
echo "Repositorio remoto ya existe."
fi
echo "Subiendo código..."
git remote add origin "$GITEA_URL/$GITEA_USER/$REPO_NAME.git" 2>/dev/null || true
git push -u origin main
echo "✔️ Repo $REPO_NAME publicado en $GITEA_URL/$GITEA_USER/$REPO_NAME"
Hazlo ejecutable:
chmod +x ~/bin/git-publish
## 2. Añade ~/bin a tu PATH si no lo tienes
Edita ~/.bashrc (o ~/.zshrc si usas Zsh) y añade:
export PATH="$HOME/bin:$PATH"
Y recarga:
source ~/.bashrc
## 3. Crea tu .env
Archivo ~/.gitpublish.env: (crea y copia tu token en gitea)
GITEA_URL=https://git.manabo.org
GITEA_USER=xavor
GITEA_TOKEN=61a7abcb33ad7bf92454dd5a85c7bfe4becc41eb
## 4. Inicializa valores globales
git config --global user.email "xavor@hotmail.es"
git config --global user.name "xavor"
git config --global credential.helper store
### ✅ Y ahora sí: úsalo
cd ~/k3s/k8s-gitea
git-publish "Manifiestos de Gitea"

View File

@ -0,0 +1,67 @@
# git-subirtodos
🚀 Sube automáticamente todos los cambios locales a los repositorios `git` dentro de carpetas `k8s-*`.
### ¿Qué hace?
Este script busca todas las carpetas que empiecen por `k8s-`, detecta si hay cambios locales sin commitear, y si los hay:
1. Añade todos los cambios (`git add .`)
2. Hace un commit con un mensaje genérico
3. Ejecuta `git push` al remoto
## 1. Crea el script
Copia este contenido en ~/bin/git-publish (crea la carpeta ~/bin si no existe):
#!/bin/bash
for dir in k8s-*; do
if [ -d "$dir/.git" ]; then
echo "📦 Entrando en $dir"
cd "$dir"
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "✅ Cambios detectados en $dir. Haciendo commit y push..."
git add .
git commit -m "Actualización automática desde git-subirtodos"
git push
else
echo "⚠️ No hay cambios en $dir"
fi
cd ..
fi
done
Hazlo ejecutable:
chmod +x ~/bin/git-subirtodos
## 2. Añade ~/bin a tu PATH si no lo tienes
Edita ~/.bashrc (o ~/.zshrc si usas Zsh) y añade:
export PATH="$HOME/bin:$PATH"
Y recarga:
source ~/.bashrc
## Uso
./git-subirtodos
## Requisitos
- Tener permisos de escritura en todos los repositorios `k8s-*`.
- Estar en una rama con remoto configurado (`origin`).
- Tener acceso por SSH o con credenciales ya configuradas.
## Ejemplo de salida
tree
📦 Entrando en k8s-gitea
✅ Cambios detectados en k8s-gitea. Haciendo commit y push...
## Notas
- Si no hay cambios, el script te lo indicará.
- No se realiza `pull`, solo subida. Usa `git-bajartodos` si quieres sincronizar desde remoto.

View File

@ -0,0 +1,22 @@
# Script: publicar-todos.sh
Si no hay ganas de teclear todos los git-publish de todos los repositorios, guarda este script como ```publicar-todos.sh```
#!/bin/bash
# Recorre todas las carpetas que empiecen por k8s-
for dir in k8s-*; do
if [ -d "$dir" ]; then
echo "📦 Entrando en $dir"
cd "$dir"
git-publish "Manifiestos de ${dir}"
cd ..
fi
done
Y dale permisos de ejecucion
chmod +x publicar-todos.sh
Hazlo en la carpeta donde tengas los repositorios y subira todas las carpetas que empiecen por ```k8s-*``` con el comando:
./publicar-todos.sh

View File

@ -0,0 +1,74 @@
# 🛠️ Herramientas auxiliares
Esta sección recoge los scripts y utilidades que facilitan el trabajo con los repositorios Git del clúster, automatizando tareas como publicar, subir o clonar todos los manifiestos gestionados por Argo CD y Gitea.
---
## `git-publish`
Publica un repositorio local en Gitea automáticamente.
Crea el repositorio remoto (si no existe), hace `init`, `add`, `commit`, crea la rama `main` y hace `push`.
📝 Documentación: [`herramienta git-publish.md`](herramienta%20git-publish.md)
---
## `publicar-todos.sh`
Script que recorre todas las carpetas de servicios (`k8s-*`) y ejecuta `git-publish` en cada una de ellas.
Ideal para hacer el primer despliegue completo de manifiestos en Gitea.
📝 Documentación: [`herramienta publicar-todos.md`](herramienta%20publicar-todos.md)
---
## `git-subirtodos`
Hace `git add`, `commit` y `push` en todos los subrepositorios del clúster.
Útil cuando se ha trabajado localmente en varias apps y se quiere subir todo de golpe.
📝 Documentación: [`herramienta git-subirtodos.md`](herramienta%20git-subirtodos.md)
---
## `git-bajartodos`
Clona todos los repositorios hijos (servicios del clúster) desde Gitea.
Permite replicar rápidamente toda la estructura del clúster en un nuevo entorno de desarrollo.
📝 Documentación: [`herramienta git-bajartodos.md`](herramienta%20git-bajartodos.md)
---
## `git-chilremove`
Elimina todos los subrepositorios Git de carpetas hijas (útil para limpiar y reestructurar).
Requiere confirmación para evitar errores destructivos.
📝 Documentación: [`herramienta git-chilremove.md`](herramienta%20git-chilremove.md)
---
## Requisitos
- Token de Gitea guardado en `.env`
- Nombre de usuario y URL base configurados en los scripts
- Estructura de carpetas estándar (`k8s-*` con su `readme.md` y `kustomization.yaml`)
---
## Ejemplo de uso rápido
```bash
# Publicar todos los manifiestos como repos en Gitea
./publicar-todos.sh
# Hacer commit y push masivo
./docs/git-subirtodos.sh
# Clonar todos los servicios desde Gitea
./docs/git-bajartodos.sh

View File

@ -0,0 +1,83 @@
# 📚 Procedimientos adicionales
Aquí se documentan acciones puntuales que pueden ser necesarias durante el mantenimiento o despliegue del clúster, incluyendo soluciones a errores frecuentes o tareas manuales especiales.
---
## 🛠️ Eliminar namespace atascado (en terminación)
### ✅ Diagnóstico confirmado
Si ves un error como este:
...is forbidden: unable to create new content in namespace kubevirt-manager because it is being terminated
Significa que el namespace está atascado en estado de terminación y Kubernetes no puede limpiarlo correctamente.
---
### 🧹 Solución forzada paso a paso
#### 1. Exporta el namespace a un archivo
kubectl get namespace kubevirt-manager -o json > ns.json
#### 2. Edita el archivo ns.json
Abre el archivo con tu editor (nano, vim, code, etc.) y elimina la sección finalizers dentro de spec.
Ejemplo original:
"spec": {
"finalizers": [
"kubernetes"
]
}
Debes dejarlo así:
"spec": {}
Guarda y cierra el archivo.
#### 3. Aplica la eliminación forzada
kubectl replace --raw "/api/v1/namespaces/kubevirt-manager/finalize" -f ./ns.json
✅ Resultado esperado
El namespace kubevirt-manager desaparecerá en unos segundos.
Verifícalo con:
kubectl get ns
#### 4. Vuelve a aplicar los manifiestos si es necesario
kubectl apply -k .
## 📥 Copiar manualmente una ISO al servidor HTTP de KubeVirt
Este procedimiento permite subir manualmente una imagen `.iso` al servidor HTTP que sirve las ISOs en el namespace `kubevirt-isoserver`, para que pueda ser utilizada desde una VM en KubeVirt.
---
### ✅ 1. Identificar la ruta del PVC del servidor HTTP
Ejecuta:
kubectl -n kubevirt-isoserver get pvc
Salida
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
iso-pvc Bound pvc-169349e9-5e0c-4cb1-b7a5-8cd6ddc48be4 800Gi RWX nfs-manabo 17m
La carpeta real en el servidor de almacenamiento será algo como:
/mnt/storage/k8s/nfsshare/kubevirt-isoserver-iso-pvc-pvc-169349e9-5e0c-4cb1-b7a5-8cd6ddc48be4/
### 📤 2. Copiar la imagen desde el servidor origen
Estando en el servidor donde tienes la imagen .iso (ej. 192.168.1.3) y suponiendo que tienes acceso SSH al servidor de almacenamiento (192.168.1.10), ejecuta:
scp /mnt/Iso/Windows.iso xavor@192.168.1.10:/mnt/storage/k8s/nfsshare/kubevirt-isoserver-iso-pvc-pvc-169349e9-5e0c-4cb1-b7a5-8cd6ddc48be4/
Deberías ver el archivo Windows.iso.