K8s部署Keycloak数据丢失且不写入MySQL,如何实现持久化?
Keycloak K8s部署数据持久化问题修复方案
问题根源
- 环境变量不兼容:Keycloak 21.x基于Quarkus重构,彻底废弃了JBoss时代的
DB_*前缀环境变量,你当前配置的DB_VENDOR、DB_ADDR等参数完全不生效,导致Keycloak默认使用内置H2内存数据库,Pod重建后数据直接丢失。 - 持久化卷挂载无效:你挂载的
/opt/jboss/keycloak/startup/elements不是Keycloak存储数据的路径,就算用H2也没法持久化数据,更别说你本来想连接MySQL。
修复步骤
1. 替换为兼容的环境变量(核心操作)
更新你的ConfigMap和Secret,改用Keycloak 21.x要求的KC_DB_*前缀变量:
更新后的配置映射(ConfigMap)
KC_DB_DATABASE=kc_db
更新后的密钥映射(Secret)
KC_DB=mysql KC_DB_URL_HOST=mysql-svc KC_DB_USERNAME=foo KC_DB_PASSWORD=fooo KEYCLOAK_ADMIN=admin KEYCLOAK_ADMIN_PASSWORD=pwd KC_LOG_LEVEL=ALL
变量说明:
KC_DB=mysql指定数据库类型为MySQLKC_DB_URL_HOST对应原配置里的DB_ADDRKC_DB_USERNAME/KC_DB_PASSWORD替换原DB_USER/DB_PASSWORDKC_LOG_LEVEL替换原KEYCLOAK_LOGLEVEL
2. 清理无用的持久化挂载
既然改用MySQL做数据持久化,原来的volumeMounts和volumes配置完全没用,直接从Deployment里删除以下内容:
volumeMounts: - mountPath: /opt/jboss/keycloak/startup/elements name: kc-ps volumes: - name: kc-ps persistentVolumeClaim: claimName: keycloak-pv-claim
如果之后需要挂载自定义主题、启动脚本等,再按需添加对应路径的挂载。
3. 验证MySQL连通性
先确保mysql-svc服务能正常访问,且MySQL中已经创建了kc_db数据库,用户foo拥有该库的读写权限。可以用以下命令快速验证:
kubectl run -it --rm --image=mysql:8.0 mysql-test -- mysql -h mysql-svc -u foo -pfooo kc_db
能成功进入MySQL命令行就说明网络和权限没问题。
4. 重新部署Keycloak
删除旧的资源后重新应用更新后的配置:
kubectl delete deployment kc-dp kubectl delete configmap kc-env kubectl delete secret kc-secret # 依次应用更新后的配置文件 kubectl apply -f your-updated-configmap.yaml kubectl apply -f your-updated-secret.yaml kubectl apply -f your-deployment.yaml
额外提示
- 开发环境用
start-dev没问题,但生产环境建议改用start模式,并强制配置HTTPS。 - 如果只是开发测试想用本地文件持久化(不用MySQL),需要挂载Keycloak的正确数据路径:
/opt/keycloak/data,这个路径存储H2数据库文件和其他运行数据。
内容的提问来源于stack exchange,提问作者HittingMyCode
相关产品推荐
相关产品推荐

