Keycloak容器无法与其他容器连接问题求助
本地以localhost运行Keycloak和API服务一切正常,但容器间连接时始终返回连接拒绝,抛出以下异常:
Caused by: org.springframework.beans.BeanInstantiationException:
Failed to instantiate
[org.springframework.security.oauth2.jwt.JwtDecoder]: Factory method
'jwtDecoder' threw exception with message: Unable to resolve the
Configuration with the provided Issuer of
"http://keycloak-authorization-server:8080/realms/microservices-realm"
Keycloak Docker配置
services: keycloak-authorization-server: image: quay.io/keycloak/keycloak:latest container_name: mykeycloak2 hostname: keycloak-server command: start-dev environment: KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin KEYCLOAK_LOGLEVEL: DEBUG DB_VENDOR: postgres JDBC_URL: jdbc:postgresql://localhost:5432/keycloak DB_PASSWORD: keycloak DB_USER: keycloak KEYCLOAK_USER: user_1 KEYCLOAK_PASSWORD: 123456 ports: - "8080:8080"
服务Docker配置
services: elastic-query-service-1: image: ${GROUP_ID}/elastic.query.service:${SERVICE_VERSION:-latest} ports: - "5008:5008" - "8183:8183" volumes: - "./docker-logs:/workspace/elastic-query-service/logs" - "./check-config-server-started.sh:/usr/local/bin/check-config-server-started.sh" user: root entrypoint: [ "check-config-server-started.sh" ] depends_on: - config-server environment: - "JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5008 -Xms128m -Xmx256m" - "LOGGING_LEVEL_COM_MICROSERVICES_DEMO=info" - "LOGGING_LEVEL_ROOT=info" - "ELASTIC-CONFIG-DATA_INDEX-NAME=twitter-index" - "ELASTIC-CONFIG-DATA_CONNECTION-URL=elastic-1:9200" - "SERVER_PORT=8183" - "SERVER_SERVLET_CONTEXT-PATH=/elastic-query-service" - "SPRING_CLOUD_CONFIG_URI=http://config-server:8888" - "ENCRYPT_KEY=${ENCRYPT_KEY}" - "SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER-URI=http://keycloak-authorization-server:8080/realms/microservices-realm" - "SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK-SET-URI=http://keycloak-authorization-server:8080/realms/microservices-realm/protocol/openid-connect/certs" - "SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_KEYCLOAK_TOKEN-URI=http://keycloak-authorization-server:8080/realms/microservices-realm/protocol/openid-connect/token" - "SPRING_DATASOURCE_URL=jdbc:postgresql://172.20.0.2:5432/postgres?currentSchema=public&binaryTransfer=true&reWriteBatchedInserts=true" networks: - ${GLOBAL_NETWORK:-services}
已省略部分运行正常的容器,尝试用localhost也出现相同错误,请问遗漏了什么配置?
1. 补全容器网络配置
你的Keycloak容器未加入服务所在的${GLOBAL_NETWORK:-services}网络,导致服务容器无法通过keycloak-authorization-server服务名解析到Keycloak实例。
修改Keycloak的Docker配置,添加网络声明:
services: keycloak-authorization-server: # 保留原有配置 networks: - ${GLOBAL_NETWORK:-services}
注:Keycloak配置中的hostname: keycloak-server不影响容器间DNS解析,Docker Compose默认以服务名作为容器间的通信地址,服务中用keycloak-authorization-server是正确的。
2. 修正Keycloak的Issuer地址一致性
Keycloak在容器中运行时,需要配置对外访问的主机名,确保它返回的Issuer地址与服务配置的SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER-URI完全一致,否则会触发配置验证失败。
给Keycloak添加环境变量:
environment: # 保留原有配置 KC_HOSTNAME: keycloak-authorization-server KC_HOSTNAME_PORT: 8080
3. 调整服务启动依赖顺序
当前服务仅依赖config-server,未等待Keycloak完全就绪就启动,可能导致服务启动时Keycloak还未完成初始化。
步骤1:给Keycloak添加健康检查
services: keycloak-authorization-server: # 保留原有配置 healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:8080/health/ready || exit 1"] interval: 10s timeout: 5s retries: 5
步骤2:修改服务的依赖配置
depends_on: - config-server - keycloak-authorization-server
4. 检查PostgreSQL连接(可选)
如果PostgreSQL是容器运行的,Keycloak配置中的JDBC_URL: jdbc:postgresql://localhost:5432/keycloak会失效(容器内的localhost指向自身),需要将PostgreSQL也加入同一网络,改用服务名访问,例如:
JDBC_URL: jdbc:postgresql://postgres-service:5432/keycloak
内容的提问来源于stack exchange,提问作者rafaelpadu

