Быстро развертывайте кластеры высокой доступности Keycloak в рабочей среде с помощью Docker.

Docker

Развертывание Keycloak на одном компьютере очень простое, и предыдущие статьи о приложении Keycloak также используются для развертывания на одном компьютере. Однако в реальной производственной среде Keycloak, как базовая служба проверки подлинности, вынуждена развертывать несколько экземпляров для формирования кластера для обеспечения высокой доступности. В этой статье описывается, как использовать Docker для быстрого развертывания кластера высокой доступности Keycloak в производственной среде.

Проблемы, которые необходимо решить при развертывании кластера Keycloak

По умолчанию пользователь, роль и другая информация о данных и сеансы нескольких экземпляров Keycloak не синхронизируются, поэтому основное внимание при развертывании кластера уделяется решению следующих двух проблем:

  • Разделение области, клиента, пользователя, роли и других данных или синхронизация экземпляров Keycloak в кластере
  • Совместное использование сеансов или синхронизация экземпляров Keycloak в кластере

Совместное использование данных экземпляра Keycloak

Keycloak по умолчанию использует встроенную базу данных H2 в качестве хранилища данных, поэтому для обеспечения совместного использования данных нам нужно только заменить H2 внешней общей базой данных. Keycloak официально поддерживает MySQL, PostgreSQL, Oracle, SQL Server и другие базы данных.

Синхронизация сеанса Keycloak

Чтобы синхронизировать сеансы между несколькими экземплярами Keycloak, вам необходимо настроить экземпляр Keycloak для реализации автоматического обнаружения. Обратитесь к официальному блогу Keycloak:Keycloak Cluster Setup, есть несколько способов сделать это. С точки зрения фактической производительности, наиболее рекомендуемое использованиеJDBC_PINGРеализовать автоматическое обнаружение.

Docker развертывает шаги кластера Keycloak

Создавайте образы Docker, поддерживающие автоматическое обнаружение

Официальный Docker-образ Keycloak поддерживает внешнюю общую базу данных, но не интегрирует механизм автоматического обнаружения, поэтому нам нужно построить его на основе официального образа, чтобы интегрировать функцию автоматического обнаружения.

FROM jboss/keycloak:latest

ADD cli/TCPPING.cli /opt/jboss/tools/cli/jgroups/discovery/
ADD cli/JDBC_PING.cli /opt/jboss/tools/cli/jgroups/discovery/

Здесь речь пойдет о JDBC_PING.cli, в официальном блоге представлена ​​только версия для MySQL.

embed-server --server-config=standalone-ha.xml --std-out=echo

batch

/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:2})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=authenticationSessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:2})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:write-attribute(name=owners, value=${env.CACHE_OWNERS:2})
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:write-attribute(name=owners, value=${env.CACHE_OWNERS:2})

/subsystem=jgroups/stack=tcp:remove()
/subsystem=jgroups/stack=tcp:add()
/subsystem=jgroups/stack=tcp/transport=TCP:add(socket-binding="jgroups-tcp")
/subsystem=jgroups/stack=tcp/protocol=JDBC_PING:add()
/subsystem=jgroups/stack=tcp/protocol=JDBC_PING/property=datasource_jndi_name:add(value=java:jboss/datasources/KeycloakDS)

/subsystem=jgroups/stack=tcp/protocol=JDBC_PING/property=initialize_sql:add(value="CREATE TABLE IF NOT EXISTS JGROUPSPING (own_addr varchar(200) NOT NULL, cluster_name varchar(200) NOT NULL, updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, ping_data varbinary(5000) DEFAULT NULL, PRIMARY KEY (own_addr, cluster_name)) ENGINE=InnoDB DEFAULT CHARSET=utf8")

/subsystem=jgroups/stack=tcp/protocol=MERGE3:add()
/subsystem=jgroups/stack=tcp/protocol=FD_SOCK:add(socket-binding="jgroups-tcp-fd")
/subsystem=jgroups/stack=tcp/protocol=FD:add()
/subsystem=jgroups/stack=tcp/protocol=VERIFY_SUSPECT:add()
/subsystem=jgroups/stack=tcp/protocol=pbcast.NAKACK2:add()
/subsystem=jgroups/stack=tcp/protocol=UNICAST3:add()
/subsystem=jgroups/stack=tcp/protocol=pbcast.STABLE:add()
/subsystem=jgroups/stack=tcp/protocol=pbcast.GMS:add()
/subsystem=jgroups/stack=tcp/protocol=pbcast.GMS/property=max_join_attempts:add(value=5)
/subsystem=jgroups/stack=tcp/protocol=MFC:add()
/subsystem=jgroups/stack=tcp/protocol=FRAG3:add()

/subsystem=jgroups/stack=udp:remove()
/subsystem=jgroups/channel=ee:write-attribute(name=stack, value=tcp)
/socket-binding-group=standard-sockets/socket-binding=jgroups-mping:remove()

run-batch

try
    :resolve-expression(expression=${env.JGROUPS_DISCOVERY_EXTERNAL_IP})
    /subsystem=jgroups/stack=tcp/transport=TCP/property=external_addr/:add(value=${env.JGROUPS_DISCOVERY_EXTERNAL_IP})
catch
    echo "JGROUPS_DISCOVERY_EXTERNAL_IP maybe not set."
end-try

stop-embedded-server

Если вы хотите использовать другую базу данных, вам необходимоinitialize_sqlЗаменяются части, такие как использование PostgreSQL, соответствующиеinitialize_sqlследующее

/subsystem=jgroups/stack=tcp/protocol=JDBC_PING/property=initialize_sql:add(value="CREATE TABLE IF NOT EXISTS JGROUPSPING (own_addr varchar(200) NOT NULL, cluster_name varchar(200) NOT NULL, updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ping_data bytea DEFAULT NULL, PRIMARY KEY(own_addr, cluster_name))")

Я создал образ Keycloak, который поддерживает развертывание кластера. Если вы не хотите создавать его самостоятельно, вы можете использовать его напрямую.vigoz/keycloak-haЭтот образ поддерживает MySQL и PostgreSQL.

Развернуть базу данных

В соответствии с фактическими потребностями база данных, развернутая в Keycloak для хранения данных, таких как MySQL, PostgreSQL и т. д., эта часть не является предметом этой статьи, и есть много справочных материалов, которые здесь пропущены.

Запуск нескольких экземпляров со встроенными образами

Возьмем в качестве примера использование базы данных PostgreSQL, здесь запущено 2 экземпляра.

запустить keycloak1

docker run -d --name keycloak1 --restart=always \
    -p 8080:8080 \
    -p 8443:8443 \
    -p 8009:8009 \
    -p 9990:9990 \
    -p 7600:7600 \
    -p 57600:57600 \
    -e KEYCLOAK_USER=admin \
    -e KEYCLOAK_PASSWORD=admin \
    -e DB_VENDOR=postgres \
    -e DB_ADDR=localhost \
    -e DB_PORT=5432 \
    -e DB_DATABASE=keycloak \
    -e DB_SCHEMA=public \
    -e DB_USER=keycloak \
    -e DB_PASSWORD=password \
    -e JGROUPS_DISCOVERY_PROTOCOL=JDBC_PING \
    -e JGROUPS_DISCOVERY_EXTERNAL_IP=172.31.72.101 \
    -e PROXY_ADDRESS_FORWARDING=true \
    -e KEYCLOAK_FRONTEND_URL=https://your-domain/auth \
    vigoz/keycloak-ha:10.0.0-postgres

запустить keycloak2

docker run -d --name keycloak2 --restart=always \
    -p 8080:8080 \
    -p 8443:8443 \
    -p 8009:8009 \
    -p 9990:9990 \
    -p 7600:7600 \
    -p 57600:57600 \
    -e KEYCLOAK_USER=admin \
    -e KEYCLOAK_PASSWORD=admin \
    -e DB_VENDOR=postgres \
    -e DB_ADDR=localhost \
    -e DB_PORT=5432 \
    -e DB_DATABASE=keycloak \
    -e DB_SCHEMA=public \
    -e DB_USER=keycloak \
    -e DB_PASSWORD=password \
    -e JGROUPS_DISCOVERY_PROTOCOL=JDBC_PING \
    -e JGROUPS_DISCOVERY_EXTERNAL_IP=172.31.72.102 \
    -e PROXY_ADDRESS_FORWARDING=true \
    -e KEYCLOAK_FRONTEND_URL=https://your-domain/auth \
    vigoz/keycloak:10.0.0-postgres

Описание переменной среды Docker

KEYCLOAK_USER: Имя администратора Keycloak

KEYCLOAK_PASSWORD: Пароль администратора Keycloak

DB_VENDOR: используемый тип базы данных

DB_ADDR: адрес базы данных

DB_PORT: порт базы данных

DB_DATABASE: имя библиотеки базы данных

DB_SCHEMA: Схема базы данных

DB_USER:имя пользователя базы данных

DB_PASSWORD: пароль базы данных

JGROUPS_DISCOVERY_PROTOCOL: автоматическое обнаружение протокола, рекомендуется использовать JDBC_PING

JGROUPS_DISCOVERY_EXTERNAL_IP: внешний IP-адрес, этот IP-адрес должен быть установлен на IP-адрес компьютера, на котором находится экземпляр Docker, чтобы гарантировать, что несколько экземпляров могут взаимодействовать друг с другом.

PROXY_ADDRESS_FORWARDING: переадресация прокси-адреса, значение true, если перед Keycloak выполняется балансировка нагрузки.

KEYCLOAK_FRONTEND_URL: Базовый адрес для внешнего доступа к Keycloak

После вышеперечисленных действий запускается кластер Keycloak, состоящий из 2 экземпляров.

Настроить балансировку нагрузки

На последнем шаге нам также необходимо настроить балансировщик нагрузки перед Keycloak, чтобы обеспечить единую запись внешнего доступа и перенаправить трафик на несколько экземпляров Keycloak.

Используйте справочник по конфигурации nginx следующим образом:

upstream keycloak {
    server 172.31.72.101:8080;
    server 172.31.72.102:8080;
}

server {
    server_name your-domain;
    location / {
        proxy_pass http://keycloak;
    }
    listen 443 ssl;
    ssl_certificate /path/to/your-domain.cer;
    ssl_certificate_key /path/to/your-domain.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
}

server {
    if ($host = your-domain) {
        return 301 https://$host$request_uri;
    }
    server_name your-domain;
    listen 80;
    return 404;
}

Суммировать

Использование Docker для развертывания высокодоступных кластеров Keycloak очень простое и эффективное, после настройки базы данных и балансировки нагрузки его можно использовать в производственной среде, что очень удобно.

Адрес докерфайла:keycloak-ha

Адрес образа докера:keycloak-ha