keycloak 微服务认证_使用Docker快速部署Keycloak高可用集群,少了环境变量还行吗?

Keycloak单机部署非常的简单,前面的关于Keycloak应用相关的文章中也都是使用的单机部署。但是在真正的生产环境中,Keycloak作为基础的身份认证服务,势必要部署多个实例组成集群以保证高可用性。本文讲述如何使用Docker在生产环境快速部署Keycloak高可用集群。

84fc54504b3396ca6afc76645ed89516.png

Keycloak集群部署需要解决的问题

默认情况下,多个Keycloak实例的用户、角色等数据信息以及Session是不同步的,所以部署集群重点是要解决以下2个问题:

集群内Keycloak实例的Realm、客户端、用户、角色等数据共享或者同步

集群内Keycloak实例的Session共享或者同步

Keycloak实例数据共享

Keycloak默认使用内嵌的H2数据库作为数据存储,所以为了实现数据共享,我们只需要将H2替换成外置的共享数据库即可。Keycloak官方支持MySQL、PostgreSQL、Oracel、SQL Server等数据库。

Keycloak Session同步

要想让Keycloak多个实例之间的Session进行同步,需要对Keycloak的实例进行配置以实现自动发现。参考Keycloak官方博客:Keycloak Cluster Setup ,有多种方式可以实现。从实际的表现来看,最推荐使用JDBC_PING实现自动发现。

Docker部署Keycloak集群步骤

构建支持自动发现机制的Docker镜像

Keycloak官方的Docker镜像有对外置共享数据库的支持,但是并没有集成自动发现机制,所以需要我们基于官方的镜像进行构建以集成自动发现功能。

FROM jboss/keycloak:latestADD 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=echobatch/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-batchtry    :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-trystop-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:数据库Schema
  • DB_USER:数据库用户名
  • DB_PASSWORD:数据库密码
  • JGROUPS_DISCOVERY_PROTOCOL:自动发现协议,建议使用JDBC_PING
  • JGROUPS_DISCOVERY_EXTERNAL_IP:外部IP,此IP需设置为Docker实例所在机器的IP,确保多个实例间可以通信
  • PROXY_ADDRESS_FORWARDING:代理地址转发,Keycloak前有负载均衡时需设为true
  • KEYCLOAK_FRONTEND_URL:Keycloak外部访问的基础地址

经过以上的步骤,就运行了一个由2个实例组成的Keycloak集群。

配置负载均衡

最后一步,我们还需要在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高可用集群非常的简单高效,配置好数据库及负载均衡后即可在生产环境使用,非常的方便。

作者:vigoz
链接:https://juejin.im/post/5eca8143e51d4578a2554509

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值