ivangfr / keycloak-clustered

Keycloak-Clustered extends quay.io/keycloak/keycloak official Keycloak Docker image by adding JDBC_PING discovery protocol.
162 stars 57 forks source link

No sharing if second Keycloak instance is deployed on different docker host #14

Closed gunterze closed 2 years ago

gunterze commented 2 years ago

No sharing on deploying second Keycloak instance on different docker host, connecting to same DB instance:

E.g.: on node1:

docker network create keycloak-net
docker run --rm --name mariadb -p 3306:3306 \
  -e MYSQL_DATABASE=keycloak \
  -e MYSQL_USER=keycloak \
  -e MYSQL_PASSWORD=password \
  -e MYSQL_ROOT_PASSWORD=root_password \
  --network keycloak-net \
  mariadb:10.7.3
docker run --rm --name keycloak-clustered-1 -p 8080:8080 \
  -e KEYCLOAK_ADMIN=admin \
  -e KEYCLOAK_ADMIN_PASSWORD=admin \
  -e KC_DB=mariadb \
  -e KC_DB_URL_HOST=mariadb \
  -e KC_DB_URL_DATABASE=keycloak \
  -e KC_DB_USERNAME=keycloak \
  -e KC_DB_PASSWORD=password \
  -e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
  -e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-1 \
  --network keycloak-net \
  ivanfranchin/keycloak-clustered:latest start-dev

On node2:

docker network create keycloak-net
docker run --rm --name keycloak-clustered-2 -p 8081:8080 \
  -e KEYCLOAK_ADMIN=admin \
  -e KEYCLOAK_ADMIN_PASSWORD=admin \
  -e KC_DB=mariadb \
  -e KC_DB_URL_HOST=node1 \
  -e KC_DB_URL_DATABASE=keycloak \
  -e KC_DB_USERNAME=keycloak \
  -e KC_DB_PASSWORD=password \
  -e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
  -e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-2 \
  --network keycloak-net \
  ivanfranchin/keycloak-clustered:latest start-dev

Select entries in JGROUPSPING table:

MariaDB [keycloak]> SELECT * FROM JGROUPSPING;
+--------------------------------------+--------------+----------------------+---------------------+---------------------------------------------------+
| own_addr                             | cluster_name | bind_addr            | updated             | ping_data                                         |
+--------------------------------------+--------------+----------------------+---------------------+---------------------------------------------------+
| d67525d8-605f-40da-bacc-db3b0525ef79 | ISPN         | keycloak-clustered-2 | 2022-05-12 15:10:36 | ���;%�y�u%�`_@� fce00d6c5459-41359� x�� |
+--------------------------------------+--------------+----------------------+---------------------+---------------------------------------------------+
1 row in set (0.001 sec)

returns only 1 record. The record inserted by first started instance got replaced by the record inserted by the second instance started after.

A may be (un-)related observation: Deploying both keycloak instances on the same docker host as described by https://github.com/ivangfr/keycloak-clustered#readme selects 2 records:

MariaDB [keycloak]> SELECT * FROM JGROUPSPING;
+--------------------------------------+--------------+----------------------+---------------------+---------------------------------------------------+
| own_addr                             | cluster_name | bind_addr            | updated             | ping_data                                         |
+--------------------------------------+--------------+----------------------+---------------------+---------------------------------------------------+
| 50225a8d-4cef-4923-90d2-2d7bac85a076 | ISPN         | keycloak-clustered-1 | 2022-05-12 14:49:20 | ��-{���vP"Z�L�I# ac8d1bb0e981-2409� x��  |
| bbc842a4-9b19-4869-a30a-a73d868ef618 | ISPN         | keycloak-clustered-1 | 2022-05-12 14:49:20 | �
�=�����B��Hi ac6ebd1b64e3-47267� x�� |
+--------------------------------------+--------------+----------------------+---------------------+---------------------------------------------------+
2 rows in set (0.001 sec)

with equal bind_addr (=that of the first started keycloak instance) !?

ivangfr commented 2 years ago

Hi @gunterze

About deploying both Keycloak instances on the same docker host, I also didn't get why both instances have the same bind_addr in JGROUPSPING tables. But, it works in the end, i.e, the cluster is formed. That is the most important thing.

About deploying the instance on different docker hosts, I tried to reproduce it using the Vagrant environment (Virtualbox) as described in the README - Running a Keycloak Cluster using JDBC_PING in Virtual Machines

In fact, I successfully got a Keycloak cluster running, even having MariaDB, Keycloak1 and Keycloak2 on completely different machines.

Screenshot 2022-05-12 at 23 39 27
gunterze commented 2 years ago

Just forgot to export the JGroups TCP port (default: 7800). Made the port configurable by an ENV in my cache configuration file:

<TCP external_addr="${env.JGROUPS_DISCOVERY_EXTERNAL_IP:127.0.0.1}" bind_addr="${env.JGROUPS_BIND_IP}" bind_port="${env.JGROUPS_TCP_PORT:7800}" />

Enabling to specify also the bind addr was needed for deploying on Docker Swarm...