无法从Docker容器

时间:2017-03-05 02:40:58

标签: javascript node.js docker redis redis-cluster

我有一个使用此ioredis javascript客户端库的Node应用程序。我的问题是我无法将此应用程序(也是已对接的)连接到我的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.,到目前为止一直很好。为什么?:

  1. 以下是output
  2. 的屏幕截图
  3. 我可以使用redis-cli -c -p 7000
  4. 进入CLI
  5. 使用docker inspect [container id]我看到它有一个NetworkSettings> IP地址172.17.0.2和网络设置>我看到的端口

    "Ports": {
                "6379/tcp": null,
                "7000/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "7000"
                    }
                ],
                ...
             }
    
  6. 接下来,我停止并删除所有容器。我导航到我的网络应用的根目录,其中我有一个Dockerfile和一个docker-compose.yml

    搬运工-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。

    完整性检查

    1. 运行docker-compose up并且如您在gist中看到的那样错误连续记录,我仍然可以在执行时从容器外部连接到群集:

      $ redis-cli -c -p 7000
      
    2. $ docker ps显示此screenshot

    3. $ docker exec 4b3ec3e53e32 ps aux | grep redis显示此screenshot

    4. 以下是redis容器再次来自$ docker inspect 4b3ec3e53e32的完整output。请注意"IPAddress": "" ...

    5. 下的NetworkSettings

      其他问题

      1. ...为什么现在这个空白?这就是我的Redis客户端无法连接到群集的原因吗?
      2. ip和"HostIp": "0.0.0.0",有什么区别? 0.0.0.0绑定在redis.conf配置中,我认为这意味着服务器只会侦听来自该地址的请求。这是否意味着那里列出的IP必须与我的其他ctn_web_1容器的IP匹配?
      3. 我们还从docker-compose up的输出中看到Redis服务器位于172.18.0.2。我注意到,在运行172.18.0.4的情况下,我的实例也发生了很大变化(例如172.18.0.3docker-compose)。为什么?是因为我在再次运行之前还没有完全删除容器吗?但是,我不应该在我的connect.js代码中使用此IP地址,因为此地址是redis容器的内部地址(而我的Web容器感兴趣的接口是redis容器的地址)?< / LI>

        更新

        一个。 $ docker-compose ps输出为here。  B.另请注意this问题。更具体地说,

          

        redis集群还不支持docker(除非你做主机网络) - &gt;广告的ip地址与他们可以通过谈话的地址不同

1 个答案:

答案 0 :(得分:1)

您应该删除该行

host: '0.0.0.0'
从你的connect.js

。您需要通过其DNS名称(redis)建立与其他容器的连接,只要您在同一个docker网络中将它们旋转起来,它就会起作用。这是具有版本2 yml文件的docker-compose的默认行为。

容器可能以不同的IP开头。我建议不要尝试将容器的IP硬编码到任何配置文件中,因为按照设计,目标容器可能来来去去。

从您引用的问题来看,上游作者不支持您尝试执行的操作。我不确定如何与你的redis-cli工作的初步发现相协调。我的回答是基于一个工作redis环境的假设。为了回应其他一些困惑:

  • 0.0.0.0是一个侦听IP,表示应该监听所有接口。您没有从客户端连接 0.0.0.0,只能将此地址作为服务器进行侦听。

  • 您看到的空IP地址是重新组织一些json输出的结果,现在所有IP都只列出了他们的特定网络,而且顶层没有列出默认IP。