无法从 Docker 容器内连接到 Redis 集群
Unable to connect to Redis Cluster from inside Docker container
我有一个使用此 ioredis javascript 客户端库的 Node 应用程序。我的问题是我无法将这个同样 docker 化的应用程序连接到我的 Redis 集群(端口 7000 到 7005)及其容器。这是我的设置和结果:
我克隆了这个 Docker-redis-cluster 存储库并按照说明从 Dockerfile
.
构建映像
$ docker build -t gsccheng/redis-cluster .
然而,在构建之前,我唯一的改变是设置我自己的版本,我已将其更改为
ARG redis_version=3.2.1
按照我的指示 运行
docker run -i -t -p 7000:7000 -p 7001:7001 -p 7002:7002 -p 7003:7003 -p 7004:7004 -p 7005:7005 -p 7006:7006 -p 7007:7007 gsccheng/redis-cluster
到目前为止很棒...
除了一些警告,如:WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
,到目前为止还不错。为什么?:
- 这是 output 的屏幕截图。
- 我可以使用
redis-cli -c -p 7000
进入 CLI
使用 docker inspect [container id]
我看到它有一个 NetworkSettings > IPAddress 172.17.0.2 在 NetworkSettings > Ports 我看到
"Ports": {
"6379/tcp": null,
"7000/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "7000"
}
],
...
}
接下来,我停止并删除所有容器。我导航到我的 Web 应用程序的根目录,其中有一个 Dockerfile
和一个 docker-compose.yml
,它们位于此处:
docker-compose.yml
version: '2.1'
services:
web:
build: .
ports:
- '8080:8080'
depends_on:
- redis
redis:
image: gsccheng/redis-cluster
ports:
- '7000:7000'
- '7001:7001'
- '7002:7002'
- '7003:7003'
- '7004:7004'
- '7005:7005'
Dockerfile
FROM node:4.4.7
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install
# Bundle app source
COPY . /usr/src/app
EXPOSE 8080
CMD [ "npm", "run", "prod" ]
connect.js
import Redis from 'ioredis';
console.log('I am totally in here');
// The commented out host options shows the many different configurations I tried too.
const node = [{
// Just need to connect to at least one of the startup nodes in the cluster. Redis will find the rest of the nodes in the cluster. All nodes only have a single db of 0 and SELECT is disabled.
port: 7000,
// host: '0.0.0.0'
// host: '127.0.0.1'
// host: '172.18.0.4'
host: 'redis'
// host: 'gsccheng/redis-cluster'
}, {
port: 7001,
// host: '0.0.0.0'
// host: '127.0.0.1'
// host: '172.18.0.4'
host: 'redis'
// host: 'gsccheng/redis-cluster'
}]
client = new Redis.Cluster(node, {});
...
我然后运行
$ docker-compose build
和
$ docker-compose up
输出在这个gist。对于这个例子,我从那里删除了一些不相关的行(用“...”表示)。
如果有区别的话,我的应用程序是从这个 React-redux boilerplate 构建的,但它不包括 Redis。
完整性检查
使用 docker-compose up
运行ning 并且如您在要点中看到的那样不断记录错误,我仍然可以在执行时从容器外部连接到集群:
$ redis-cli -c -p 7000
$ docker ps
显示此 screenshot.
$ docker exec 4b3ec3e53e32 ps aux | grep redis
显示此 screenshot.
这是来自 $ docker inspect 4b3ec3e53e32
的 redis 容器的完整 output。注意 NetworkSettings
...
下的 "IPAddress": ""
更多问题
- ...为什么现在是空白?这就是我的 Redis 客户端无法连接到集群的原因吗?
- 那个ip和
"HostIp": "0.0.0.0",
有什么区别? 0.0.0.0
绑定在 redis.conf
配置中,我认为这意味着服务器只会侦听来自该地址的请求。这是否意味着此处列出的 IP 必须与我的其他 ctn_web_1
容器的 IP 匹配?
- 我们还从
docker-compose up
的输出中看到 Redis 服务器已启动 172.18.0.2
。我注意到这在我 运行ning docker-compose
的实例之间也发生了很大变化(例如 172.18.0.4
、172.18.0.3
)。为什么?是因为我在再次 运行ning 之前还没有完全删除容器吗?但是,我不应该在我的 connect.js
代码中使用这个 ip 地址,因为这个地址是 redis 容器的内部地址(而我的 web 容器感兴趣的接口是 redis 容器的地址)?
更新:
一个。 $ docker-compose ps
输出为 here。
B. 还要注意 this 问题。更具体地说
redis cluster doesnt support docker yet (unless you do host networking) - >advertised ip address would be different from the one they can talk through
您应该删除该行
host: '0.0.0.0'
来自您的 connect.js。您需要通过它们的 DNS 名称 (redis) 与其他容器建立连接,只要您在同一个 docker 网络中启动它们,它就可以工作。这是 docker-compose 与版本 2 yml 文件的默认行为。
容器可能以不同的 IP 开头。我建议不要尝试将容器的 IP 硬编码到任何配置文件中,因为根据设计,目标容器可能会来来去去。
从您提到的问题来看,上游作者似乎不支持您尝试做的事情。我不确定这如何与您最初发现 redis-cli 的结果相协调。我的回答是基于一个工作的 redis 环境的假设。回应一些其他的困惑:
0.0.0.0是监听IP,表示所有接口都应该被监听。你不从客户端连接到0.0.0.0,只作为服务端监听这个地址
您看到的空 IP 地址是重新组织一些 json 输出的结果,现在所有 IP 仅与其特定网络一起列出,顶级不再列出默认 IP .
我有一个使用此 ioredis javascript 客户端库的 Node 应用程序。我的问题是我无法将这个同样 docker 化的应用程序连接到我的 Redis 集群(端口 7000 到 7005)及其容器。这是我的设置和结果:
我克隆了这个 Docker-redis-cluster 存储库并按照说明从 Dockerfile
.
$ docker build -t gsccheng/redis-cluster .
然而,在构建之前,我唯一的改变是设置我自己的版本,我已将其更改为
ARG redis_version=3.2.1
按照我的指示 运行
docker run -i -t -p 7000:7000 -p 7001:7001 -p 7002:7002 -p 7003:7003 -p 7004:7004 -p 7005:7005 -p 7006:7006 -p 7007:7007 gsccheng/redis-cluster
到目前为止很棒...
除了一些警告,如:WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
,到目前为止还不错。为什么?:
- 这是 output 的屏幕截图。
- 我可以使用
redis-cli -c -p 7000
进入 CLI
使用
docker inspect [container id]
我看到它有一个 NetworkSettings > IPAddress 172.17.0.2 在 NetworkSettings > Ports 我看到"Ports": { "6379/tcp": null, "7000/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "7000" } ], ... }
接下来,我停止并删除所有容器。我导航到我的 Web 应用程序的根目录,其中有一个 Dockerfile
和一个 docker-compose.yml
,它们位于此处:
docker-compose.yml
version: '2.1'
services:
web:
build: .
ports:
- '8080:8080'
depends_on:
- redis
redis:
image: gsccheng/redis-cluster
ports:
- '7000:7000'
- '7001:7001'
- '7002:7002'
- '7003:7003'
- '7004:7004'
- '7005:7005'
Dockerfile
FROM node:4.4.7
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install
# Bundle app source
COPY . /usr/src/app
EXPOSE 8080
CMD [ "npm", "run", "prod" ]
connect.js
import Redis from 'ioredis';
console.log('I am totally in here');
// The commented out host options shows the many different configurations I tried too.
const node = [{
// Just need to connect to at least one of the startup nodes in the cluster. Redis will find the rest of the nodes in the cluster. All nodes only have a single db of 0 and SELECT is disabled.
port: 7000,
// host: '0.0.0.0'
// host: '127.0.0.1'
// host: '172.18.0.4'
host: 'redis'
// host: 'gsccheng/redis-cluster'
}, {
port: 7001,
// host: '0.0.0.0'
// host: '127.0.0.1'
// host: '172.18.0.4'
host: 'redis'
// host: 'gsccheng/redis-cluster'
}]
client = new Redis.Cluster(node, {});
...
我然后运行
$ docker-compose build
和
$ docker-compose up
输出在这个gist。对于这个例子,我从那里删除了一些不相关的行(用“...”表示)。
如果有区别的话,我的应用程序是从这个 React-redux boilerplate 构建的,但它不包括 Redis。
完整性检查
使用
docker-compose up
运行ning 并且如您在要点中看到的那样不断记录错误,我仍然可以在执行时从容器外部连接到集群:$ redis-cli -c -p 7000
$ docker ps
显示此 screenshot.$ docker exec 4b3ec3e53e32 ps aux | grep redis
显示此 screenshot.这是来自
$ docker inspect 4b3ec3e53e32
的 redis 容器的完整 output。注意NetworkSettings
... 下的
"IPAddress": ""
更多问题
- ...为什么现在是空白?这就是我的 Redis 客户端无法连接到集群的原因吗?
- 那个ip和
"HostIp": "0.0.0.0",
有什么区别?0.0.0.0
绑定在redis.conf
配置中,我认为这意味着服务器只会侦听来自该地址的请求。这是否意味着此处列出的 IP 必须与我的其他ctn_web_1
容器的 IP 匹配? - 我们还从
docker-compose up
的输出中看到 Redis 服务器已启动172.18.0.2
。我注意到这在我 运行ningdocker-compose
的实例之间也发生了很大变化(例如172.18.0.4
、172.18.0.3
)。为什么?是因为我在再次 运行ning 之前还没有完全删除容器吗?但是,我不应该在我的connect.js
代码中使用这个 ip 地址,因为这个地址是 redis 容器的内部地址(而我的 web 容器感兴趣的接口是 redis 容器的地址)?
更新:
一个。 $ docker-compose ps
输出为 here。
B. 还要注意 this 问题。更具体地说
redis cluster doesnt support docker yet (unless you do host networking) - >advertised ip address would be different from the one they can talk through
您应该删除该行
host: '0.0.0.0'
来自您的 connect.js。您需要通过它们的 DNS 名称 (redis) 与其他容器建立连接,只要您在同一个 docker 网络中启动它们,它就可以工作。这是 docker-compose 与版本 2 yml 文件的默认行为。
容器可能以不同的 IP 开头。我建议不要尝试将容器的 IP 硬编码到任何配置文件中,因为根据设计,目标容器可能会来来去去。
从您提到的问题来看,上游作者似乎不支持您尝试做的事情。我不确定这如何与您最初发现 redis-cli 的结果相协调。我的回答是基于一个工作的 redis 环境的假设。回应一些其他的困惑:
0.0.0.0是监听IP,表示所有接口都应该被监听。你不从客户端连接到0.0.0.0,只作为服务端监听这个地址
您看到的空 IP 地址是重新组织一些 json 输出的结果,现在所有 IP 仅与其特定网络一起列出,顶级不再列出默认 IP .