docker-compose:连接在容器之间拒绝,但服务可以从主机访问 [英] docker-compose: connection refused between containers, but service accessible from host

查看:1716
本文介绍了docker-compose:连接在容器之间拒绝,但服务可以从主机访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR:如何更改我的下面 docker-compose.yml ,以便允许一个容器使用另一个容器通过自定义(非我有一个很常见的设置:一个web应用程序的容器(Padrino [Ruby]),Postgres,Redis和一个排队框架(Sidekiq) 。网络应用程序附带自定义的Docker文件,其余的服务来自标准图像(Postgres,Redis),或从Web应用程序(Sidekiq)安装数据。他们通过以下 docker-compose.yml 绑定在一起:

 版本:'2'

服务:
web:
build:。
命令:'bundle exec puma -C config / puma.rb'
卷:
- 。/ / myapp
ports:
- 9000:3000
depends_on:
- postgres
- redis

sidekiq:
build:。
命令:'bundle exec sidekiq -C config / sidekiq.yml -r ./config/boot.rb'
volumes:
- 。:/ myapp
depends_on:
- postgres
- redis

postgres:
image:postgres:9.5
环境:
POSTGRES_USER:my-postgres-user
POSTGRES_PASSWORD:my-postgres-pass
ports:
- '9001:5432'
volumes:
- 'postgres:/ var / lib / postgresql / data'

redis:
image:redis
ports:
- '9002:6379'
volumes:
- 'redis:/ var / lib / redis /数据'

卷:
redis:
postgres:

这里要注意的一个关键点是我正在使用非标准端口(9000-9002)的容器服务。



如果我使用 docker-compise up 开始安装,Redis和Postgres容器会很好,但是web应用程序和Sidekiq的容器因为无法连接到Redis在 redis:9002 而失败。值得注意的是,如果我使用6379(标准的Redis端口)而不是9002,则相同的设置工作



docker ps 也看起来很好afaik:

  CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 
9148566c2509 redisdocker-entrypoint.sh不到一秒钟上传大约一分钟0.0.0.0:9002->6379/tcp ruby​​dockerpadrino_redis_1
e6d47321c939 postgres:9.5/docker-entrypoint.s不到一秒钟前大约一分钟0.0.0.0:9001->5432/tcp ruby​​dockerpadrino_postgres_1

更令人困惑的是:我可以通过 redis-cli -h localhost -p 9002 -n 0 从主机访问Redis容器,但Web应用程序和Sidekiq容器无法建立连接。



我正在使用这个MacOS上的docker版本:
Docker版本1.12.3,构建6b644ec,实验



任何想法我做错了吗我很感激任何提示如何让我的设置运行。

解决方案

当您绑定这样的端口 '9002:6379'你正在告诉Docker从 localhost:9002 - > redis:6379 。这就是为什么这可以从您的主机运行:

  redis-cli -h localhost -p 9002 -n 0 

但是,当容器相互通信时,它们都默认连接到同一个网络(Docker bridge docker0 )。默认情况下,容器可以在该网络上自由地互相通信,而不需要打开任何端口。在这个网络中,您的 redis 容器正在监听通常的端口( 6379 )上的流量,主机不涉及在所有这就是为什么你的容器到集装箱通讯工作在 6379


TL;DR: How do I have to change my below docker-compose.yml in order to allow one container to use a service of another over a custom (non-standard) port?

I have a pretty common setup: containers for a web app (Padrino [Ruby]), Postgres, Redis, and a queueing framework (Sidekiq). The web app comes with its custom Dockerfile, the remaining services come either from standard images (Postgres, Redis), or mount the data from the web app (Sidekiq). They are ties together via the following docker-compose.yml:

version: '2'

services:
  web:
    build: .
    command: 'bundle exec puma -C config/puma.rb'
    volumes:
      - .:/myapp
    ports:
      - "9000:3000"
    depends_on:
      - postgres
      - redis

  sidekiq:
    build: .
    command: 'bundle exec sidekiq -C config/sidekiq.yml -r ./config/boot.rb'
    volumes:
      - .:/myapp
    depends_on:
      - postgres
      - redis

  postgres:
    image: postgres:9.5
    environment:
      POSTGRES_USER: my-postgres-user
      POSTGRES_PASSWORD: my-postgres-pass
    ports:
      - '9001:5432'
    volumes:
      - 'postgres:/var/lib/postgresql/data'

  redis:
    image: redis
    ports:
      - '9002:6379'
    volumes:
      - 'redis:/var/lib/redis/data'

volumes:
  redis:
  postgres:

One key point to notice here is that I am exposing the containers services on non-standard ports (9000-9002).

If I start the setup with docker-compose up, the Redis and Postgres containers come up fine, but the containers for the web app and Sidekiq fail since they can't connect to Redis at redis:9002. Remarkably enough, the same setup works if I use 6379 (the standard Redis port) instead of 9002.

docker ps also looks fine afaik:

CONTAINER ID        IMAGE                   COMMAND                  CREATED                  STATUS              PORTS                              NAMES
9148566c2509        redis                   "docker-entrypoint.sh"   Less than a second ago   Up About a minute   0.0.0.0:9002->6379/tcp             rubydockerpadrino_redis_1
e6d47321c939        postgres:9.5            "/docker-entrypoint.s"   Less than a second ago   Up About a minute   0.0.0.0:9001->5432/tcp             rubydockerpadrino_postgres_1

What's even more confusing: I can access the Redis container from the host via redis-cli -h localhost -p 9002 -n 0, but the web app and Sidekiq containers fail to establish a connection.

I am using this docker version on MacOS: Docker version 1.12.3, build 6b644ec, experimental

Any ideas what I am doing wrong? I'd appreciate any hint how to get my setup running.

解决方案

When you bind ports like this '9002:6379' you're telling Docker to forward traffic from localhost:9002 -> redis:6379. That's why this works from your host machine:

redis-cli -h localhost -p 9002 -n 0

However, when containers talk to each other, they are all connected to the same network by default (the Docker bridge or docker0). By default, containers can communicate with each other freely on this network, without needing any ports opened. Within this network, your redis container is listening for traffic on it's usual port (6379), host isn't involved at all. That's why your container to container communication works on 6379.

这篇关于docker-compose:连接在容器之间拒绝,但服务可以从主机访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆