añadido driver seagate

This commit is contained in:
2025-08-26 22:00:11 +02:00
parent fc3640f5e6
commit 33aced03a0
11 changed files with 489 additions and 0 deletions

316
seagate/readme.md Normal file
View File

@@ -0,0 +1,316 @@
# Seagate Exos X CSI (ME5 dualsite) — Guía de instalación y operación
Este README documenta cómo he dejado **reproducible** la instalación del *Seagate Exos X CSI Driver* (soporta ME5) en un clúster Kubernetes con **dos cabinas / dos zonas** (sitea y siteb) usando iSCSI + multipath y *topología por zona*.
> **Objetivo**
>
> * Un único despliegue del driver (Helm).
> * **Dos StorageClass** (uno por sitio) con `allowedTopologies` y credenciales (Secret) separadas.
> * *WaitForFirstConsumer* para que el volumen se cree en la **misma zona** del pod.
> * Montajes iSCSI rápidos gracias a multipath bien configurado (modo `greedy`).
---
## 1) Prerrequisitos en los nodos
1. **Multipath** y **iSCSI** instalados/activos.
2. **/etc/multipath.conf** — opciones relevantes usadas:
```conf
defaults {
user_friendly_names "no"
find_multipaths "greedy"
no_path_retry "queue"
}
devices {
device {
vendor "DellEMC"
product "ME5"
path_grouping_policy "multibus"
path_checker "tur"
prio "alua"
}
}
```
> **Por qué `greedy`?**
>
> * `find_multipaths "greedy"` evita crear *maps* hasta que haya más de un camino **o** el dispositivo sea claramente multipath, reduciendo falsos positivos y estabilizando el *udev settle*. Mejora tiempos de descubrimiento y evita *flapping*.
Reiniciar servicios y refrescar paths tras cambiar multipath:
```bash
sudo systemctl restart multipathd
sudo multipath -r
```
3. **Propagación de montajes (rshared)**
Asegurar que `/` y `/var/lib/kubelet` están en **rshared** para que los montajes hechos por el plugin dentro del pod del *nodeserver* aparezcan en el host:
```bash
sudo mount --make-rshared /
# systemd dropin para kubelet
sudo install -d /etc/systemd/system/kubelet.service.d
cat <<'EOF' | sudo tee /etc/systemd/system/kubelet.service.d/10-mount-propagation.conf
[Service]
MountFlags=
ExecStartPre=/bin/mkdir -p /var/lib/kubelet
ExecStartPre=/bin/mount --bind /var/lib/kubelet /var/lib/kubelet
ExecStartPre=/bin/mount --make-rshared /var/lib/kubelet
EOF
sudo systemctl daemon-reload
sudo systemctl restart kubelet
```
Comprobar:
```bash
sudo findmnt -o TARGET,PROPAGATION /
sudo findmnt -o TARGET,PROPAGATION /var/lib/kubelet
```
4. **Etiquetas de topología en nodos**
Etiquetar cada nodo con su zona:
```bash
kubectl label nodes <nodo-del-site-a> topology.kubernetes.io/zone=site-a --overwrite
kubectl label nodes <nodo-del-site-b> topology.kubernetes.io/zone=site-b --overwrite
```
---
## 2) Despliegue del Driver con Helm
### 2.1. Namespace y valores
```bash
kubectl apply -f namespace.yaml # namespace: seagate
```
**values.yaml** (resumen de lo usado):
* Imagen del driver: `ghcr.io/seagate/seagate-exos-x-csi:v1.10.0`
* Sidecars:
* `csi-provisioner v5.0.1` (timeout 60s)
* `csi-attacher v4.6.1`
* `csi-resizer v1.11.1`
* `csi-snapshotter v8.0.1`
* `csi-node-driver-registrar v2.9.0`
* `controller.extraArgs: ["-v=2"]`
* `node.extraArgs: ["-v=2"]`
> **Nota:** no es necesario tocar `CSIDriver` para topología; la topología se maneja desde los `StorageClass` + etiquetas de nodo.
### 2.2. Instalación
```bash
helm upgrade --install exos-x-csi \
-n seagate --create-namespace \
./seagate-exos-x-csi \
-f ./values.yaml
```
#### Si hay residuos de una instalación anterior (RBAC)
Si aparece un error de *invalid ownership metadata* con recursos tipo `ClusterRole/ClusterRoleBinding` de un release previo (p.ej. `exosx-csi`), eliminarlos:
```bash
kubectl delete clusterrole external-provisioner-runner-systems
kubectl delete clusterrolebinding csi-provisioner-role-systems
# (si hubiera más, listarlos por label y borrarlos)
# kubectl get clusterrole,clusterrolebinding -A -l app.kubernetes.io/instance=<old-release>
```
Reintentar `helm upgrade --install`.
---
## 3) Secret por cabina (A y B)
Un `Secret` por sitio en el *namespace* `seagate` con `apiAddress`, `username`, `password` en Base64.
```bash
kubectl apply -f secret-me5-site-a.yaml
kubectl apply -f secret-me5-site-b.yaml
```
> **Importante:** Los `StorageClass` deben usar las **claves estándar CSI** para que el provisioner pase el Secret al driver:
>
> * `csi.storage.k8s.io/provisioner-secret-name|namespace`
> * `csi.storage.k8s.io/controller-publish-secret-name|namespace`
> * `csi.storage.k8s.io/controller-expand-secret-name|namespace`
> * `csi.storage.k8s.io/node-stage-secret-name|namespace` *(si aplica)*
> * `csi.storage.k8s.io/node-publish-secret-name|namespace` *(si aplica)*
El síntoma de no usar estos nombres es: `missing API credentials` en el evento del PVC.
---
## 4) StorageClass por zona (topología)
Se definen **dos** `StorageClass` idénticos salvo:
* Secret (A o B)
* `pool` (p. ej., `dg01` para sitea, `dg02` para siteb)
* `volPrefix` (ej. `sza` / `szb` para identificar site en el nombre de LUN)
* `allowedTopologies` con la zona correspondiente
* `volumeBindingMode: WaitForFirstConsumer`
> Con WFFC, el PVC **no** se enlaza hasta que exista un Pod consumidor; el scheduler elige un nodo, y el provisioner crea el volumen en la **zona del nodo**.
Aplicar ambos `StorageClass`:
```bash
kubectl apply -f sc-me5-site-a.yaml
kubectl apply -f sc-me5-site-b.yaml
```
---
## 5) Prueba de extremo a extremo
### 5.1. PVC + Pod en sitea
* PVC: `pvc-a` con `storageClassName: sc-me5-site-a`
* Pod: `pod-a` con `nodeSelector: topology.kubernetes.io/zone=site-a`
```bash
kubectl apply -f pvc-pod-a.yaml
kubectl apply -f pod-a.yaml
kubectl get pvc,pod
```
Deberías ver el Pod en *Running* y el volumen creado/montado en la ME5 del sitea.
### 5.2. Verificaciones útiles
* **iSCSI nodes vistos:**
```bash
sudo iscsiadm -m node | sort
```
* **Multipath:**
```bash
sudo multipath -ll
```
* **Eventos del PVC:**
```bash
kubectl describe pvc <nombre>
```
* **Logs del controller:** (búsqueda de credenciales / errores de provisión)
```bash
kubectl -n seagate logs deploy/seagate-exos-x-csi-controller-server \
-c seagate-exos-x-csi-controller | grep -i -E 'cred|secret|error'
```
---
## 6) Medir el tiempo de *NodePublish* (montaje)
Para medir cuánto tarda el montaje (fase *NodePublishVolume*) desde el *nodeserver*:
```bash
kubectl -n seagate logs -l name=seagate-exos-x-csi-node-server \
-c seagate-exos-x-csi-node --tail=10000 \
| grep "NodePublishVolume" \
| grep "ROUTINE END" \
| sed -E 's/.*NodePublishVolume.*<([^>]*)>.*/\1/'
```
* Valores \~**< 2 min** indican que el montaje completa dentro de la ventana de kubelet, evitando `DeadlineExceeded`.
* Si ves \~**4m34s** constantes: el driver está esperando a que aparezcan *dmname* de portales inaccesibles. Revisa topologías, conectividad y que solo se prueben portales de la zona activa.
> Para validar zonaB, lanza un Pod/PVC análogo en `site-b` y repite el grep anterior en los logs.
---
## 7) Solución de problemas
* **`missing API credentials` al provisionar**
* Asegúrate de usar las **claves CSI** en `parameters:` del `StorageClass` (ver §3).
* **Errores Helm de *invalid ownership metadata***
* Borra los `ClusterRole/ClusterRoleBinding` residuales del release antiguo (ver §2.2).
* **`DeadlineExceeded` durante montaje**
* Comprueba:
* `find_multipaths "greedy"` y resto de multipath según §1.2.
* Etiquetas de zona en el nodo donde programa el Pod.
* Que el `StorageClass` correcto tenga `allowedTopologies` de esa zona.
* **Ver puertos/portales iSCSI efectivos**
* `sudo iscsiadm -m node | sort` para ver a qué destinos quedó configurado el nodo. Con topología bien aplicada, deben ser los del sitio correspondiente.
---
## 8) Limpieza y reintentos
Para repetir la prueba desde cero (manteniendo el driver):
```bash
kubectl delete -f pod-a.yaml
kubectl delete -f pvc-pod-a.yaml
```
Si quisieras limpiar *todo el despliegue* del driver:
```bash
helm uninstall exos-x-csi -n seagate
# Si quedaron RBAC de releases previos:
kubectl delete clusterrole external-provisioner-runner-systems || true
kubectl delete clusterrolebinding csi-provisioner-role-systems || true
```
---
## 9) Resumen de lo que quedó en repo (carpeta `seagate/`)
* `namespace.yaml` — Namespace `seagate`.
* `secret-me5-site-a.yaml` / `secret-me5-site-b.yaml` — Credenciales por sitio.
* `values.yaml` — Valores de Helm usados para el driver v1.10.0.
* `sc-me5-site-a.yaml` / `sc-me5-site-b.yaml` — StorageClass con `allowedTopologies`, `pool`, `volPrefix`, claves CSI de Secret y `WaitForFirstConsumer`.
* `pvc-pod-a.yaml` + `pod-a.yaml` — Manifests de prueba en `site-a`.
* *(Opcional)* `csi-exos-x-csidriver.yaml` — no es necesario modificarlo para topología en esta versión.
---
## 10) Anexos — Comandos útiles ejecutados
* Reinicio multipath/kubelet y propagación de montajes.
* Limpieza iSCSI/multipath (cuando se rehizo la prueba):
```bash
sudo iscsiadm -m node -u || true
sudo iscsiadm -m node -o delete || true
sudo multipath -F || true
sudo multipath -r
```
* Despliegue Helm + manejo de residuos RBAC (ver §2.2).
* Aplicación secuencial de `namespace`, `secrets`, `StorageClass`, `PVC` y `Pod`.
---
### Resultado
* **Reproducible**: con esta receta, el volumen se crea en la cabina de su zona y el Pod arranca.
* **Tiempos de montaje**: bajan de \~4m34s a **≈1m30s** (observado), dentro del presupuesto de kubelet.
* **Aislamiento por zona**: cada StorageClass limita portales iSCSI a su sitio gracias a `allowedTopologies` + etiquetas de nodo.