KubeRay con vLLM abre 15 de 17 puertos que su pod spec no declara
Una prueba sobre un clúster EKS muestra sockets de Ray fuera de la definición del contenedor, alcanzables desde otro namespace por gRPC en claro
Un despliegue por defecto de KubeRay con vLLM sobre un clúster EKS acaba escuchando en más sitios de los que confiesa su pod spec. De los 17 sockets en escucha que abría Ray, 15 no figuraban entre los puertos declarados del contenedor. Y entre los que sí eran alcanzables desde un pod de otro namespace estaban el GCS de Ray en el 6379 y el RPC del raylet en el rango 10002-10006, hablando gRPC sin cifrar.
El dato sale de una sola prueba sobre un único clúster: la cifra es de quien la hizo, no de un barrido sobre varias flotas. Los datos crudos están en un repositorio de Sorami Consulting, con el material en bruto de la medición, y la guía con los pasos de endurecimiento está publicada aparte.
Los escáneres miran donde no hay que mirar
Cuatro configuraciones por defecto de escáner no inspeccionaron el recurso RayCluster. Eso deja un punto ciego concreto: la herramienta lee el pod spec, pero en KubeRay quien abre los puertos es el operador, a partir de un CRD. Lo que el contenedor declara y lo que Ray termina escuchando no tienen por qué coincidir, y quien revisa lo primero no está viendo lo segundo.
El resultado es una superficie de red que no aparece en la definición del workload y que tampoco salta en las auditorías automáticas. GCS y raylet no están pensados para exponerse fuera del clúster, y menos en claro.
La mitigación que midieron
De las opciones probadas, la más barata fue una NetworkPolicy de default-deny en el ingress del namespace: bloqueó todos los puertos de Ray que se sondearon. Es contención de red clásica, sin tocar la configuración de Ray ni del operador, aunque conviene revisar que las reglas cubran los rangos reales y no solo los declarados, porque ahí estaba justamente el problema.
Quien tenga Ray o vLLM en Kubernetes debería comprobar su caso antes de dar por buena la política heredada de una plantilla. Los rangos se pueden mover entre versiones del operador y la lista de puertos declarados no es una fuente fiable. Un ss -tlnp dentro del pod y una prueba de conectividad desde otro namespace cuestan menos que confiar en el CRD.


