Linux 上的 docker-compose `host-gateway` 无法连接到 RPC (v20.10.1)
Posted
技术标签:
【中文标题】Linux 上的 docker-compose `host-gateway` 无法连接到 RPC (v20.10.1)【英文标题】:docker-compose `host-gateway` on Linux cannot connect to RPC (v20.10.1) 【发布时间】:2021-04-06 08:09:38 【问题描述】:随着 Docker 20.10
的出现,host-gateway
应该可以在 Linux 平台上使用(详见 this 精彩回答)。因此,应该可以创建一个与平台无关的docker-compose
脚本。 (我自己在 Debian 上。)
这里有一些问题和答案的链接,这些链接有助于我走到这一步:here、here 和 here(以及其他一些答案和 cmets)
我正在尝试创建一个用于运行 The Graph 的脚本,其中包括在 Docker 容器内运行 ipfs
和 postgres
,并连接到 Docker 外部的区块链实例(在端口 8545 上)。这是脚本:
version: '3'
services:
graph-node:
extra_hosts:
- "host.docker.internal:host-gateway"
image: graphprotocol/graph-node
ports:
- '8000:8000'
- '8001:8001'
- '8020:8020'
- '8030:8030'
- '8040:8040'
depends_on:
- ipfs
- postgres
environment:
postgres_host: postgres
postgres_user: graph-node
postgres_pass: let-me-in
postgres_db: graph-node
ipfs: 'ipfs:5001'
ethereum: 'localhost:http://host.docker.internal:8545'
RUST_LOG: info
ipfs:
image: ipfs/go-ipfs:v0.4.23
ports:
- '5001:5001'
volumes:
- ./data/ipfs:/data/ipfs
postgres:
image: postgres
ports:
- '5432:5432'
command: ["postgres", "-cshared_preload_libraries=pg_stat_statements"]
environment:
POSTGRES_USER: graph-node
POSTGRES_PASSWORD: let-me-in
POSTGRES_DB: graph-node
volumes:
- ./data/postgres:/var/lib/postgresql/data
Docker 启动正常,ipfs
、postgres
和 graph-node
的实例都启动正常,但随后 graph-node
的 RPC 调用(对区块链)都失败并出现类似的错误到以下:
WARN Trying again after eth_getBlockByNumber(0, false) RPC call failed (attempt #18) with result Err(Transport error: Error(Connect, Os code: 111, kind: ConnectionRefused, message: "Connection refused" ))
我使用extra-hosts
错了吗?我可以做些什么来使这个脚本既能在我的 Linux 机器上运行,又能在 Mac 和 Windows 用户上运行?
谢谢!
【问题讨论】:
您找到解决该问题的方法了吗?我有同样的问题.. @Twixx 很遗憾没有 我现在遇到了这个问题。它只是随机开始发生。当我 ssh 进入图形节点泊坞窗时,我可以毫无问题地 ping 到主机,但是一旦我添加端口 8545 以连接到链,我就会被拒绝连接。我在安全帽节点上使用 --hostname 0.0.0.0 选项,所以不确定这里会发生什么...... 嗯,现在它随机工作了......似乎是安全帽节点上的 --hostname 0.0.0.0 选项修复了它。 【参考方案1】:您主机上运行的应用程序可能绑定到与 Docker 使用的接口不同的接口。
您可以通过netstat
查看:
$ netstat -pan | grep 8545
tcp6 0 0 127.0.0.1:8545 :::* LISTEN 496150/java
如果它正在监听127.0.0.1
,就像在这个例子中,这意味着它只能通过环回接口访问。
解决方案是找出主机网关指向的 IP 地址,并确保服务绑定到该 IP 地址而不是 127.0.0.1。
如果该服务在所有接口上都可用(包括例如您的 wifi 网络)没有问题,您可以绑定到0.0.0.0
使其在所有接口上可用。
【讨论】:
我也遇到了这个问题,当我运行netstat
命令时,我在主机上看到以下内容:tcp6 0 0 :::8545 :::* LISTEN 23703/geth
。
这意味着您的服务已经在监听所有接口(@987654327@ 是与 IPv6 兼容的写法0.0.0.0
),所以您没有我的答案就是解决方案的问题.不过,我知道另一个可能与相同症状相匹配的问题 - 我将对此添加第二个答案。【参考方案2】:
如果主机系统是 Linux,则您的主机防火墙规则可能会应用于容器之间的通信。您可以检查sysctl
是否是这种情况,它会为以下设置返回1
:
$ sysctl net.bridge.bridge-nf-call-arptables
1
$ sysctl net.bridge.bridge-nf-call-iptables
1
$ sysctl net.bridge.bridge-nf-call-ip6tables
您可以通过将这些值设置为“0”来解决此问题:
$ sudo sysctl net.bridge.bridge-nf-call-arptables=0
net.bridge.bridge-nf-call-arptables = 0
$ sudo sysctl net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-iptables = 0
$ sudo sysctl net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-ip6tables = 0
【讨论】:
是的,所有这些值都是1
。我将它们全部更改为0
,但是当我运行一个容器然后exec -it /bin/bash
进入它时,我无法连接到端口8545 上的主机:root@localhost:~/code/metis/ops# docker exec -it ops_l2geth-mainnet_1 /bin/sh / # geth attach http://host.docker.internal:8545 Fatal: Failed to start the javascript console: api modules: Post "http://host.docker.internal:8545": context deadline exceeded
。但是,如果我手动运行ufw allow 8545
,则上面的geth attach
命令有效。我试图弄清楚如何只启用本地容器访问 8545
嗯,我以为 ufw 会在后台使用 iptables。当您弄清楚时,会很想知道它是如何组合在一起的!以上是关于Linux 上的 docker-compose `host-gateway` 无法连接到 RPC (v20.10.1)的主要内容,如果未能解决你的问题,请参考以下文章
了解 Docker/Docker-Compose 上的 Gunicorn 和 Flask
Docker-compose 在 M1 mac 上的 VM (Parallels) 中
node_modules 上的 docker-compose 卷但为空
Linux企业运维——Docker三剑客之docker-compose
docker-compose ECONNREFUSED 用于 nodeJS 上的 Postgres
Docker Compose (docker-compose) 无法连接到 Windows Server 2016 TP5 上的 docker 守护进程