芹菜工人无法连接到 docker 实例上的 redis
Posted
技术标签:
【中文标题】芹菜工人无法连接到 docker 实例上的 redis【英文标题】:Celery workers unable to connect to redis on docker instances 【发布时间】:2018-04-26 14:12:55 【问题描述】:我有一个运行 Django 应用程序的 dockerized 设置,我在其中使用 Celery 任务。 Celery 使用 Redis 作为代理。
版本控制:
Docker 版本 17.09.0-ce,构建 afdb6d4 docker-compose 版本 1.15.0,构建 e12f3b9 Django==1.9.6 django-celery-beat==1.0.1 celery==4.1.0 芹菜[redis] redis==2.10.5问题:
我的 celery worker 似乎无法连接到位于 localhost:6379 的 redis 容器。我能够在指定端口上远程登录到 redis 服务器。我能够验证 redis-server 是否在容器上运行。
当我手动连接到 Celery docker 实例并尝试使用命令 celery -A backend worker -l info
创建一个工作器时,我收到了通知:
[2017-11-13 18:07:50,937: ERROR/MainProcess] consumer: Cannot connect to redis://localhost:6379/0: Error 99 connecting to localhost:6379. Cannot assign requested address..
Trying again in 4.00 seconds...
注意事项:
我可以通过 6379 端口远程登录到 redis 容器。在 redis 容器上,redis-server 正在运行。
我还有什么遗漏的吗?我已经在兔子洞里走得很远了,但感觉我错过了一些非常简单的东西。
Docker 配置文件:
docker-compose.common.yml here docker-compose.dev.yml here
【问题讨论】:
尝试用127.0.0.1
替换localhost
你有 docker-compose 文件吗?分享吧。
@Opal 将配置文件添加到帖子底部。
当我更改为 127.0.0.1 时,@warvariuc 的结果相同。另外需要注意的是,使用 redis 容器的 docker IP 地址也不起作用。
肯定不会是localhost
,因为redis不工作不能和celery在同一个主机上工作。你能通过 celery 的 IP ping redis 吗?
【参考方案1】:
当您使用 docker-compose 时,您不会使用 localhost
进行容器间通信,您将使用容器的 compose 分配的主机名。在这种情况下,您的 redis 容器的主机名是 redis
。 services:
下的***元素是您的默认主机名。
所以要让celery 连接redis,你应该试试redis://redis:6379/0
。由于协议和服务名称相同,我将详细说明:如果您在 docker-compose 中将 redis 服务命名为“butter-pecan-redis”,则改为使用redis://butter-pecan-redis:6379/0
。
另外,docker-compose.dev.yml 似乎没有 celery 和 redis 在一个公共网络上,这可能会导致它们无法看到彼此。我相信他们需要至少共享一个网络才能解析各自的主机名。
Networking in docker-compose 在前几段中有一个示例,还有一个 docker-compose.yml 可供查看。
【讨论】:
他们没有共享一个公共网络,这有助于解决问题。 如果我的两个容器在同一个网络中,这种redis://butter-pecan-redis:6379/0
的连接方式仍然有效吗??(我不想使用 docker-compose)
@AATHITHRAJENDRAN 不,不会。 Docker 继承了主机的 DNS,因此除非您将 butter-pecan-redis
的 DNS 条目映射到 Docker 外部某处的 localhost:<port>
,否则一个容器不会按名称解析另一个容器。 Docker-compose 做了一些额外的事情来让它工作,我不记得它是否在 compose 中具有每个 Docker 网络的 DNS,或者 docker-compose 是否调整主机或 resolv.conf。无论哪种方式,简单的按名称解析都是 docker-compose 功能。
这是我最终通过 docker-compose.yml 文件让 Docker、Django、Celery 和 Redis 一起工作的难题中缺失的部分。感谢您解释这一点!【参考方案2】:
您可能需要将 link 和 depends_on 部分添加到您的 docker compose 文件中,然后通过它们的主机名引用容器。
更新了 docker-compose.yml:
version: '2.1'
services:
db:
image: postgres
memcached:
image: memcached
redis:
image: redis
ports:
- '6379:6379'
backend-base:
build:
context: .
dockerfile: backend/Dockerfile-base
image: "/backend:base"
backend:
build:
context: .
dockerfile: backend/Dockerfile
image: "/backend:$ENV:-local"
command: ./wait-for-it.sh db:5432 -- gunicorn backend.wsgi:application -b 0.0.0.0:8000 -k gevent -w 3
ports:
- 8000
links:
- db
- redis
- memcached
depends_on:
- db
- redis
- memcached
celery:
image: "/backend:$ENV:-local"
command: ./wait-for-it.sh db:5432 -- celery worker -E -B --loglevel=INFO --concurrency=1
environment:
C_FORCE_ROOT: "yes"
links:
- db
- redis
- memcached
depends_on:
- db
- redis
- memcached
frontend-base:
build:
context: .
dockerfile: frontend/Dockerfile-base
args:
NPM_REGISTRY: http://.view.build
PACKAGE_INSTALLER: yarn
image: "/frontend:base"
links:
- db
- redis
- memcached
depends_on:
- db
- redis
- memcached
frontend:
build:
context: .
dockerfile: frontend/Dockerfile
image: "/frontend:$ENV:-local"
command: 'bash -c ''gulp'''
working_dir: /app/user
environment:
PORT: 3000
links:
- db
- redis
- memcached
depends_on:
- db
- redis
- memcached
然后配置redis、postgres、memcached等的url:
redis://redis:6379/0
postgres://user:pass@db:5432/database
【讨论】:
您好,感谢您的贡献。 “......配置redis,postgres,memcached......的url”到底是什么意思?【参考方案3】:对我来说,问题是所有容器,包括 celery,都指定了网络参数。如果是这种情况,redis 容器也必须具有相同的参数,否则您将收到此错误。见下文,修复是添加“网络”:
redis:
image: redis:alpine
ports:
- '6379:6379'
networks:
- server
【讨论】:
以上是关于芹菜工人无法连接到 docker 实例上的 redis的主要内容,如果未能解决你的问题,请参考以下文章
芹菜不起作用:无法连接到 amqp://guest:**@127.0.0.1:5672//