如何管理安装在 docker 镜像和运行容器中的 Python 包版本

时间:2021-04-05 01:50:58

标签: docker kubernetes pip docker-swarm

我想控制和监控安装在容器上的自定义 python 包的版本。这是为了在将新自定义 Python 包部署到更高风险或生产容器之前,将它们受控、增量地发布到低风险或测试容器中。

例如,我可能想用新的 Python 包迭代更新一小部分容器,直到所有容器都更新完毕。

在不知道可以为我执行此操作的实用程序的情况下,我有一个想法可以解释我想要完成的一些事情-

我能想到的最好办法是在镜像构建过程中将 Python 包版本作为参数,将这些版本传递给 Dockerfile 中的 pip,然后在镜像作为 Dockerfile 的最后一步。这允许我在我的所有容器中运行一个命令 (cat MYPACKAGES.json) 来打印正在运行的容器中的所有 Python 包版本,并选择哪些需要和应该升级。

是否有使用现有实用程序更简洁的方法?

1 个答案:

答案 0 :(得分:1)

标准 Python 打包工具已经基本上支持您所描述的工作流程。如果您使用“经典”setup.py,那么该文件将列出您的应用程序直接依赖的包以及一系列可接受的版本;然后,您可以运行 pip freeze 来创建一个 requirements.txt 文件,其中包含您直接或间接使用的每个包和确切版本。同样,如果您使用 Pipenv,它的 PipfilePipfile.lock 带有版本范围和精确版本。

在构建 Docker 映像时,您应该确保拥有锁定文件以获取确切版本。

FROM python:3.9
WORKDIR /app
COPY requirements.txt .  # with exact versions
RUN pip install -r requirements.txt
COPY . .
RUN pip install .        # also install application into "system" Python
CMD ["my_app"]

这意味着使用非 Docker 虚拟环境进行日常开发、单元测试和部署前测试。这在任何情况下都可能是个好主意,因为如果您尝试使用仅存在于容器内的工具,Docker 的隔离机制可能会增加一些重大挑战。

<块引用>

我可能想用新的 Python 包迭代更新一小部分容器,直到所有容器都更新完毕。

如果您有良好的 Kubernetes 实践,这是可能的。

在最简单的版本中,您会在启动时检测到一些兼容性问题,如果库堆栈不起作用,新的 pod 就会崩溃。在这种情况下,您不需要做太多事情。确保应用程序的每个构建都有一个不同的 Docker 映像标记,并更改部署规范中的 image:。 Kubernetes 会自行开始使用新镜像部署新 Pod,只有在新 Pod 成功通过健康检查后才会拆除旧 Pod。

如果您想对流程进行更多控制,您可以使用两个单独的部署来做类似的事情。您可以将它们标记为例如“蓝色”和“绿色”,让相同的 Service 选择两组 Pod,并使用 kubectl scale deployment 更改每个的副本数量,直到您完全切换为止。

如果您确实在 Docker 映像中构建了精确的库依赖项,并且确实为每个映像指定了不同的标签,那么更好的方法是设置集成测试环境。在那里运行应用程序的完整副本,包括您提议的库更新,并确保您有足够好的测试来知道它是否有效。如果您在此环境中成功运行(尤其是库更新),那么您很可能也会在生产中成功运行相同的图像,因此您可能可以直接跳到“更新部署”步骤,而无需更复杂的蓝色/green 部署设置。