Docker容器之间的通信(Keycloak和Spring)

5

我创建了一个Java Spring Boot应用程序,使用Keycloak对其用户进行身份验证。

当我从docker-compose运行Keycloak时,可以成功地在独立的jar文件或调试运行我的应用程序中进行身份验证。但是,当我将我的Spring Boot应用程序作为Docker容器放置在docker-compose中时,我无法再对用户进行身份验证。

我的Spring Boot Docker容器的错误日志:

springBootApp  | 2019-12-19 13:16:41.498 ERROR 1 --- [nio-8081-exec-2] o.k.a.rotation.JWKPublicKeyLocator       : Error when sending request to retrieve realm keys
springBootApp  | 
springBootApp  | org.keycloak.adapters.HttpClientAdapterException: IO error

我认为问题与网络有关。但是所有容器都在同一个虚拟网络中运行。它们也在同一个docker-compose文件中。

这是我的keycloak部分:

  keycloak:
    image: jboss/keycloak
    ports:
      - 18080:8080
    volumes:
        - ../keycloak:/opt/jboss/keycloak/imports
    command: 
        - "-b 0.0.0.0 -Dkeycloak.import=/opt/jboss/keycloak/imports/realm-export.json"
    environment:
              - KEYCLOAK_USER=admin
              - KEYCLOAK_PASSWORD=admin

我的Spring Boot应用程序
  mySpringBootApp:
    image: mySpringBootApp:master-1
    environment:
      - SPRING_PROFILES_ACTIVE=developmentTest
    depends_on: 
      - jaeger
      - keycloak
      - db
    ports:
      - "8081:8081"

当我从我的主机使用curl localhost:18080时,我得到了响应。但是,当我从springBootApp docker中使用curl时,我收到了连接被拒绝的错误。因此,我认为即使它们在同一个网络中,它们也无法相互访问。


我遇到了完全相同的问题,你最终是如何解决它的? - thahgr
1
实际上,你必须在 Docker 容器内使用 Keycloak 的 IP 地址。你也可以通过主机名 (keycloak:18080) 在 Docker 容器内调用 Keycloak。请查看 Docker 网络文档以获取说明。 - Kristjan
2个回答

3
请注意,您的Docker容器与其运行的主机隔离开来。 对于您的计算机,localhost与Docker容器内的localhost是不同的。
您正在使用docker-compose,并且两个服务都在同一个docker-compose.yaml配置中,这意味着您可以使用服务名称从一个服务访问同一docker-compose文件中的另一个服务。
在您的情况下,您要访问的服务名为keycloak,并且您将其端口映射为18080:8080,这意味着从您的计算机localhost 18080可访问此特定容器的端口8080。
为了访问此容器(或在docker-compose上下文中的服务),您需要将localhost替换为您的服务名称。
在您的情况下,要从mySprngBootApp容器中curl keycloak容器,您需要将lcalhost替换为服务名称,简而言之:curl keycloak:18080

1
使用 "docker exec springBootApp curl keycloak:18080" 并不起作用。我需要在 Spring Boot 应用程序 Docker 中指定其他内容才能使用 Keycloak 吗? 如何更改我的 Docker 容器,使其与本地主机一起工作? - Kristjan

-1

我会在Docker Compose中为您的服务定义网络,例如:

services:
  app:
    image: some-image
    networks:
      - my-network-name

networks:
  my-network-name:
   name: my-global-net

你可以放心,服务在同一个网络中,并通过服务名称相互通信。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接