Coherence. Crear un nodo de tipo proxy con Coherence Operator.
En una entrada anterior desplegamos un cluster de Oracle Coherence en OKE con Coherence Operator. En esta entrada añadiremos un punto de entrada para clientes remotos usando Coherence*Extend.
Coherence*Extend permite que clientes que no forman parte del cluster se conecten a través de un ProxyService. En Kubernetes esto encaja muy bien con un servicio interno ClusterIP para pruebas o consumo dentro del cluster, y con un LoadBalancer de OKE cuando necesitamos exponerlo fuera.
La arquitectura del ejemplo será la siguiente:
- Un despliegue
Coherencepara miembros de almacenamiento. - Un despliegue
Coherenceseparado para miembros proxy, constorageEnabled: false. - Un puerto
extendescuchando en20000. - Acceso local mediante
kubectl port-forward. - Exposición opcional mediante un Service
LoadBalancer.
Separar storage y proxy no es obligatorio, pero suele ser más limpio: puedes escalar proxies sin tocar el número de miembros de almacenamiento.
Configuración de caché para los miembros storage
Primero mantenemos una configuración de almacenamiento sencilla en storage-cache-config.xml:
<?xml version="1.0"?>
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
<caching-scheme-mapping>
<cache-mapping>
<cache-name>test*</cache-name>
<scheme-name>distributed</scheme-name>
</cache-mapping>
</caching-scheme-mapping>
<caching-schemes>
<distributed-scheme>
<scheme-name>distributed</scheme-name>
<service-name>DistributedCache</service-name>
<backing-map-scheme>
<local-scheme/>
</backing-map-scheme>
<autostart>true</autostart>
</distributed-scheme>
</caching-schemes>
</cache-config>
Configuración del proxy Extend
Creamos ahora proxy-cache-config.xml. La parte importante es el proxy-scheme, que escucha en 0.0.0.0 para que Kubernetes pueda enrutar tráfico al contenedor.
<?xml version="1.0"?>
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
<caching-scheme-mapping>
<cache-mapping>
<cache-name>test*</cache-name>
<scheme-name>distributed</scheme-name>
</cache-mapping>
</caching-scheme-mapping>
<caching-schemes>
<distributed-scheme>
<scheme-name>distributed</scheme-name>
<service-name>DistributedCache</service-name>
<backing-map-scheme>
<local-scheme/>
</backing-map-scheme>
<autostart>true</autostart>
</distributed-scheme>
<proxy-scheme>
<service-name>ExtendTcpProxyService</service-name>
<acceptor-config>
<tcp-acceptor>
<local-address>
<address system-property="coherence.extend.address">0.0.0.0</address>
<port system-property="coherence.extend.port">20000</port>
</local-address>
</tcp-acceptor>
</acceptor-config>
<load-balancer>client</load-balancer>
<autostart>true</autostart>
</proxy-scheme>
</caching-schemes>
</cache-config>
La imagen de aplicación debe incluir ambos ficheros:
files/
conf/
storage-cache-config.xml
proxy-cache-config.xml
lib/
...tus jars si los necesitas...
Construimos una nueva versión y la publicamos en OCIR:
docker build -t coherence-demo:1.0.1 .
docker tag coherence-demo:1.0.1 \
fra.ocir.io/<ocir-namespace>/coherence-demo:1.0.1
docker push fra.ocir.io/<ocir-namespace>/coherence-demo:1.0.1
Desplegar miembros de almacenamiento
coherence-storage.yaml:
apiVersion: coherence.oracle.com/v1
kind: Coherence
metadata:
name: coherence-storage
namespace: coherencetest
spec:
replicas: 3
image: fra.ocir.io/<ocir-namespace>/coherence-demo:1.0.1
imagePullSecrets:
- name: ocirsecret
jvm:
memory:
heapSize: 2g
coherence:
cacheConfig: storage-cache-config.xml
storageEnabled: true
Aplicamos:
kubectl apply -f coherence-storage.yaml
kubectl -n coherencetest get pods
Desplegar miembros proxy
Creamos otro recurso Coherence para el tier de proxy.
coherence-proxy.yaml:
apiVersion: coherence.oracle.com/v1
kind: Coherence
metadata:
name: coherence-proxy
namespace: coherencetest
spec:
replicas: 2
image: fra.ocir.io/<ocir-namespace>/coherence-demo:1.0.1
imagePullSecrets:
- name: ocirsecret
ports:
- name: extend
port: 20000
coherence:
cacheConfig: proxy-cache-config.xml
storageEnabled: false
wka:
deployment: coherence-storage
El campo wka.deployment indica al tier de proxy que debe descubrir el cluster de storage a través del despliegue coherence-storage.
Aplicamos:
kubectl apply -f coherence-proxy.yaml
kubectl -n coherencetest get pods
kubectl -n coherencetest get svc
El Operator debe crear un servicio para el puerto extend, normalmente con un nombre parecido a:
coherence-proxy-extend
Compruébalo con:
kubectl -n coherencetest get svc | grep extend
Probar con port-forward
Antes de publicar nada fuera del cluster, probamos localmente:
kubectl -n coherencetest port-forward svc/coherence-proxy-extend 20000:20000
En el cliente Extend usamos 127.0.0.1:20000. Ejemplo de client-cache-config.xml:
<?xml version="1.0"?>
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
<caching-scheme-mapping>
<cache-mapping>
<cache-name>test*</cache-name>
<scheme-name>remote</scheme-name>
</cache-mapping>
</caching-scheme-mapping>
<caching-schemes>
<remote-cache-scheme>
<scheme-name>remote</scheme-name>
<service-name>ExtendTcpCacheService</service-name>
<initiator-config>
<tcp-initiator>
<remote-addresses>
<socket-address>
<address system-property="proxy.address">127.0.0.1</address>
<port system-property="proxy.port">20000</port>
</socket-address>
</remote-addresses>
</tcp-initiator>
</initiator-config>
</remote-cache-scheme>
</caching-schemes>
</cache-config>
Prueba conceptual con la consola o con un cliente Java:
Map (?): cache test1
Map (test1): put mykey myvalue
Map (test1): get mykey
myvalue
Map (test1): bye
Exponer el proxy fuera del cluster
Para consumo interno desde otros pods, no necesitas LoadBalancer. Puedes usar el DNS interno:
coherence-proxy-extend.coherencetest.svc.cluster.local:20000
Si necesitas acceder desde fuera de OKE, crea un Service de tipo LoadBalancer. Antes de definir el selector, mira las etiquetas reales de los pods:
kubectl -n coherencetest get pods \
-l coherence.oracle.com/deployment=coherence-proxy \
--show-labels
Un ejemplo de Service externo sería:
apiVersion: v1
kind: Service
metadata:
name: coherence-proxy-extend-lb
namespace: coherencetest
annotations:
oci.oraclecloud.com/load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
coherence.oracle.com/deployment: coherence-proxy
ports:
- name: extend
protocol: TCP
port: 20000
targetPort: 20000
loadBalancerSourceRanges:
- 203.0.113.0/24
Aplicamos:
kubectl apply -f coherence-proxy-extend-lb.yaml
kubectl -n coherencetest get svc coherence-proxy-extend-lb
Cuando OKE asigne IP pública, veremos algo similar a:
NAME TYPE EXTERNAL-IP PORT(S)
coherence-proxy-extend-lb LoadBalancer 131.141.250.155 20000/TCP
Entonces el cliente puede usar:
-Dproxy.address=131.141.250.155 -Dproxy.port=20000
Seguridad: no publiques Extend sin controles
Publicar un proxy Extend en Internet sin controles no es una buena idea. Antes de hacerlo en producción, revisa como mínimo:
- Usar un load balancer privado y entrar por VPN, FastConnect o bastión.
- Restringir rangos de origen con
loadBalancerSourceRanges, NSGs o security lists. - Activar TLS en el proxy y en los clientes.
- Definir autenticación y autorización si aplica en tu arquitectura.
- Usar Network Policies para limitar qué pods pueden hablar con el proxy.
- Monitorizar conexiones, errores y latencia del proxy.
- Escalar proxies de forma independiente del tier de storage.
Escalado del proxy
El tier de proxy se escala igual que cualquier recurso Coherence:
kubectl -n coherencetest scale coherence/coherence-proxy --replicas=3
Comprueba que el Service reparte tráfico hacia los nuevos pods:
kubectl -n coherencetest get endpoints coherence-proxy-extend
Limpieza
kubectl -n coherencetest delete svc coherence-proxy-extend-lb
kubectl -n coherencetest delete coherence coherence-proxy
kubectl -n coherencetest delete coherence coherence-storage
Conclusión
Un proxy Coherence*Extend permite que clientes externos al cluster consuman cachés de Coherence sin convertirse en miembros del cluster. En Kubernetes, una forma clara de organizarlo es separar los miembros de storage y los miembros proxy, exponiendo el puerto Extend solo donde sea necesario.
El patrón de trabajo queda así:
- Mantener los miembros de storage separados de los proxies.
- Exponer el puerto Extend con
spec.ports. - Probar primero con
kubectl port-forward. - Usar
LoadBalancersolo cuando haya una necesidad real. - No abrir el proxy a Internet sin TLS, filtrado de origen y controles de red.
Enlaces útiles
- Documentación de Coherence Operator
- Ejemplos de Coherence Operator
- Documentación de Oracle Coherence
- Load balancers en OKE

Superb Blog, das pure Leidenschaft strahlt … Beatrice Fredrick Anuska