añadido script clientes
This commit is contained in:
@@ -4,28 +4,55 @@ metadata:
|
||||
name: repo-sources
|
||||
namespace: repo
|
||||
data:
|
||||
# Lista de orígenes a espejar
|
||||
# Formato por línea: NAME|URL|SUBDIR
|
||||
# SUBDIR cuelga de /mirror/repos (asegúrate de que tu Deployment monta el PVC en /usr/local/apache2/htdocs con subPath repos)
|
||||
sources.txt: |
|
||||
# openSUSE Leap 15.6 (básicos + updates)
|
||||
repo-oss|http://download.opensuse.org/distribution/leap/15.6/repo/oss/|opensuse/leap/15.6/oss
|
||||
repo-non-oss|http://download.opensuse.org/distribution/leap/15.6/repo/non-oss/|opensuse/leap/15.6/non-oss
|
||||
update-oss|http://download.opensuse.org/update/leap/15.6/oss/|opensuse/leap/15.6/update/oss
|
||||
update-non-oss|http://download.opensuse.org/update/leap/15.6/non-oss/|opensuse/leap/15.6/update/non-oss
|
||||
update-sle|http://download.opensuse.org/update/leap/15.6/sle/|opensuse/leap/15.6/update/sle
|
||||
backports|http://download.opensuse.org/update/leap/15.6/backports/|opensuse/leap/15.6/update/backports
|
||||
|
||||
# Codecs openh264
|
||||
openh264|http://codecs.opensuse.org/openh264/openSUSE_Leap/|opensuse/openh264
|
||||
|
||||
# Terceros (opcional)
|
||||
nvidia|https://download.nvidia.com/opensuse/leap/15.6/|thirdparty/nvidia/leap/15.6
|
||||
k8s-stable|https://pkgs.k8s.io/core:/stable:/v1.33/rpm/|thirdparty/kubernetes/core/stable/v1.33/rpm
|
||||
|
||||
# Claves públicas a publicar en /mirror/keys
|
||||
# Formato por línea: NAME|URL|FILENAME
|
||||
# Ajusta las URLs si prefieres otras fuentes/ubicaciones oficiales
|
||||
keys.txt: |
|
||||
opensuse|https://download.opensuse.org/repositories/openSUSE:/Leap:/15.6:/Update/standard/repodata/repomd.xml.key|RPM-GPG-KEY-openSUSE
|
||||
nvidia|https://download.nvidia.com/opensuse/repodata/repomd.xml.key|RPM-GPG-KEY-NVIDIA
|
||||
k8s|https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key|RPM-GPG-KEY-k8s
|
||||
|
||||
# Script de sincronización diario (CronJob)
|
||||
# - Sincroniza repos a /mirror/repos/...
|
||||
# - Publica claves GPG en /mirror/keys
|
||||
sync.sh: |
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SRC_LIST="/config/sources.txt"
|
||||
KEYS_LIST="/config/keys.txt"
|
||||
|
||||
DEST_ROOT="/mirror/repos"
|
||||
DEST_KEYS="/mirror/keys"
|
||||
|
||||
mkdir -p "$DEST_ROOT"
|
||||
mkdir -p "$DEST_ROOT" "$DEST_KEYS"
|
||||
|
||||
command -v rsync >/dev/null 2>&1 || echo "Aviso: rsync no disponible; usaré wget para HTTP/HTTPS"
|
||||
# Requisitos
|
||||
command -v wget >/dev/null 2>&1 || { echo "ERROR: wget requerido"; exit 1; }
|
||||
if ! command -v rsync >/dev/null 2>&1; then
|
||||
echo "Aviso: rsync no disponible; usaré wget para HTTP/HTTPS"
|
||||
fi
|
||||
|
||||
echo "===== SYNC REPOS ====="
|
||||
while IFS='|' read -r NAME URL SUBDIR; do
|
||||
[[ -z "${NAME:-}" || "${NAME:0:1}" == "#" ]] && continue
|
||||
|
||||
@@ -35,22 +62,39 @@ data:
|
||||
echo "==> Sync ${NAME} (${URL}) -> ${DEST}"
|
||||
|
||||
if [[ "$URL" == rsync://* ]]; then
|
||||
# Sincronización eficiente por rsync (si el mirror lo soporta)
|
||||
rsync -aH --delete --partial --info=stats1,progress2 "${URL}" "${DEST}/"
|
||||
else
|
||||
# Mirror vía HTTP/HTTPS con wget
|
||||
TMP="${DEST}.tmp"
|
||||
mkdir -p "$TMP"
|
||||
|
||||
# -m (mirror), -np (no subir), -nH (sin host en ruta), robots=off
|
||||
wget -m -np -nH -e robots=off -P "$TMP" --no-verbose --show-progress "$URL"
|
||||
|
||||
# Mover contenido espeljado a DEST (limpiando y dejando estructura limpia)
|
||||
shopt -s dotglob nullglob
|
||||
SRC_CONTENT=("$TMP"/*)
|
||||
if [[ ${#SRC_CONTENT[@]} -gt 0 ]]; then
|
||||
if compgen -G "$TMP/*" >/dev/null; then
|
||||
rsync -a --delete "$TMP"/ "$DEST"/
|
||||
fi
|
||||
rm -rf "$TMP"
|
||||
fi
|
||||
|
||||
# Permisos legibles por httpd y Samba
|
||||
chmod -R a+rX "$DEST"
|
||||
done < "$SRC_LIST"
|
||||
|
||||
echo "Sync completado."
|
||||
echo "===== SYNC KEYS ====="
|
||||
if [[ -f "$KEYS_LIST" ]]; then
|
||||
while IFS='|' read -r KNAME KURL KFILE; do
|
||||
[[ -z "${KNAME:-}" || "${KNAME:0:1}" == "#" ]] && continue
|
||||
echo "==> Key ${KNAME} (${KURL}) -> ${DEST_KEYS}/${KFILE}"
|
||||
wget -q -O "${DEST_KEYS}/${KFILE}.tmp" "$KURL"
|
||||
mv "${DEST_KEYS}/${KFILE}.tmp" "${DEST_KEYS}/${KFILE}"
|
||||
chmod a+r "${DEST_KEYS}/${KFILE}"
|
||||
done < "$KEYS_LIST"
|
||||
else
|
||||
echo "No hay KEYS_LIST ($KEYS_LIST), omitido."
|
||||
fi
|
||||
|
||||
echo "===== DONE ====="
|
||||
|
||||
144
repo/configure-local-repos.sh
Normal file
144
repo/configure-local-repos.sh
Normal file
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ============================
|
||||
# Configuración (ajusta aquí)
|
||||
# ============================
|
||||
BASE_URL="${BASE_URL:-http://repo.c2et.net}" # tu dominio del mirror (sin / al final)
|
||||
LEAP_VER="${LEAP_VER:-15.6}" # versión de Leap
|
||||
ENABLE_NVIDIA="${ENABLE_NVIDIA:-true}" # true/false
|
||||
ENABLE_K8S="${ENABLE_K8S:-true}" # true/false
|
||||
DISABLE_EXTERNAL="${DISABLE_EXTERNAL:-true}" # true/false (deshabilitar repos externos)
|
||||
|
||||
# Rutas base del mirror interno
|
||||
REPO_BASE="${BASE_URL}/opensuse/leap/${LEAP_VER}"
|
||||
KEYS_BASE="${BASE_URL}/keys"
|
||||
|
||||
# Directorio de repos dnf/zypp
|
||||
REPOS_DIR="/etc/zypp/repos.d"
|
||||
|
||||
# ============================
|
||||
# Helpers
|
||||
# ============================
|
||||
need_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Este script debe ejecutarse como root (o con sudo)." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
have_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
write_repo() {
|
||||
local alias="$1" name="$2" baseurl="$3" gpgkey="$4"
|
||||
local path="${REPOS_DIR}/${alias}.repo"
|
||||
|
||||
cat >"${path}.tmp" <<EOF
|
||||
[${alias}]
|
||||
name=${name}
|
||||
enabled=1
|
||||
autorefresh=1
|
||||
baseurl=${baseurl}
|
||||
type=rpm-md
|
||||
gpgcheck=1
|
||||
gpgkey=${gpgkey}
|
||||
EOF
|
||||
|
||||
# Solo mueve si cambió (idempotente)
|
||||
if [[ ! -f "${path}" ]] || ! cmp -s "${path}.tmp" "${path}"; then
|
||||
mv "${path}.tmp" "${path}"
|
||||
echo " - Escrito ${path}"
|
||||
else
|
||||
rm -f "${path}.tmp"
|
||||
echo " - Sin cambios ${path}"
|
||||
fi
|
||||
}
|
||||
|
||||
import_key() {
|
||||
local url="$1" file="key-$(basename "$url")"
|
||||
# rpm ignora si ya está importada; esto es idempotente
|
||||
echo " - Importando clave: $url"
|
||||
rpm --import "$url" || {
|
||||
echo " * Aviso: no se pudo importar $url. ¿Hay conectividad al mirror?" >&2
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
disable_external_repos() {
|
||||
echo "Deshabilitando repos externos conocidos..."
|
||||
# Deshabilita TODO lo que no sea *_local que creemos, de forma segura:
|
||||
# Busca todos los alias actuales y deshabilita los que no terminen en '-local'
|
||||
local aliases
|
||||
aliases=$(zypper --non-interactive lr -u | awk 'NR>2 {print $1,$2}' | tail -n +1 | awk '{print $2}')
|
||||
for a in $aliases; do
|
||||
if [[ "$a" != *-local ]]; then
|
||||
# Algunos sistemas traen alias con espacios; saltamos los complicados
|
||||
if [[ "$a" =~ ^[A-Za-z0-9._:-]+$ ]]; then
|
||||
zypper --non-interactive mr -d "$a" || true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# ============================
|
||||
# Main
|
||||
# ============================
|
||||
need_root
|
||||
|
||||
if ! have_cmd zypper; then
|
||||
echo "No se encontró zypper. ¿Es openSUSE/SLE este sistema?" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "== Configurando repos locales desde ${BASE_URL} para Leap ${LEAP_VER} =="
|
||||
|
||||
mkdir -p "$REPOS_DIR"
|
||||
|
||||
# 1) Importa claves GPG desde tu mirror
|
||||
echo "Importando claves GPG desde ${KEYS_BASE} ..."
|
||||
import_key "${KEYS_BASE}/RPM-GPG-KEY-openSUSE" || true
|
||||
$ENABLE_NVIDIA && import_key "${KEYS_BASE}/RPM-GPG-KEY-NVIDIA" || true
|
||||
$ENABLE_K8S && import_key "${KEYS_BASE}/RPM-GPG-KEY-k8s" || true
|
||||
|
||||
# 2) Repos base de openSUSE
|
||||
echo "Escribiendo archivos .repo para repos locales..."
|
||||
write_repo "repo-oss-local" "repo-oss-local" "${REPO_BASE}/oss" "${KEYS_BASE}/RPM-GPG-KEY-openSUSE"
|
||||
write_repo "repo-non-oss-local" "repo-non-oss-local" "${REPO_BASE}/non-oss" "${KEYS_BASE}/RPM-GPG-KEY-openSUSE"
|
||||
write_repo "update-oss-local" "update-oss-local" "${REPO_BASE}/update/oss" "${KEYS_BASE}/RPM-GPG-KEY-openSUSE"
|
||||
write_repo "update-non-oss-local" "update-non-oss-local" "${REPO_BASE}/update/non-oss" "${KEYS_BASE}/RPM-GPG-KEY-openSUSE"
|
||||
write_repo "update-sle-local" "update-sle-local" "${REPO_BASE}/update/sle" "${KEYS_BASE}/RPM-GPG-KEY-openSUSE"
|
||||
write_repo "update-backports-local" "update-backports-local" "${REPO_BASE}/update/backports" "${KEYS_BASE}/RPM-GPG-KEY-openSUSE"
|
||||
write_repo "openh264-local" "openh264-local" "${BASE_URL}/opensuse/openh264" "${KEYS_BASE}/RPM-GPG-KEY-openSUSE"
|
||||
|
||||
# 3) Repos de terceros (opcional)
|
||||
if $ENABLE_NVIDIA; then
|
||||
write_repo "nvidia-local" "nvidia-local" \
|
||||
"${BASE_URL}/thirdparty/nvidia/leap/${LEAP_VER}" \
|
||||
"${KEYS_BASE}/RPM-GPG-KEY-NVIDIA"
|
||||
fi
|
||||
|
||||
if $ENABLE_K8S; then
|
||||
write_repo "k8s-stable-local" "k8s-stable-local" \
|
||||
"${BASE_URL}/thirdparty/kubernetes/core/stable/v1.33/rpm" \
|
||||
"${KEYS_BASE}/RPM-GPG-KEY-k8s"
|
||||
fi
|
||||
|
||||
# 4) Deshabilitar repos externos si procede
|
||||
if $DISABLE_EXTERNAL; then
|
||||
disable_external_repos
|
||||
fi
|
||||
|
||||
# 5) Refrescar repos (no interactivo)
|
||||
echo "Refrescando repos..."
|
||||
zypper --non-interactive --gpg-auto-import-keys ref || true
|
||||
|
||||
echo
|
||||
echo "== Listado final de repos =="
|
||||
zypper lr -d || true
|
||||
|
||||
echo
|
||||
echo "Listo. Si quieres personalizar:"
|
||||
echo " BASE_URL=... LEAP_VER=... ENABLE_NVIDIA=true/false ENABLE_K8S=true/false DISABLE_EXTERNAL=true/false \\"
|
||||
echo " sudo -E ./$(basename "$0")"
|
||||
@@ -1,22 +1,30 @@
|
||||
## Cómo usarlo (rápido)
|
||||
# Repositorio Privado openSUSE
|
||||
|
||||
Este despliegue en Kubernetes crea un **mirror interno de repositorios de openSUSE** (y de terceros opcionales, como NVIDIA o Kubernetes). Sirve para que los servidores de nuestra red se actualicen **desde dentro**, sin depender de internet.
|
||||
|
||||
El sistema funciona con:
|
||||
|
||||
* **Servidor HTTP/HTTPS** → los clientes SUSE acceden vía `http://repo.c2et.net/...` o `https://repo.c2et.net/...` para descargar paquetes y metadatos.
|
||||
* **Servidor Samba (SMB)** → expone la misma carpeta por red. Esto nos permite que el **“diodo de datos”** copie los repos de manera unidireccional hacia la red clasificada. Así aseguramos que las máquinas en la red sensible reciben actualizaciones sin conectividad exterior.
|
||||
|
||||
La carpeta de repos se actualiza automáticamente cada día mediante un **CronJob**, que sincroniza contra los repos oficiales de openSUSE y de terceros.
|
||||
|
||||
---
|
||||
|
||||
## Cómo desplegarlo
|
||||
|
||||
1. Ajusta **dominio** en el Ingress y (si quieres) IP fija en el Service de Samba.
|
||||
2. Revisa tamaño de **PVC**.
|
||||
3. (Opcional) Cambia o amplía la lista en `sources.txt`. Si tienes un mirror con **rsync**, usa `rsync://...` en la URL para más eficiencia.
|
||||
4. Aplica en orden:
|
||||
2. Revisa tamaño de **PVC** (mínimo 300 GB recomendado).
|
||||
3. (Opcional) Cambia o amplía la lista en `sources.txt` (por ejemplo, usando mirrors con `rsync://`).
|
||||
4. Despliega todo de una vez con **Kustomize**:
|
||||
|
||||
```bash
|
||||
kubectl apply -f repo/namespace.yaml
|
||||
kubectl apply -f repo/pvc.yaml
|
||||
kubectl apply -f repo/configmap/repo-sources.yaml
|
||||
kubectl apply -f repo/deployments/repo-server.yaml
|
||||
kubectl apply -f repo/services/service-http.yaml
|
||||
kubectl apply -f repo/services/service-samba.yaml # o NodePort
|
||||
kubectl apply -f repo/ingress/ingress-repo.yaml
|
||||
kubectl apply -f repo/cronjobs/repo-sync.yaml
|
||||
kubectl apply -k repo/
|
||||
```
|
||||
|
||||
5. Lanza una sync inicial **ad hoc** (sin esperar al cron) creando un Job manual:
|
||||
*(Si prefieres, aún puedes aplicar los manifiestos uno por uno en el orden indicado en la carpeta `repo/`.)*
|
||||
|
||||
5. Para lanzar una sincronización inicial manual (sin esperar al cron):
|
||||
|
||||
```bash
|
||||
kubectl create job --from=cronjob/repo-sync repo-sync-now -n repo
|
||||
@@ -27,28 +35,37 @@ kubectl logs -f job/repo-sync-now -n repo
|
||||
|
||||
## Configuración en los clientes SUSE
|
||||
|
||||
En tus servidores, añade repos apuntando a tu repo interno, por ejemplo:
|
||||
En los clientes no hace falta configurar repos manualmente. Basta con ejecutar el **script de cliente** incluido en este repo (`configure-local-repos.sh`). Este script:
|
||||
|
||||
* Importa las claves GPG desde `http://repo.c2et.net/keys/`.
|
||||
* Crea los `.repo` apuntando al mirror interno.
|
||||
* Deshabilita los repos externos para que solo se usen los `-local`.
|
||||
|
||||
### Uso del script en el cliente
|
||||
|
||||
```bash
|
||||
# HTTP (recomendado)
|
||||
sudo zypper ar -f http://repo.c2et.net/opensuse/leap/15.6/oss repo-oss-local
|
||||
sudo zypper ar -f http://repo.c2et.net/opensuse/leap/15.6/non-oss repo-non-oss-local
|
||||
sudo zypper ar -f http://repo.c2et.net/opensuse/leap/15.6/update/oss update-oss-local
|
||||
sudo zypper ar -f http://repo.c2et.net/opensuse/leap/15.6/update/non-oss update-non-oss-local
|
||||
sudo zypper ar -f http://repo.c2et.net/opensuse/leap/15.6/update/sle update-sle-local
|
||||
sudo zypper ar -f http://repo.c2et.net/opensuse/leap/15.6/update/backports update-backports-local
|
||||
sudo zypper ar -f http://repo.c2et.net/opensuse/openh264 openh264-local
|
||||
|
||||
# Terceros (si los espejas):
|
||||
sudo zypper ar -f http://repo.c2et.net/thirdparty/nvidia/leap/15.6 nvidia-local
|
||||
sudo zypper ar -f http://repo.c2et.net/thirdparty/kubernetes/core/stable/v1.33/rpm k8s-stable-local
|
||||
chmod +x configure-local-repos.sh
|
||||
sudo ./configure-local-repos.sh
|
||||
```
|
||||
|
||||
> Truco: deja tus repos “externos” deshabilitados (`zypper mr -d <alias>`) y activa solo los “-local”. Así fuerzan el uso del mirror interno.
|
||||
Esto deja el sistema listo para trabajar solo con los repos locales.
|
||||
|
||||
---
|
||||
|
||||
## Ventajas de esta arquitectura
|
||||
|
||||
* **Seguridad**: los clientes nunca salen a internet, solo acceden al repo interno.
|
||||
* **Control**: el mirror se actualiza de forma programada (p. ej. de madrugada). Siempre sabemos qué versiones están disponibles.
|
||||
* **Simplicidad**: los clientes usan HTTP/HTTPS estándar; el Ingress se encarga del TLS si hace falta.
|
||||
* **Integración con el diodo**: gracias a Samba, la carpeta puede replicarse unidireccionalmente hacia la red clasificada.
|
||||
* **Verificación**: zypper siempre valida las firmas GPG de los paquetes, aunque se distribuyan por HTTP.
|
||||
|
||||
---
|
||||
|
||||
## Sugerencias y mejoras
|
||||
|
||||
* **Mejor rsync**: si eliges un mirror con `rsync://`, cambia las URLs de `download.opensuse.org` a ese mirror (ej. `rsync://<mirror>/opensuse/distribution/leap/15.6/repo/oss/`) para acelerar y reducir ancho de banda (usa `--delete`).
|
||||
* **Throttle nocturno**: añade `--bwlimit=MB` a `rsync` si tu ventana noc
|
||||
* Usar **mirrors oficiales con rsync** para ahorrar ancho de banda y tiempo de sincronización.
|
||||
* Añadir `--bwlimit` en el `sync.sh` si queremos limitar consumo nocturno de ancho de banda.
|
||||
* Sustituir `httpd` por `nginx` si se busca mayor rendimiento en descargas masivas.
|
||||
* Proteger el Ingress con autenticación si se expone fuera de la red de confianza.
|
||||
* Mantener el **script de cliente** actualizado para simplificar el alta de repos en todos los servidores SUSE.
|
||||
|
||||
Reference in New Issue
Block a user