【问题标题】:Docker - Tomcat and PostgreSQL containers in same host - No Route to hostDocker - 同一主机中的 Tomcat 和 PostgreSQL 容器 - 没有到主机的路由
【发布时间】:2014-07-31 22:15:53
【问题描述】:

我已经容器化了一个在 Tomcat 上运行的 Web 应用程序并使用命令启动了容器,

docker run -d -p 8080:8080 tveuser/tve-repository:tve-services

我还在使用以下命令在同一主机上运行 PostgreSQL 容器:

docker run -d  -p 80:80 -p  5432:5432 tveuser/tve-repository:tve-postgresql

我通过使用 phpPgAdmin 验证了 PostgreSQL 正在运行,但无法让 tomcat 连接到它。 'docker ps' 还告诉我两个容器都已启动并正在运行。

我通过 tomcat context.xml 将 Web 应用程序与数据库连接起来,该文件有一个类似

的条目
<Parameter name="abc.connection.url" value="jdbc:postgresql://1.2.3.4:5432/dbname" />

其中 1.2.3.4 是运行容器的 docker 主机 Ip。但是当我运行 tomcat 容器时出现以下错误:

org.postgresql.util.PSQLException: The connection attempt failed.
        at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:225)
        at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:64)
        at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:136)
...............

Caused by: java.net.NoRouteToHostException: No route to host
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)

任何帮助表示赞赏。

【问题讨论】:

    标签: postgresql tomcat containers docker


    【解决方案1】:

    TL;DR:检查主机上的防火墙

    您需要连接到您在 postgres 容器上为 postgres 公开的端口上的主机 IP 地址,而不是 docker 容器的 IP 地址。

    例如,

    <Parameter name="abc.connection.url" value="jdbc:postgresql://192.168.x.x:5432/dbname" />
    

    您还需要在您的 postgres docker 容器中配置 postgres 以侦听来自 127.0.0.1 以外的其他位置的连接,这是默认设置。

    例如,pg_hba.conf:

    host    all             all             0.0.0.0/0               md5
    

    这告诉 postgres 接受来自任何 IP 地址的传入连接(您可能希望将其锁定为 192.168.0.0/16 之类的东西。

    您还需要在postgres.conf 中更改listen_addresses 的值:

    listen_addresses = '*'      # what IP address(es) to listen on;
    

    完成这些配置更改后,您可以检查 postgres 是否正在侦听来自 docker 容器内所有 IP 的所有请求:

    netstat -tunlp
    
    Active Internet connections (only servers)                                 
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      816/postgres         
    tcp6       0      0 :::5432                 :::*                    LISTEN      816/postgres         
    

    然后从您的主机,确保您可以远程登录到端口 5432:

    telnet 192.168.x.x 5432
    Trying 192.168.x.x...
    Connected to 192.168.x.x.
    Escape character is '^]'.
    

    【讨论】:

    • 从 tomcat 容器到 postgresql 容器的 Telnet 不起作用。它说没有路由到主机。不知道为什么。我正在使用主机 IP(其中部署了 postgresql 容器)和 postgresql(5432)的端口进行 telnet
    • 好的,更新您上面的问题,并在 a) 您的主机和 b) 您的 postgres 容器上向我提供以下输出:netstat -tunlp。并添加您的 pg_hba.confpostgres.conf 文件。
    • OK 将更新。但是,当我从我的 tomcat 容器 telnet 1.2.3.4 5432 运行 telnet 命令时,其中 1.2.3.4 是部署和运行 postgresql 容器的主机 IP,而 5432 是其公开的端口号,它表示没有到主机的路由。它不是故意的吗?
    • 不,您应该能够使用您的主机 IP 和 5432 从您的 tomcat 容器远程登录到您的 postgres 容器。
    • 还有一点,你的主机有iptable规则吗?如果是,您需要允许来自docker0 接口的连接。
    【解决方案2】:

    正如 Chris McKinnel 指出的那样,将端口转发到主机并非如此。我想给你第二个解决方案来替代他的:链接。

    https://docs.docker.com/userguide/dockerlinks/

    所以你可以这样做:

    docker run -d -P --name tomcat --link postgres:postgres apache/tomcat apachectl start

    ...假设您的 PostgreSQL 容器被命名为“postgres”,它将允许您直接从 Tomcat 容器连接。

    请注意,这仅在两个容器位于同一台机器上时才有效,但听起来它们是。

    【讨论】:

    • 但是跨主机的端口转发在 docker 中是开箱即用的。问题出在主机的防火墙规则上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多