Instalar en Kubernetes (Kustomize)
El paquete de Kubernetes son manifiestos simples con Kustomize, que se aplican con kubectl apply -k. No hay gráfico de Helm. El paquete está en deploy/k8s del repositorio. Úselo cuando ya tenga un clúster; para un solo servidor sin clúster use el instalador de VM o el paquete de Docker Compose.
:::info Estado
Los manifiestos se validan de forma estática y en un clúster kind local. La ruta de medios (SIP y RTP a través de un cortafuegos y NAT de nube real) todavía no está probada en internet. Lea los límites en deploy/k8s/README.md antes de conectar troncales en vivo.
:::
Requisitos
- Kubernetes 1.30 o más reciente, con una StorageClass predeterminada (tres volúmenes ReadWriteOnce para las bases de datos incluidas).
- Un CNI que aplique NetworkPolicy (Calico, Cilium, GKE Dataplane V2). Sin uno, las políticas se aceptan pero se ignoran.
- Al menos un nodo de medios: un nodo con dirección pública (o NAT 1:1) al que le asigna la etiqueta
mpbx.io/media=true. SIP y RTP se ejecutan allí con red del host. kubectlykustomize(okubectlcon su Kustomize integrado).- Sus propias imágenes de contenedor de una versión, fijadas por digest para producción.
Instalación
Primero defina los tres valores que necesita el overlay. El archivo del overlay tiene los mismos tres lugares marcados como 1., 2. y 3..
export MEDIA_NODE="${MEDIA_NODE:?set to the name of the media node}"
export MEDIA_NODE_IP="${MEDIA_NODE_IP:?set to the internal IP of the media node}"
export MPBX_PUBLIC_URL="${MPBX_PUBLIC_URL:?set to the https URL users open, for example https://pbx.example.com}"
Después edite deploy/k8s/overlays/small/kustomization.yaml:
images:nombra las imágenesmpbx,mpbx-mediaympbx-rtpenginede su versión. Usedigest: sha256:...en lugar denewTagen producción.MPBX_PUBLIC_URL=enconfigMapGeneratores la dirección del cliente web. Se usa para el enlace de configuración del primer administrador.db-from-media-nodescontiene la dirección interna del nodo de medios como/32.
Aplique el paquete:
set -eu
: "${MEDIA_NODE:?set MEDIA_NODE to the media node name}"
: "${MPBX_PUBLIC_URL:?set MPBX_PUBLIC_URL}"
kubectl label node "$MEDIA_NODE" mpbx.io/media=true --overwrite
kubectl apply -k deploy/k8s/overlays/small
kubectl -n mpbx wait --for=condition=complete job/mpbx-init --timeout=5m
Lea la clave de recuperación y el enlace de configuración del primer administrador. Se muestran una sola vez:
set -eu
kubectl -n mpbx logs job/mpbx-init
kubectl -n mpbx delete job mpbx-init
Anote la clave de recuperación en un administrador de contraseñas o en papel. No se guarda en ningún lugar del clúster. Sin ella, si se pierde el Secret se pierden las contraseñas de troncales, las claves de API y las grabaciones cifradas. Respalde el Secret mpbx/mpbx-secrets con los respaldos de su clúster, y tome respaldos del PBX cifrados con frase de paso como se describe en Respaldo y restauración. Esos respaldos incluyen la clave maestra.
Abra el enlace de configuración y continúe con los pasos de la primera ejecución.
Los pods de la API y de SIP suelen reiniciarse una o dos veces en la primera instalación mientras arranca Postgres. Es lo esperado.
Revisar la instalación
set -eu
kubectl -n mpbx get pods
kubectl -n mpbx rollout status deploy/mpbx-api --timeout=5m
kubectl -n mpbx port-forward svc/mpbx-api 8080:80 >/dev/null 2>&1 &
pf=$!
trap 'kill "$pf" 2>/dev/null || true' EXIT
sleep 3
curl -fsS http://127.0.0.1:8080/api/v1/version
La API responde solo después de que se ejecutaron sus migraciones de base de datos. El endpoint de vitalidad /healthz está en el puerto de métricas (9464), no en el puerto de la API.
Volver a aplicar y actualizar
kubectl apply -k puede ejecutarse de nuevo en cualquier momento. El Job de inicialización crea el Secret solo si no existe, así que volver a aplicar nunca rota una clave. La plantilla de pod de un Job es inmutable: si mpbx-init todavía existe cuando cambia la imagen, elimínelo primero (kubectl -n mpbx delete job mpbx-init).
La actualización y la reversión están automatizadas en deploy/k8s/ops/upgrade y scripts/upgrade.sh. Ejecute primero --dry-run. Vea Actualización y reversión.
Puertos y cortafuegos
| Dónde | Puerto | Para qué |
|---|---|---|
| Ingress o balanceador de carga | 443/tcp | Cliente web, API, WebSocket. El componente opcional de Ingress (deploy/k8s/components/ingress) lo sirve. |
| Nodo de medios (cortafuegos de la nube) | 5060/udp y 5060/tcp | SIP. Restrínjalo a sus troncales y sitios siempre que pueda. |
| Nodo de medios (cortafuegos de la nube) | 40000-50000/udp | RTP. |
Nunca abra 5432, 6379, 8123, 9000 ni 22222 (el puerto de control de rtpengine no tiene autenticación). El paquete no crea ningún Service público para ellos.
Simulación sin clúster
Para revisar los manifiestos sin clúster, genere el overlay:
set -eu
kustomize build deploy/k8s/overlays/small >/dev/null
echo "overlay renders"
deploy/k8s/scripts/validate.sh ejecuta cada overlay con kubeconform y las invariantes de los manifiestos (no root, sistema de archivos raíz de solo lectura, excepciones de Pod Security).
Desinstalar
kubectl delete -k deploy/k8s/overlays/small
Esto elimina las cargas de trabajo. Los volúmenes persistentes y el Secret pueden permanecer; elimínelos solo después de verificar su respaldo.