¿Cómo expongo los servicios TCP no HTTP en Kubernetes?

8

Estoy ejecutando un clúster de Kubernetes en una nube pública (Azure / AWS / Google Cloud), y tengo algunos servicios que no son HTTP que me gustaría exponer para los usuarios.

Para los servicios HTTP, normalmente usaría un recurso Ingress para exponer ese servicio públicamente a través de una entrada DNS direccionable.

Para servicios no basados ​​en HTTP, basados ​​en TCP (por ejemplo, una base de datos como PostgreSQL), ¿cómo debo exponerlos para el consumo público?

Pensé en usar los NodePortservicios, pero esto requiere que los nodos sean accesibles públicamente (confiando en la kube-proxyruta al nodo apropiado). Prefiero evitar esto si es posible.

LoadBalancerLos servicios parecen otra opción, aunque no quiero crear un equilibrador de carga en la nube dedicado para cada servicio TCP que quiero exponer.

Soy consciente de que el controlador NGINX Ingress admite la exposición de servicios TCP y UDP , pero eso parece requerir una definición estática de los servicios que le gustaría exponer. Para mi caso de uso, estos servicios se crean y destruyen dinámicamente, por lo que no es posible definir estas asignaciones de servicios por adelantado en una estática ConfigMap.

cjheppell
fuente

Respuestas:

1

Quizás este flujo de trabajo pueda ayudar:

(Supongo que el proveedor de la nube es AWS)

  • Consola de AWS: cree una VPC segregada y cree sus instancias Kubernetes ec2 (o grupo de autoescalado) deshabilitando la creación de IP pública. Esto hace que sea imposible acceder a la instancia desde Internet, aún puede acceder a través de la IP privada (por ejemplo, 172.30.1.10) a través de una VPN de sitio 2 o a través de una instancia ec2 secundaria en la misma VPC con IP pública.

  • Kubernetes: Cree un servicio con un NodePort fijo (por ejemplo, 35432 para Postgres).

  • Consola de AWS: cree un Loadblancer Classic o Layer 4 dentro de la misma VPC de sus nodos, en la pestaña Listeners abra el puerto 35432 (y otros puertos que pueda necesitar) apuntando a uno o todos sus nodos a través de un "Grupo objetivo". No hay cargo en el número de puertos.

En este punto, no sé cómo automatizar la actualización de los nodos vivos actuales en el grupo objetivo de Load Balancer, esto podría ser un problema con las funciones de escalado automático, si las hay ... Tal vez un trabajo de Cron con una secuencia de comandos bash información de la API de AWS y actualizar el grupo objetivo?

Hugo V
fuente
Gracias, esto es útil. Aunque, obviamente, esta no es una solución genérica para cualquier entorno de Kubernetes y está estrechamente vinculada al proveedor de la nube de elección. ¿Quizás un operador podría ser una buena opción para una solución que oculta los detalles del proveedor de nube elegido?
cjheppell
0

Para servicios no basados ​​en HTTP, basados ​​en TCP (por ejemplo, una base de datos como PostgreSQL), ¿cómo debo exponerlos para el consumo público?

Bueno, ¿eso depende de cómo espera que el usuario final se dirija a esos Servicios? Como señaló, con un Ingress, es posible usar un alojamiento virtual para enrutar todas las solicitudes al mismo controlador de Ingress, y luego usar el Host:encabezado para enviar dentro del clúster.

Con un servicio TCP, como PostgreSQL, no existe ese encabezado. Por lo tanto, necesariamente debe tener un mecanismo basado en IP o asignar a cada uno un puerto dedicado en su IP con conexión a Internet

Si sus clientes conocen IPv6, asignar a cada Servicio una dirección IP dedicada es absolutamente razonable, dado el espacio de IP absolutamente masivo que ofrece IPv6. Pero de lo contrario, tiene dos botones para activar: la IP y el puerto.

A partir de ahí, cómo enrutará esas conexiones dentro de su clúster hacia el Servicio correcto dependerá de cómo resolvió el primer problema

mdaniel
fuente
Gracias por tu respuesta. Entiendo que cada servicio expone su propio puerto único. Mi problema es que los tipos de servicio actuales de Kubernetes no parecen apropiados para mi caso de uso. NodePorts requieren abrir los puertos en los nodos públicamente, lo que no es ideal desde el punto de vista de la seguridad. LoadBalancer por servicio es costoso. Suponiendo que puedo enrutar correctamente al host, ¿qué servicio de Kubernetes debería usar para hacer que los usuarios puedan conectarse públicamente, particularmente cuando se activan y desactivan dinámicamente?
cjheppell