【问题标题】:How to manage Python package versions installed in docker images and in running containers如何管理安装在 docker 镜像和正在运行的容器中的 Python 包版本
【发布时间】:2021-04-05 01:50:58
【问题描述】:

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

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

在不知道有什么实用工具可以为我做这件事的情况下,我有一个想法可以解释我想要完成的一些事情-

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

有没有更简洁的方法可以使用现有的实用程序来做到这一点?

【问题讨论】:

  • 你是如何安装 Python 包的?例如,您可以使用“点子列表”
  • 它在 Dockerfile 中有一个私有 repo 和非系统版本的 Python,例如运行 pip3.8 install --extra-index-url 192.168.0.11:${PIP_REPO_PORT_FOR_THIS_RELEASE_STAGE} --trusted-host 192.168.0.11 my_package==${MY_PACKAGE_VERSION}

标签: docker kubernetes pip docker-swarm


【解决方案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 更改每个 Pod 的副本数,直到您完全切换为止。

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

【讨论】:

  • 与 Kubernetes 与 Jenkins + 原生 docker 进行持续集成有哪些好处?仅仅是弹性和回滚管理还是更多?
  • 由于问题被标记为“kubernetes”,我认为它已经是部署管道的一部分。我在最后几段中描述的工作流程很难用普通的 Docker 完成。 CD 系统需要知道自己才能部署一个新容器,检查它是否正在运行,然后拆除旧容器,但这是 Kubernetes Deployment 开箱即用的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-23
  • 2020-07-03
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
相关资源
最近更新 更多