相关文章推荐
健壮的墨镜  ·  Uni-app ...·  1 年前    · 
卖萌的排球  ·  python ...·  1 年前    · 
骑白马的蚂蚁  ·  时区 - ...·  1 年前    · 
聪明的啤酒  ·  mysql - Error Code: ...·  1 年前    · 

Celery工作者无法连接到docker实例上的redis

18 人关注

我有一个运行Django应用程序的docker化设置,其中我使用Celery任务。Celery使用Redis作为代理。

Versioning:

  • Docker version 17.09.0-ce, build afdb6d4
  • docker-compose version 1.15.0, build e12f3b9
  • Django==1.9.6
  • django-celery-beat==1.0.1
  • celery==4.1.0
  • celery[redis]
  • redis==2.10.5
  • Problem:

    我的celery工作者似乎无法连接到位于localhost:6379的redis容器。我能够在指定的端口上telnet到redis服务器。我能够验证redis-server是否在容器上运行。

    当我手动连接到Celery docker实例并试图使用命令 celery -A backend worker -l info 创建一个worker时我得到了这样的通知。

    [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...

    Notes:

    我能够telnet到6379端口的redis容器。在redis容器上,redis-server正在运行。

    还有什么是我所遗漏的吗?我已经在兔子洞里走了很远,但感觉我错过了一些非常简单的东西。

    DOCKER CONFIG FILES:

    docker-compose.common.yml here
    docker-compose.dev.yml here

    5 个评论
    Try replacing localhost with 127.0.0.1
    Opal
    你有一个docker-compose文件吗?分享一下吧。
    @Opal在帖子的底部添加了配置文件。
    @warvariuc 当我改成127.0.0.1时,结果也一样。另外值得注意的是,为redis容器使用docker IP地址也不起作用。
    Opal
    它肯定不会是 localhost ,因为redis不工作并不与celery在同一主机上工作。你能通过IP从celery上ping到redis吗?
    python
    django
    docker
    docker-compose
    celery
    user1026996
    发布于 2017-11-14
    3 个回答
    bluescores
    bluescores
    发布于 2020-05-22
    已采纳
    0 人赞同

    当你使用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 的连接方式还能工作吗?
    @AATHITHRAJENDRAN 不,它不会的。Docker继承了主机的DNS,所以除非你有一个 butter-pecan-redis 的DNS条目映射到Docker之外的某个地方的 localhost:<port> ,否则一个容器不会通过名字解析另一个容器。Docker-compose做了一些额外的工作,使其能够工作,我不记得它是否与compose中每个Docker网络的DNS有关,或者docker-compose是否调整主机或resolv.conf。无论如何,简单的按名称解析是docker-compose的一个功能。
    这是我最终让Docker、Django、Celery和Redis从docker-compose.yml文件中一起工作的拼图中缺少的一块。谢谢你的解释!
    A. J. Parr
    A. J. Parr
    发布于 2020-05-22
    0 人赞同

    你可能需要添加 link depends_on sections to your docker compose file,和then reference the containers by their hostname.

    更新了docker-compose.yml。

    version: '2.1'
    services:
            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:
                - redis
                - memcached
            depends_on:
                - 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:
                - redis
                - memcached
            depends_on:
                - redis
                - memcached
        frontend-base:
            build:
                context: .
                dockerfile: frontend/Dockerfile-base
                args:
                    NPM_REGISTRY: http://.view.build
                    PACKAGE_INSTALLER: yarn
            image: "/frontend:base"
            links:
                - redis
                - memcached
            depends_on:
                - redis
                - memcached
        frontend:
            build:
                context: .
                dockerfile: frontend/Dockerfile
            image: "/frontend:${ENV:-local}"
            command: 'bash -c ''gulp'''
            working_dir: /app/user
            environment:
                PORT: 3000
            links:
                - redis
                - memcached
            depends_on:
                - redis
                - memcached
    

    然后用以下方法配置到redis、postgres、memcached等的urls。

  • redis://redis:6379/0
  • postgres://user:pass@db:5432/database
  • 嘿,谢谢你的贡献。你说"......将尿液配置到redis、postgres、memcached...... "到底是什么意思?
    DannyMoshe
    DannyMoshe
    发布于 2020-05-22
    0 人赞同

    我的问题是,所有的容器,包括celery都指定了一个网络参数。如果是这样的话,redis容器也必须有同样的参数,否则你会得到这个错误。见下文,修复方法是添加'networks'。

      redis:
        image: redis:alpine