我目前面临 Celery 5.3.4 的问题,要求我安装反向移植模块。该应用程序在 debian 11 主机上使用 python 版本 3.10.13 的容器 (3.10.13-bullseye) 中运行。当我运行命令
celery -A app beat -l INFO
时。我遇到以下错误:
以下是我的设置的详细信息:
主机操作系统 Debian 11 :
在 Debian11 主机上
点版本:
root@5b45db7349aa:/app# pip3 --version
pip 23.3.1 from /usr/local/lib/python3.10/site-packages/pip (python 3.10)
root@5b45db7349aa:/app# python --version
Python 3.10.13
错误:
root@5b45db7349aa:/app# celery -A app beat -l info
celery beat v5.3.4 (emerald-rush) is starting.
__ - ... __ - _
LocalTime -> 2023-11-03 10:48:13
Configuration ->
. broker -> redis://redis:6379/0
. loader -> celery.loaders.app.AppLoader
. scheduler -> celery.beat.PersistentScheduler
. db -> celerybeat-schedule
. logfile -> [stderr]@%DEBUG
. maxinterval -> 5.00 minutes (300s)
[2023-11-03 10:48:13,939: DEBUG/MainProcess] Setting default socket timeout to 30
[2023-11-03 10:48:13,940: INFO/MainProcess] beat: Starting...
[2023-11-03 10:48:13,945: CRITICAL/MainProcess] beat raised exception <class 'ModuleNotFoundError'>: ModuleNotFoundError("No module named 'backports'")
Traceback (most recent call last):
File "/usr/local/lib/python3.10/shelve.py", line 111, in __getitem__
value = self.cache[key]
KeyError: 'entries'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/celery/apps/beat.py", line 113, in start_scheduler
service.start()
File "/usr/local/lib/python3.10/site-packages/celery/beat.py", line 634, in start
humanize_seconds(self.scheduler.max_interval))
File "/usr/local/lib/python3.10/site-packages/kombu/utils/objects.py", line 31, in __get__
return super().__get__(instance, owner)
File "/usr/local/lib/python3.10/functools.py", line 981, in __get__
val = self.func(instance)
File "/usr/local/lib/python3.10/site-packages/celery/beat.py", line 677, in scheduler
return self.get_scheduler()
File "/usr/local/lib/python3.10/site-packages/celery/beat.py", line 668, in get_scheduler
return symbol_by_name(self.scheduler_cls, aliases=aliases)(
File "/usr/local/lib/python3.10/site-packages/celery/beat.py", line 513, in __init__
super().__init__(*args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/celery/beat.py", line 264, in __init__
self.setup_schedule()
File "/usr/local/lib/python3.10/site-packages/celery/beat.py", line 541, in setup_schedule
self._create_schedule()
File "/usr/local/lib/python3.10/site-packages/celery/beat.py", line 570, in _create_schedule
self._store['entries']
File "/usr/local/lib/python3.10/shelve.py", line 114, in __getitem__
value = Unpickler(f).load()
ModuleNotFoundError: No module named 'backports'
附加信息:
同一个容器在带有 Docker Desktop 的 Windows 10 上运行时,可以正常工作。
我检查过pip、python和celery的版本是一样的。
FROM python:3.10.13-slim-bullseye
# Con questa riga Python stampa direttamente sulla console senza fare buffere dei messaggi
ENV PYTHONUNBUFFERED 1
# viene passato da Docker compose file e per il momento del sviluppo viene sostiuito ed e true
ARG DEV=false
# Creazione del enviorment and upgrading pip
RUN apt-get update
RUN apt-get install -y gcc python3-dev build-essential curl nano
RUN apt-get install -y postgresql-client libjpeg-dev libpq-dev
#Download the desired package(s)
RUN curl https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc
RUN curl https://packages.microsoft.com/config/debian/11/prod.list | tee /etc/apt/sources.list.d/mssql-release.list
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get install -y msodbcsql17
# optional: for unixODBC development headers
RUN apt-get install -y unixodbc-dev
# optional: kerberos library for debian-slim distributions
RUN apt-get install -y libgssapi-krb5-2
RUN mv /etc/localtime /etc/localtime.old
RUN ln -s /usr/share/zoneinfo/Europe/Rome /etc/localtime
# locales
#RUN echo "it_IT.UTF-8 UTF-8" >> /etc/locale.gen
#RUN locale-gen
COPY ./requirements.txt /tmp/requirements.txt
COPY ./requirements.dev.txt /tmp/requirements.dev.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt
COPY ./compose/celery/celery_worker_start.sh /celery_worker_start.sh
RUN sed -i 's/\r$//g' /celery_worker_start.sh
RUN chmod +x /celery_worker_start.sh
COPY ./compose/celery/celery_beat_start.sh /celery_beat_start.sh
RUN sed -i 's/\r$//g' /celery_beat_start.sh
RUN chmod +x /celery_beat_start.sh
COPY ./compose/celery/celery_flower_start.sh /celery_flower_start.sh
RUN sed -i 's/\r$//g' /celery_flower_start.sh
RUN chmod +x /celery_flower_start.sh
RUN mkdir /app
WORKDIR /app
EXPOSE 8000
#esecuzuione del container come utente django
#CMD ["run.sh"]v
uname -a #from the container: Linux 3865cf0f97ec 4.19.0-25-amd64 #1 SMP Debian 4.19.289-2 (2023-08-08) x86_64 GNU/Linux uname -a #from the Host: Linux VSRVDEB01 4.19.0-25-amd64 #1 SMP Debian 4.19.289-2 (2023-08-08) x86_64 GNU/Linux
另外,当您说“相同的容器”时,您的意思是相同的来源:
是的,同一来源。
python:3.10.13-slim-bullseye
已损坏,已推送修复。这并不罕见,但我也希望其他人报告问题。如果修复了故障,则可以(并且很可能)将新版本推送到同一标签下。在这种情况下,我会采用后一种解释。
# Remove image
$ docker image rm python:3.10.13-slim-bullseye
# Pull image again
$ docker pull python:3.10.13-slim-bullseye
3.10.13-slim-bullseye: Pulling from library/python
0bc8ff246cb8: Pull complete
ea6c70a3b047: Pull complete
94293398fb1c: Pull complete
2b0c0766ac49: Pull complete
5e93a6aa11f2: Pull complete
Digest: sha256:829bfd6812e20121a26a14bc419b375ee405d1c24dc252f9b740637c4701b122
Status: Downloaded newer image for python:3.10.13-slim-bullseye
docker.io/library/python:3.10.13-slim-bullseye
当心!每层的输出必须包含
Pull complete
!否则,Docker 守护进程会重复使用缓存层,这是我们想要避免的。如果您在删除所有层时遇到问题,请尝试“修剪”Docker 映像(请参阅https://stackoverflow.com/a/44791684/1120802),或者在最极端的情况下,删除所有 Docker 引擎资源并重新开始(请参阅Docker 映像损坏?删除层?)。小心,两者都是破坏性行为!
接下来,重新构建并设置
--no-cache
选项
$ docker build -t your-image-name-here --no-cache .
如果这不能解决问题,请参阅“图像不存在问题?”下面的部分。
这是对如何发生这种情况的解释和演示,而不是解决此类问题的步骤!
要解决图像不良的问题,我们可以使用
docker image ls
查找目标图像的 ID:
$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 7f27d60cb8e0 12 days ago 138MB
python 3.10.13-bullseye 1a28f256af27 4 weeks ago 911MB
python 3.10.13-slim-bullseye ee6be26d226b 4 weeks ago 126MB
ubuntu latest e4c58958181a 5 weeks ago 77.8MB
镜像 ID 是组成给定 Docker 镜像的字节集的更精确标识符。就我而言,
3.10.13-slim-bullseye
的(缩短的)ID 为 ee6be26d226b
。如果机器之间存在差异,我们就会知道图像是不同的。为了举例,我们可以看到 ubuntu:latest
图像在拉取之前和之后有何不同(在不同的机器上):
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 6a47e077731f 2 months ago 69.2MB
$ docker pull ubuntu:latest
latest: Pulling from library/ubuntu
bfbe77e41a78: Pull complete
Digest: sha256:2b7412e6465c3c7fc5bb21d3e6f1917c167358449fecac8176c6e496e5c1f05f
Status: Downloaded newer image for ubuntu:latest
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest e343402cadef 5 weeks ago 69.2MB
给定的 docker 镜像由“层”组成(您可能已经看到它们通过推送到注册表或从注册表中拉出而被引用)。拉取映像后,这些层驻留在本地文件系统上。不幸的是,当图像首次写入磁盘时、拉入最终图像时或中间的任何时间,这些层的内容可能会被损坏。作为这种情况如何发生的示例,让我们有意引入腐败并检查其如何出现。我们将使用本文中引用的基础图像
python:3.10.13-slim-bullseye
作为示例。
首先,找到我们正在使用的图像的
UpperDir
。这是一个单行代码,将一些内容打包在一起,但输出文件系统上存储一些基本容器内容的位置:
$ docker image inspect python:3.10.13-slim-bullseye --format="{{json .GraphDriver.Data.UpperDir}}" | jq -r | sed 's/\diff//'
/var/lib/docker/overlay2/a9c2824fa4a07f72827b358a7a92480975e9243b30158e4dabf8c5808ed65928/
好吧,现在让我们破坏我们的形象:
$ touch /var/lib/docker/overlay2/a9c2824fa4a07f72827b358a7a92480975e9243b30158e4dabf8c5808ed65928/hello-from-corruption-town
最后,使用引用的镜像构建一个容器。在此示例中,我使用下面包含的 Dockerfile。注意
--no-cache
!
$ docker build -t so-hack --no-cache .
[+] Building 5.6s (9/9) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 746B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/python:3.10.13-slim-bullseye 0.0s
=> CACHED [1/5] FROM docker.io/library/python:3.10.13-slim-bullseye 0.0s
=> [2/5] RUN <<EOF cat >> /tmp/requirements.txt 0.4s
=> [3/5] RUN pip install --no-cache-dir -r /tmp/requirements.txt 4.6s
=> [4/5] WORKDIR /app 0.0s
=> [5/5] RUN <<EOF cat >> app.py 0.3s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:8bcd9ca6e43b5d94644e3c284b99c83a156f6fdfe0fb3d81a3a4ce3bebb9c763 0.0s
=> => naming to docker.io/library/so-hack 0.0s
最后,运行映像并列出根文件系统的内容。
$ docker run -it --rm so-hack /bin/bash -c 'ls /'
app bin boot dev etc hello-from-corruption-town home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
我们的旗帜,
hello-from-corruption-town
,代表着我们的形象!让我们看看如果我们尝试重新拉取图像会发生什么:
$ docker pull python:3.10.13-slim-bullseye
3.10.13-slim-bullseye: Pulling from library/python
Digest: sha256:829bfd6812e20121a26a14bc419b375ee405d1c24dc252f9b740637c4701b122
Status: Image is up to date for python:3.10.13-slim-bullseye
docker.io/library/python:3.10.13-slim-bullseye
$ ls /var/lib/docker/overlay2/a9c2824fa4a07f72827b358a7a92480975e9243b30158e4dabf8c5808ed65928/
committed diff hello-from-corruption-town link lower work
我们可以看到,重新拉取损坏的图像不会修复该图像。在此示例中,我们添加了一个标志 (
hello-from-corruption-town
),但这也可能是其他形式的损坏,无论是错误的二进制文件、截断的文件还是丢失的目录。最好的解决方案是删除所有相关图像并重新下载图像图层。
尝试构建问题的最小重现,例如从最小的 Dockerfile 开始,如下所示:
FROM python:3.10.13-slim-bullseye
RUN <<EOF cat >> /tmp/requirements.txt
celery[redis]==5.3.4
EOF
RUN pip install --no-cache-dir -r /tmp/requirements.txt
WORKDIR /app
RUN <<EOF cat >> main.py
# Taken from https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html#entries
from celery import Celery
from celery.schedules import crontab
app = Celery()
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# Calls test('hello') every 10 seconds.
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')
@app.task
def test(arg):
print(arg)
@app.task
def add(x, y):
z = x + y
print(z)
EOF
CMD ["python", "/app/main.py"]
从这里开始,迭代调整 Dockerfile,直到您可以重现问题(并且您将知道是哪一步导致的)。