Publicado: 22 ago 2025
Recientemente tuve que resolver un problema bastante curioso con la conexión a Kafka. Surgió la necesidad de conectarse a un clúster externo de Kafka desde un entorno seguro. Se introducen en el cliente de Python tres nodos del clúster, cuyas direcciones se conocen. Los pods en el entorno seguro no tienen acceso directo a Internet. Todas las solicitudes HTTP se realizan a través de un proxy levantado especialmente. Pero Kafka no funciona por HTTP. Para tales propósitos, el proxy tiene un modo especial: en los encabezados HTTP se transmite el host y el puerto al cual se requiere abrir un túnel; después del intercambio de encabezados, la conexión HTTP permanece activa. Luego, el socket de esta conexión HTTP se puede utilizar como un túnel TCP al puerto deseado. Pero hay un problema: no se puede pasar un socket al cliente de Kafka para la conexión.
Dentro del mismo proceso de Python se levanta un socket que escucha en el puerto local y en la interfaz de loopback, y se hace un proxy de todo el tráfico al socket HTTP obtenido del proxy externo. El cliente de Kafka, a su vez, se conecta al puerto local.
Pero no es suficiente tener conexión solo a un nodo del clúster. Al conectarse a cualquiera de los nodos, el cliente recibe la topología actual del clúster y, para un funcionamiento estable, debe tener la capacidad de conectarse a cualquiera de los nodos. No se puede resolver solo con un túnel. Abrir un túnel hacia cada uno de los hosts objetivo no es un problema, pero de alguna manera es necesario informar sobre estos túneles al cliente de Kafka.
A nivel de transporte no podemos organizar el enrutamiento por dominio, pero es necesario conectarse a la misma interfaz loopback. Por otro lado, nada impide crear nuevas interfaces virtuales loopback y asignar a cada una de ellas, en el archivo hosts, uno de los dominios del clúster Kafka. Después de esto, para el cliente Kafka, todo comienza a funcionar de manera completamente transparente.