Saltar al contenido principal

Alcanzar Zaris desde fuera del clúster: clientes externos sin un SDK nativo

· 6 min de lectura
Clustron Team
Ingeniería de Sistemas Distribuidos

Alcanzar Zaris desde fuera del clúster

Ejecuta Zaris en Kubernetes y el camino feliz es sencillo: los clientes dentro del clúster alcanzan los pods por sus direcciones internas — IPs de pod y nombres de DNS del clúster como zaris-0.zaris.svc — y todo se enruta limpiamente. En el momento en que un cliente vive fuera del clúster, eso se rompe. Una aplicación externa no puede marcar zaris-0.zaris.svc ni una IP de pod; esos nombres y direcciones solo resuelven y enrutan dentro de la red del clúster.

Esto no es una rareza de Zaris — es la división fundamental entre la red interna del clúster y el mundo exterior. Muerde con más fuerza a los clientes conscientes de la topología. Un cliente Redis en modo cluster, o cualquier cliente que descubre nodos y enruta por clave, obtiene un mapa de topología del servidor y se conecta a las direcciones que contiene. Si esas direcciones son internas, un cliente externo recibe un mapa lleno de endpoints que nunca podrá alcanzar.

Zaris resuelve esto con direcciones anunciadas, gestionadas como una "vista de frontera" por listener.

Por qué las direcciones internas del clúster fallan externamente​

Kubernetes da a cada pod una identidad interna: una IP de pod en la red del clúster, y nombres de DNS estables a través de un Service headless, como zaris-0.zaris.svc. Dentro del clúster esos enrutan perfectamente. Fuera, no tienen sentido — la red del cliente externo no tiene ruta hacia una IP de pod ni un resolver para *.svc.

Cuando Zaris responde a una solicitud de topología o redirección, devuelve direcciones. Si siempre devolviera sus direcciones internas, un cliente externo recibiría un mapa de nodos a los que no puede conectarse. Obtendría la topología, intentaría diligentemente abrir conexiones a los nodos anunciados y fallaría en cada una — aunque el clúster esté perfectamente sano.

Por qué un único endpoint LoadBalancer no basta​

El primer arreglo obvio es un único balanceador de carga delante de todo, y para clientes simples eso funciona. Pero no satisface a un cliente consciente de la topología que necesita direccionamiento por nodo.

Todo el diseño de un cliente en modo cluster consiste en obtener la lista de nodos y enrutar cada clave directamente al nodo que la posee, siguiendo redirecciones a medida que la propiedad se mueve. Para hacerlo necesita una dirección distinta y alcanzable para cada nodo — no un único endpoint compartido que los oculte a todos. Una única IP virtual no le da al cliente a dónde enviar una conexión por nodo ni una redirección. Así que cada nodo tiene que ser alcanzable de forma independiente desde fuera, y las direcciones que Zaris anuncia a los clientes externos tienen que ser esas direcciones por nodo alcanzables externamente.

Direcciones anunciadas por listener: la vista de frontera​

Esta es la idea central. Cada nodo — más precisamente, cada listener de un nodo — puede anunciar una dirección diferente a los clientes externos de la que usa internamente. Zaris trata cada listener como una frontera entre dos vistas de la topología, y traduce las direcciones que devuelve por listener.

Concretamente: cuando una solicitud llega al listener interno, Zaris rellena la respuesta de topología (las direcciones de nodo que devuelve en respuestas de cluster y de redirección) con direcciones internas. Cuando una solicitud llega al listener designado para clientes externos, rellena esa misma respuesta con la dirección anunciada externamente de cada nodo. Cada respuesta de topología o redirección se reescribe para coincidir con la frontera en la que está el cliente — a un cliente externo siempre se le indica una dirección que puede alcanzar, y a un cliente dentro del clúster se le sigue dando la dirección interna, que es la más rápida para él.

Como esto es por listener, el clúster no tiene que elegir entre ser direccionable internamente o externamente — es ambas cosas a la vez, y cada cliente obtiene la vista que coincide con el lugar por el que entró.

Validado en vivo: 200/200, ambos lados a la vez​

Esto se validó con clientes externos e internos ejecutándose simultáneamente contra el mismo clúster: 200/200 operaciones exitosas desde clientes externos e internos al mismo tiempo, con una traducción de direcciones por listener correcta — los clientes externos se conectaron a las direcciones anunciadas externamente, los clientes internos usaron las internas, y ninguna vista se filtró en la otra. Ejecutar ambos de forma concurrente es la clave: la frontera tiene que mantenerse en ambas direcciones a la vez.

El cableado de Kubernetes que sigue siendo tuyo​

Zaris hace que el direccionamiento sea correcto — entrega a cada cliente una dirección que puede alcanzar. Hacer que cada nodo sea realmente alcanzable desde fuera es red de Kubernetes, y eso sigue siendo trabajo del operador. Importan dos piezas.

Services por pod. Como los clientes externos conscientes de la topología necesitan que cada nodo sea alcanzable de forma independiente, expones los nodos individualmente — un Service por pod, cada uno dando a un nodo su propia dirección alcanzable externamente, que es exactamente la dirección que ese nodo anuncia en su listener externo.

apiVersion: v1
kind: Service
metadata:
name: zaris-0-ext
spec:
type: LoadBalancer
selector:
statefulset.kubernetes.io/pod-name: zaris-0
ports:
- name: resp
port: 6379
targetPort: 6379

A cada nodo se le indica entonces su dirección anunciada externamente:

kubectl set env statefulset/zaris \
ZARIS_ADVERTISED_ADDRESS_EXTERNAL="10.0.0.10:6379"

# Confirm an external client is handed reachable, per-node addresses.
redis-cli -h 10.0.0.10 -p 6379 CLUSTER SLOTS

SANs de TLS. Cuando TLS está habilitado, un cliente valida el certificado contra el nombre al que se conectó. Dado que los clientes externos se conectan a los nombres anunciados externamente, esos nombres deben aparecer en los Subject Alternative Names del certificado. Si un nodo anuncia 10.0.0.10 (o un nombre como redis.example.com) pero su certificado solo cubre zaris-0.zaris.svc, el handshake TLS externo falla aunque la dirección sea alcanzable. Gestionar esos SANs es trabajo del operador.

El límite honesto​

La contribución de Zaris es precisa: hace que el direccionamiento sea correcto a través de la frontera clúster/mundo exterior, por listener, de modo que a ningún cliente se le entregue jamás una dirección que no pueda usar. No aprovisiona tus balanceadores de carga ni emite tus certificados. Los Services por pod y la gestión de SANs de TLS te corresponde cablearlos a ti.

Esa es la división del trabajo correcta. La parte difícil y fácil de equivocar — traducir cada respuesta de topología y redirección a la vista correcta para el cliente que preguntó — se gestiona por ti. Una vez que la red que la rodea está en su sitio, los clientes externos e internos comparten un mismo clúster sin pisarse.