你看下服务端有没有异常,这个看着是连上了,但是后面请求后,服务挂掉了?
@dingding @zealot-shin 1.x版本打断点调试会发现从meta节点获取到的storage节点的ip为172.x.x.x,而执行scan脚本的这台机器访问不通172.x.x.x ,调试信息会发现有timeout error
这个是正常的现象,1.0 docker用的是内部的子网,外部访问不了,2.0用的还是还是内部域名,更加不能直接访问。所以你们要用docker-compose启动的服务做scan 操作,要么网络改成host模式,要么自己起个容器运行。
我这边自己尝试了一些连接,作出了一个猜测,麻烦各位大佬看下是不是这样:
我用windows环境的pycharm运行scan的代码,meta client连接时,指定的ip和端口分别为宿主机的ip和启动docker的metad的宿主机端口(上面docker图片中35931)
(windows上使用telnet可以正常访问宿主机的ip和端口,但是无法访问docker中nebula指定的172.28.x.x的ip和端口。)
此时连接metad可以正常连接,但是通过metad得知storage的ip和端口是172.28.2.2 和44500,所以无法正常连接到storaged,之后获取nebula中的listspace以及查询具体的space时,都是空的。
所以,如果我能让windows环境可以连接docker启动的172.28.1.1以及172.28.2.2以及各自的端口,应该就可以正常运行scan的代码了。
是不是这样呢?
可以这样
不过目前来看,想要让外部网络访问容器启动的nebula的ip和端口,只有使用host模式来启动容器才可以做到吧。
我现在启动的nebula容器其实已经做了宿主机的端口映射了,但是由于我刚才提到的从metad获取的storaged总是容器内部的ip和端口,所以即使连接metad通过映射的宿主机ip和端口能够成功,之后的连接storaged是一定会失败的。。
看来,目前的解决办法是只有改成host模式了。
不知道我的理解对不对。
bingo
你可以用console验证一下整个服务是否正常,你在宿主机上连接docker映射出来的端口是可以的,失败应该是其他原因
服务没问题;
宿主机连接也没问题。
我这边的问题是docker启动的nebula,想要从宿主机外部进行访问。单纯访问web界面或者使用nebula的connection客户端都可以连接。
但是使用metaclient,无法正常使用scan等方法。因为创建metaclient时,虽然可以通过连接宿主机ip和映射的端口连接metad,但是接下来无法通过metad获取的元信息正常连接storaged。
所以从宿主机外部可以访问nebula-web,可以使用connection 客户端访问,但是meta client不行。
打搅一下,我怎么联系你们技术人员啊,有没有社区群啊
大家好,关于这个问题,我理解可以采用的 mitigation(macOS下用官方的 docker-compose 默认配置 拉一个 ng cluster)有两个:
-
在 docker 里创建一个 container,网络选择
nebula-docker-compose_nebula-net
,在这个 container 里边跑 python/java client 的代码来 scanVertex scanEdge,那里边到 meta 的 docker 网络是可达的,到 storage 的网络和 hostname 也是可解析的,不过这个方式我还没有试过,图省事儿,我只用了下边 2 的方法。 -
做端口映射。这里边我理解 a) metaclient 需要给配置所有 metaD 的9559的 (ip:port),然后storage_client 会从 metaD 取得 b) storageD 的 hostname:port,这样我们只需要做 a), b) 的端口映射就足够了。
方法 1
关于 1. 我试了一下是 work 的。
$ docker run -dit --name ng --network nebula-docker-compose_nebula-net ubuntu:latest bash
$ docker exec -it ng bash
$ apt update
$ apt install python3 python3-pip
$ pip3 install nebula2-python==2.0.0rc1
看一下 metad 的地址
$ docker network inspect nebula-docker-compose_nebula-net | grep "Name\|IPv4"
"Name": "nebula-docker-compose_nebula-net",
"Name": "nebula-docker-compose_storaged2_1",
"IPv4Address": "172.18.0.8/16",
"Name": "nebula-docker-compose_storaged1_1",
"IPv4Address": "172.18.0.2/16",
"Name": "nebula-docker-compose_metad0_1",
"IPv4Address": "172.18.0.10/16",
"Name": "nebula-docker-compose_metad2_1",
"IPv4Address": "172.18.0.9/16",
"Name": "ng",
"IPv4Address": "172.18.0.11/16",
"Name": "nebula-docker-compose_graphd1_1",
"IPv4Address": "172.18.0.3/16",
"Name": "nebula-docker-compose_graphd2_1",
"IPv4Address": "172.18.0.5/16",
"Name": "nebula-docker-compose_storaged0_1",
"IPv4Address": "172.18.0.7/16",
"Name": "nebula-docker-compose_metad1_1",
"IPv4Address": "172.18.0.6/16",
"Name": "nebula-docker-compose_graphd_1",
"IPv4Address": "172.18.0.4/16",
试一下
storage_client
第一次 scan 可以工作。
$ python3
>>> meta_cache = MetaCache([('172.18.0.10', 9559),
... ('172.18.0.6', 9559),
... ('172.18.0.9', 9559)],
... 50000)
>>>
>>> graph_storage_client = GraphStorageClient(meta_cache)
>>>
>>> resp = graph_storage_client.scan_vertex(
... space_name='pokemon_club_1',
... tag_name='trainer',
... limit=100,
... only_latest_version=True)
>>> resp._req
ScanVertexRequest(
space_id=6,
part_id=0,
return_columns=VertexProp(
tag=7,
props=[b'_vid', b'name']),
limit=100,
start_time=0,
end_time=9223372036854775807,
only_latest_version=True,
enable_read_from_follower=True)
方法 2
关于 2. 我自己在 macOS catalina 下用 ssh 测试了一下,metaClient 第一次 scan 是可以工作的
$ docker ps | grep "metad\|9559\|storaged\|9779"
1eda7b857308 vesoft/nebula-storaged:v2-nightly "./bin/nebula-storag…" 3 hours ago Up 2 hours (healthy) 9777-9778/tcp, 9780/tcp, 0.0.0.0:32792->9779/tcp, 0.0.0.0:32787->19779/tcp, 0.0.0.0:32780->19780/tcp nebula-docker-compose_storaged2_1
a6923d0a27bd vesoft/nebula-storaged:v2-nightly "./bin/nebula-storag…" 3 hours ago Up 2 hours (healthy) 9777-9778/tcp, 9780/tcp, 0.0.0.0:32790->9779/tcp, 0.0.0.0:32784->19779/tcp, 0.0.0.0:32777->19780/tcp nebula-docker-compose_storaged0_1
3ea06cca8ed2 vesoft/nebula-storaged:v2-nightly "./bin/nebula-storag…" 3 hours ago Up 2 hours (healthy) 9777-9778/tcp, 9780/tcp, 0.0.0.0:32771->9779/tcp, 0.0.0.0:32769->19779/tcp, 0.0.0.0:32768->19780/tcp nebula-docker-compose_storaged1_1
49f918306d8e vesoft/nebula-metad:v2-nightly "./bin/nebula-metad …" 3 hours ago Up 2 hours (healthy) 9560/tcp, 0.0.0.0:32793->9559/tcp, 0.0.0.0:32789->19559/tcp, 0.0.0.0:32782->19560/tcp nebula-docker-compose_metad0_1
c2dcc251d9e4 vesoft/nebula-metad:v2-nightly "./bin/nebula-metad …" 3 hours ago Up 2 hours (healthy) 9560/tcp, 0.0.0.0:32788->9559/tcp, 0.0.0.0:32781->19559/tcp, 0.0.0.0:32774->19560/tcp nebula-docker-compose_metad1_1
5d138afd7de9 vesoft/nebula-metad:v2-nightly "./bin/nebula-metad …" 3 hours ago Up 2 hours (healthy) 9560/tcp, 0.0.0.0:32791->9559/tcp, 0.0.0.0:32786->19559/tcp, 0.0.0.0:32779->19560/tcp nebula-docker-compose_metad2_1
# 可以看到 metad, storaged 映射到 host可达的端口是 327xx 的
# 咱们做一下解析的部分
$ grep storage /etc/hosts
127.0.0.1 storaged0
10.1.1.153 storaged1
10.1.1.249 storaged2
# 这里我的本机有三个 ip 地址 127.0.0.1/10.1.1.153/10.1.1.249,我们用 ssh 把它们映射如下
$ ssh -L 9779:localhost:32790 -L 10.1.1.153:9779:localhost:32771 -L 10.1.1.249:9779:localhost:32792 \
-L 9559:localhost:32793 -L 10.1.1.153:9559:localhost:32788 -L 10.1.1.249:9559:localhost:32791 \
localhost
按照上边这么映射之后,meteclient, storage_client 连接就可以建立起来了
In [1]: meta_cache = MetaCache([('127.0.0.1', 9559),
...: ('10.1.1.153', 9559),
...: ('10.1.1.249', 9559)],
...: 50000)
...: graph_storage_client = GraphStorageClient(meta_cache)
...:
...: resp = graph_storage_client.scan_vertex(
...: space_name='pokemon_club_1',
...: tag_name='trainer',
...: limit=100,
...: only_latest_version=True)
...: print(resp._req)
...:
ScanVertexRequest(
space_id=6,
part_id=0,
return_columns=VertexProp(
tag=7,
props=[b'_vid', b'name']),
limit=100,
start_time=0,
end_time=9223372036854775807,
only_latest_version=True,
enable_read_from_follower=True)
问题
不知道我这么做有没有什么问题,现在我发现没有任何第一次 scan 的连接问题,只是scanVertex 的 next 结果是空的,方法 1,2 结果都是一样的,是不是和这个方法无关,是我数据,ngdb cluster的问题?
In [3]: resp.has_next()
Out [3]: True
In [4]: result = resp.next()
WARNING:root:Get empty result
In [5]: type(result)
Out [5]: NoneType
数据为空的问题,你执行下 SHOW HOSTS
截下图
谢谢 dingding 大佬!抱歉才回复您。
我从您的这个 issues#91 comment里知道是我用了 PyPi 里的 rc1 client 造成的,原来和 nightly
对应的是 master
的 nebula2-python
。
是有一些 thrift 的不同?
>>> r = resp.next()
>>> r
[DataSet(
column_names=[b'trainer._vid', b'trainer.name'],
rows=[Row(
values=[Value(
sVal=b'Jerry'), Value(
sVal=b'Jerry')]),
Row(
values=[Value(
sVal=b'Joe'), Value(
sVal=b'Joe')]),
Row(
values=[Value(
sVal=b'John'), Value(
sVal=b'John')]),
Row(
values=[Value(
sVal=b'Stephen'), Value(
sVal=b'Stephen')]),
Row(
values=[Value(
sVal=b'Sue'), Value(
sVal=b'Sue')]),
Row(
values=[Value(
sVal=b'Tom'), Value(
sVal=b'Tom')])]), DataSet(
column_names=[b'trainer._vid', b'trainer.name'],
rows=[Row(
values=[Value(
sVal=b'Wey'), Value(
sVal=b'Wey')])])]
是的,1.0和2.0的thrift接口完全变了
关于这部分目前有什么改进计划吗?目前看无论是在docker-compose的网络里起容器运行sdk还是把docker-compose里的容器网络都改成host,然后一个一个改端口映射都不算很优雅的方案,在试用过程中碰到这个问题其实不是很友好。不知道官方在nebula本身机制上有没有修改计划。
btw, 我尝试修改了一下nebula2-python里GraphStorageClient的逻辑,使得可以在构造它的时候可以选择手动传入storage的地址来覆盖从metad中获取的地址,本来以为这样就可以解决从metad里获取到诸如storaged0, storaged1这种地址而无法解析的问题,但实际操作时并不能成功。
我尝试修改了一下nebula2-python里GraphStorageClient的逻辑,使得可以在构造它的时候可以选择手动传入storage的地址来覆盖从metad中获取的地址
不建议这样做,本来 storage的所有信息都是由meta管理的,假如支持用户自己配置一份映射关系,这样容易出错,不利于维护和问题排查。
本来以为这样就可以解决从metad里获取到诸如storaged0, storaged1这种地址而无法解析的问题,但实际操作时并不能成功。
是的,假如你用docker-compose的话,里面用到的是docker内部的域名,外部是怎么都访问不了的,这要么就是起个同网络的容器去执行 scan,要么就需要修改docker-compose的配置。