Apolo SSL – Manifiestos de Kubernetes
Manifiestos de Apolo para Kubernetes con Kustomize. Incluye backend (PHP + Postgres + RabbitMQ), servicios web, WebSocket, CoreDNS interno para la VPN, chat (ejabberd), Nakama, y el stack de streaming (MediaMTX, Kurento Media Server y su API, Streamer). Certificados vía cert-manager y exposición con ingress-nginx y MetalLB.
Despliegue único:
kubectl apply -k .
Requisitos
-
Kubernetes 1.24+ (probado con containerd).
-
MetalLB configurado y con rango para IPs del LB (ej.
192.168.200.0/24). -
ingress-nginx desplegado. En este entorno se usan dos Services:
ingress-nginx/ingress-nginx-controller→ IP pública (ej.192.168.0.100)ingress-nginx/ingress-nginx-controller-200→ IP VPN192.168.200.10(tráfico interno)
-
cert-manager con un
ClusterIssuerllamadoletsencrypt-prod. -
StorageClass disponible (
ceph-rbd) para los PVC de Postgres, RabbitMQ y ejabberd. -
(Para acceso por VPN) WireGuard + NAT desde la subred de la VPN hacia la red del clúster / redes internas.
-
Acceso al Harbor privado (se crea un Secret
harbor-cred).
Estructura
certs/ # Certificados de cert-manager (Certificate)
configmaps/ # ConfigMaps de cada servicio (web, portal, CoreDNS, etc.)
deployments/ # Deployments de cada componente
ingress/ # Ingress (TLS, whitelists VPN, etc.)
pvc/ # PersistentVolumeClaims (Postgres, Rabbit, ejabberd)
secrets/ # Secrets de aplicación (no commitear credenciales privadas)
services/ # Services (ClusterIP / LoadBalancer) y alias de docker-compose
namespace.yaml # Namespace apolo
kustomization.yaml
DNS interno para la VPN
Se expone un CoreDNS propio con IP LB 192.168.200.11 que resuelve:
chat.apolo.c2et.netmuc.chat.apolo.c2et.netportal.apolo.c2et.netcolossus.apolo.c2et.netstreaming.apolo.c2et.netmeeting.apolo.c2et.netbackend.apolo.c2et.net
Para clientes VPN, configurar DNS a
192.168.200.11.
Certificados TLS
certs/contieneCertificatepara dominios comochat.*ymeeting.*.- El resto de hosts se gestionan vía Ingress con
tls.secretNameemitido porletsencrypt-prod.
Whitelists y acceso
Los Ingress sensibles incluyen:
nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,10.244.0.0/16,192.168.4.0/24"
- 192.168.200.0/24: clientes por VPN
- 10.244.0.0/16: tráfico intra-clúster
- 192.168.4.0/24: nodos/infra local (ajústalo si aplica)
Despliegue
# Namespace y todo el stack
kubectl apply -k .
# Ver pods
kubectl -n apolo get pods -w
IPs de Services (ejemplo)
- Ingress interno (nginx):
192.168.200.10 - CoreDNS interno:
192.168.200.11 - MediaMTX (streaming):
192.168.200.12 - Ejabberd (chat):
192.168.200.12 - Kurento API:
192.168.200.14
Operación
-
Escalar:
kubectl -n apolo scale deploy/apolo-web --replicas=2 -
Actualizar imagen:
- Cambia el tag en el
Deploymenty aplicakubectl apply -k .
- Cambia el tag en el
-
Logs:
kubectl -n apolo logs deploy/apolo-web -f -
Ingress / TLS:
kubectl -n apolo describe ingress apolo-backend kubectl -n apolo get certificate kubectl -n apolo describe certificate <name>
Notas y “gotchas”
-
PV de Postgres: el contenedor requiere subdirectorio
PGDATA. Ya se maneja coninitContainerpara evitar ellost+foundal montar el PVC. -
Health checks web: los
readiness/livenessusan/. Algunos contenedores devuelven 404 en raíz; está ajustado para que no reinicien en bucle. -
ejabberd:
- Permisos de volúmenes: se monta con
fsGroupadecuado; si vespermission denied, revisarunAsUser/runAsGroup/fsGroupy el dueño de los paths del contenedor. - TLS: el
initContainerconcatenatls.key + tls.crt → chat.pem(formato que espera ejabberd).
- Permisos de volúmenes: se monta con
-
.com vs .net:
- El Portal puede hablar con
backend.apolo.c2et.com; la VPN/CoreDNS “traduce” a la IP interna (192.168.200.10) sin tocar certificados. - Si más adelante migras todo a
.com, cambiahostsde los Ingress yCertificate.
- El Portal puede hablar con
Troubleshooting rápido
-
Ver por qué el Ingress devuelve 403/401/404:
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller -f kubectl -n apolo describe ingress apolo-backend -
Revisar eventos de un pod:
kubectl -n apolo describe pod <pod> -
Comprobar variables de entorno en PHP (conectividad DB/Rabbit):
kubectl -n apolo exec deploy/apolo-php -- printenv | egrep 'DATABASE_URL|MESSENGER_TRANSPORT_DSN'
Despliegue
kubectl apply -k .
kubectl -n apolo get pods -w