Azure 中的 Python 容器应用概述

本文介绍如何从 Python 项目代码(例如 Web 应用)转到 Azure 中部署的 Docker 容器。 讨论的一般过程是容器化、Azure 中容器的部署选项,以及 Azure 中特定于 Python 的容器配置。

Docker 容器的性质是,从代码创建 Docker 映像并将该映像部署到 Azure 中的容器在编程语言中相似。 特定于语言的注意事项(在本例中,Python)在 Azure 中的容器化过程中处于配置中,尤其是支持 Python Web 框架(如 DjangoFlaskFastAPI)的 Dockerfile 结构和配置。

容器工作流方案

对于 Python 容器开发,用于从代码迁移到容器的一些典型工作流包括:

方案 说明 工作流
开发 在开发环境中生成 Python Docker 映像。 代码:git 将代码克隆到开发环境(已安装 Docker)。

生成:使用 Docker CLI、VS Code(带有扩展)、PyCharm(包含插件)。 在“使用 Python Docker 映像和容器”部分中介绍。

测试:在 Docker 容器的开发环境中。

推送:推送到Azure 容器注册表、Docker 中心或专用注册表等注册表。

部署:从注册表部署到 Azure 服务。
混合 在开发环境中,在 Azure 中生成 Python Docker 映像。 代码:git 将代码克隆到开发环境(不需要安装 Docker)。

生成:VS Code(包含扩展),Azure CLI。

推送:Azure 容器注册表

部署:从注册表部署到 Azure 服务。
Azure 所有云中;使用 Azure Cloud Shell 从 GitHub 存储库生成 Python Docker 映像代码。 代码:git 将 GitHub 存储库克隆到 Azure Cloud Shell。

生成:在 Azure Cloud Shell 中,使用 Azure CLI 或 Docker CLI。

推送:到注册表(如 Azure 容器注册表、Docker 中心或专用注册表)。

部署:从注册表部署到 Azure 服务。

这些工作流的最终目标是在支持 Docker 容器的一个 Azure 资源中运行容器,如下一部分所列。

开发环境可以是具有 Visual Studio Code 或 PyCharm、 Codespaces (云中托管的开发环境)或 Visual Studio 开发容器 (作为开发环境的容器)的本地工作站。

Azure 中的部署容器选项

以下服务支持 Python 容器应用。

服务 说明
用于容器的 Web 应用 适用于容器化 Web 应用程序的完全托管托管服务,包括网站和 Web API。 Azure 应用服务上的容器化 Web 应用可按需缩放,并将简化的 CI/CD 工作流与 Docker Hub、Azure 容器注册表和 GitHub 配合使用。 非常适合开发人员轻松利用完全托管的Azure App 服务平台,但还需要包含应用及其所有依赖项的单个可部署项目。

示例:在 Azure App 服务 上部署 Flask 或 FastPI Web 应用。
Azure 容器应用 (ACA) 由 Kubernetes 提供支持的完全托管无服务器容器服务,以及 DaprKEDAenvoy 等开源技术。 基于最佳做法并针对常规用途容器进行了优化。 群集基础结构由 ACA 管理,不支持直接访问 Kubernetes API。 在容器的基础上提供许多特定于应用程序的概念,包括证书、修订、规模和环境。 非常适合想要开始构建容器微服务的团队,而无需管理 Kubernetes 的基础复杂性。

示例: 在 Azure 容器应用上部署 Flask 或 FastPI Web 应用
Azure 容器实例 (ACI) 一种无服务器产品/服务,按需提供单个 Hyper-V 隔离容器。 按消耗而不是预配的资源计费。 缩放、负载均衡和证书等概念不随 ACI 容器一起提供。 用户通常通过其他服务与 ACI 交互;例如,用于业务流程的 AKS。 如果需要一个不太“有意见”的构建基块,该构建基块与 Azure 容器应用正在优化的方案不一致,则理想。

示例:创建用于部署到Azure 容器实例的容器映像。 (本教程不是特定于 Python 的,但显示的概念适用于所有语言。
Azure Kubernetes 服务 (AKS) Azure 中完全托管的 Kubernetes 选项。 支持直接访问 Kubernetes API 并运行任何 Kubernetes 工作负荷。 整个群集位于你的订阅中,群集配置和操作都由你控制和负责。 非常适合在 Azure 中查找完全托管版本的 Kubernetes 的团队。

示例:使用 Azure CLI 部署Azure Kubernetes 服务群集。
Azure Functions 事件驱动的无服务器函数即服务(FAAS)解决方案。 与 Azure 容器应用共享许多特征,这些特征围绕缩放和与事件集成,但针对部署为代码或容器的临时函数进行了优化。 非常适合希望触发对事件执行函数的团队;例如,要绑定到其他数据源。

示例: 使用自定义容器在 Linux 上创建函数。

有关这些服务的更详细比较,请参阅 将容器应用与其他 Azure 容器选项进行比较。

虚拟环境和容器

在开发环境中运行 Python 项目时,使用虚拟环境是管理依赖项并确保项目设置可重现的常见方法。 虚拟环境具有一个 Python 解释器、库和脚本,这些脚本由在该环境中运行的项目代码需要安装。 Python 项目的依赖项通过 requirements.txt 文件进行管理。

提示

对于容器,除非出于测试或其他原因使用虚拟环境,否则不需要虚拟环境。 如果使用虚拟环境,请不要将它们复制到 Docker 映像中。 使用 .dockerignore 文件排除它们。

可以将 Docker 容器视为提供与虚拟环境类似的功能,但在可重现性和可移植性方面具有进一步的优势。 无论 OS 如何,都可以在任意位置运行 Docker 容器。

Docker 容器包含 Python 项目代码以及代码需要运行的所有内容。 若要达到这一点,需要将 Python 项目代码构建到 Docker 映像中,然后创建容器(该映像的可运行实例)。

对于容器化 Python 项目,关键文件包括:

项目文件 说明
requirements.txt 在生成 Docker 映像期间用于获取映像中的正确依赖项。
Dockerfile 用于指定如何生成 Python Docker 映像。 有关详细信息,请参阅 Python 的 Dockerfile 说明部分
.dockerignore .dockerignore 中的文件和目录不会随 Dockerfile 中的命令复制到 Docker 映像COPY .dockerignore 文件支持类似于 .gitignore 文件的排除模式。 有关详细信息,请参阅 .dockerignore 文件

排除文件有助于映像生成性能,但还应用于避免将敏感信息添加到可以检查的映像。 例如, .dockerignore 应包含忽略 .env.venv (虚拟环境)的行。

Web 框架的容器设置

Web 框架具有侦听 Web 请求的默认端口。 使用某些 Azure 容器解决方案时,需要指定容器侦听的端口将接收流量。

Web 框架 端口
Django 8000
Flask 5000 或 5002
FastAPIuvicorn 8000 或 80

下表显示了如何设置不同 Azure 容器解决方案的端口。

Azure 容器解决方案 如何设置 Web 应用端口
用于容器的 Web 应用 默认情况下,应用服务假定自定义容器在端口 80 或端口 8080 上进行侦听。 如果容器侦听其他端口,请在App 服务应用中设置WEBSITES_PORT应用设置。 有关详细信息,请参阅为Azure App 服务配置自定义容器。
Azure 容器应用 使用 Azure 容器应用,可以通过启用入口,向公共 Web、VNET 或其他容器应用公开你的容器应用。 将入口 targetPort 设置为容器侦听传入请求的端口。 应用程序入口终结点始终在端口 443 上公开。 有关详细信息,请参阅 在 Azure 容器应用中设置 HTTPS 或 TCP 入口。
Azure 容器实例 Azure Kubernetes 在创建容器期间设置端口。 你需要确保解决方案具有 Web 框架、应用程序服务器(例如 gunicorn、uvicorn)和 Web 服务器(例如 nginx)。 例如,可以创建两个容器,一个容器包含 Web 框架和应用程序服务器,另一个容器与 Web 服务器。 这两个容器在一个端口上通信,Web 服务器容器公开 80/443 作为外部请求。

Python Dockerfile

Dockerfile 是一个文本文件,其中包含生成 Docker 映像的说明。 第一行表示要以基本映像开头。 此行后跟有关安装所需程序、复制文件和其他创建工作环境的说明。 例如,下表显示了一些特定于 Python 的 Python Dockerfile 指令的示例。

说明 用途 示例
FROM 设置后续说明的基本映像。 FROM python:3.8-slim
EXPO标准版 告知 Docker 容器在运行时侦听指定的网络端口。 EXPOSE 5000
复制 从指定的源复制文件或目录,并将其添加到位于指定目标路径的容器的文件系统中。 COPY . /app
运行 在 Docker 映像中运行命令。 例如,拉取依赖项。 该命令在生成时运行一次。 RUN python -m pip install -r requirements.txt
CMD 该命令提供用于执行容器的默认值。 只能有一个 CMD 指令。 CMD ["gunicorn", "--bind", "0.0.0.0:5000", "wsgi:app"]

Docker 生成命令从 Dockerfile 和上下文生成 Docker 映像。 生成上下文是位于指定路径或 URL 中的文件集。 通常,你将从 Python 项目的根目录生成映像,生成命令的路径为“。”如以下示例所示。

docker build --rm --pull  --file "Dockerfile"  --tag "mywebapp:latest"  .

生成过程可以引用上下文中的任何文件。 例如,生成可以使用 COPY 指令引用上下文中的文件。 下面是使用 Flask 框架的 Python 项目的 Dockerfile 示例:

FROM python:3.8-slim

EXPOSE 5000

# Keeps Python from generating .pyc files in the container.
ENV PYTHONDONTWRITEBYTECODE=1

# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED=1

# Install pip requirements.
COPY requirements.txt .
RUN python -m pip install -r requirements.txt

WORKDIR /app
COPY . /app

# Creates a non-root user with an explicit UID and adds permission to access the /app folder.
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
USER appuser

# Provides defaults for an executing container; can be overridden with Docker CLI.
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "wsgi:app"]

可以手动创建 Dockerfile,也可以使用 VS Code 和 Docker 扩展自动创建它。 有关详细信息,请参阅 生成 Docker 文件

Docker 生成命令是 Docker CLI 的一部分。 使用 VS Code 或 PyCharm 等 IDE 时,用于处理 Docker 映像的 UI 命令会为你调用生成命令,并自动指定选项。

使用 Python Docker 映像和容器

VS Code 和 PyCharm

无需在集成开发环境(IDE)中处理 Python 容器开发,但可以简化许多与容器相关的任务。 下面是可以使用 VS Code 和 PyCharm 执行的一些操作。

  • 下载并生成 Docker 映像。

    • 在开发环境中生成映像。
    • 在 Azure 中生成 Docker 映像,而无需在开发环境中安装 Docker。 (对于 PyCharm,请使用 Azure CLI 在 Azure 中生成映像。
  • 从现有映像、拉取映像或直接从 Dockerfile 创建和运行 Docker 容器。

  • 使用 Docker Compose 运行多容器应用程序。

  • 连接并使用 Docker Hub、GitLab、JetBrains Space、Docker V2 和其他自承载 Docker 注册表等容器注册表。

  • (仅限 VS Code) 添加为 Python 项目定制的 Dockerfile 和 Docker compose 文件。

若要设置 VS Code 和 PyCharm 以在开发环境中运行 Docker 容器,请使用以下步骤。

如果尚未安装,请安装 适用于 VS Code 的 Azure 工具。

说明 屏幕快照
步骤 1:使用 SHIFT + ALT + A 打开 Azure 扩展并确认已连接到 Azure。

还可以选择 VS Code 扩展栏上的 Azure 图标。

如果未登录,请选择“ 登录到 Azure ”,然后按照提示进行操作。

如果访问 Azure 订阅时遇到问题,可能是因为你在代理后面。 若要解决连接问题,请参阅 Visual Studio Code 中的网络连接。
Screenshot showing how Azure Tools looks once signed in.Screenshot showing how Azure Tools looks if you aren't signed in.
步骤 2:使用 CTRL + SHIFT + X 打开扩展、搜索 Docker 扩展并安装扩展。

还可以选择 VS Code 扩展栏上的“扩展 ”图标。
Screenshot showing how to add Docker extension to VS Code.
步骤 3:选择扩展栏中的 Docker 图标,展开映像,然后右键单击作为容器运行的映像。 Screenshot showing how to use the Docker extension in VS Code to run a container from a Docker image.
步骤 4:在终端窗口中监视 Docker 运行输出 Screenshot showing an example of running a container in VS Code.

Azure CLI 和 Docker CLI

还可以使用 Azure CLI 和 Docker CLI 处理 Python Docker 映像和容器。 VS Code 和 PyCharm 都有终端,你可以在其中运行这些 CLIs。

如果希望更好地控制生成和运行参数以及实现自动化,请使用 CLI。 例如,以下命令演示如何使用 Azure CLI az acr build 指定 Docker 映像名称。

az acr build --registry <registry-name> \
  --resource-group <resource-group> \
  --target pythoncontainerwebapp:latest .

作为另一个示例,请考虑以下命令,该命令演示如何使用 Docker CLI 运行 命令。 该示例演示如何在容器外部运行与开发环境中的 MongoDB 实例通信的 Docker 容器。 在命令行中指定时,完成命令的不同值更易于自动执行。

docker run --rm -it \
  --publish <port>:<port> --publish 27017:27017 \
  --add-host mongoservice:<your-server-IP-address> \
  --env CONNECTION_STRING=mongodb://mongoservice:27017 \
  --env DB_NAME=<database-name> \
  --env COLLECTION_NAME=<collection-name> \
  containermongo:latest  

有关此方案的详细信息,请参阅 在本地生成和测试容器化 Python Web 应用。

容器中的环境变量

Python 项目通常使用环境变量将数据传递给代码。 例如,可以在环境变量中指定数据库连接信息,以便在测试期间轻松更改它。 或者,将项目部署到生产环境时,可以更改数据库连接以引用生产数据库实例。

python-dotenv包通常用于从 .env 文件中读取键值对,并将其设置为环境变量。 在虚拟环境中运行时,.env 文件非常有用,但在使用容器时不建议这样做。 不要将 .env 文件复制到 Docker 映像中,尤其是在它包含敏感信息且容器将公开时。 使用 .dockerignore 文件将文件从复制到 Docker 映像中排除。 有关详细信息,请参阅本文中的虚拟环境和容器部分

可以通过多种方式将环境变量传递到容器:

  1. 在 Dockerfile定义为 ENV 指令。
  2. 使用 Docker 生成命令作为--build-arg参数传入。
  3. 使用 Docker 生成命令和 BuildKit 后端作为--secret参数传入。
  4. 使用 Docker 运行命令作为--env参数传入。--env-file

前两个选项的缺点与上面 提到的 .env 文件相同,即将潜在的敏感信息硬编码到 Docker 映像中。 可以检查 Docker 映像并查看环境变量,例如,使用命令 docker 映像检查

使用 BuildKit 的第三个选项,可以传递要在 Dockerfile 中使用的机密信息,以安全的方式生成 docker 映像,最终不会存储在最终映像中。

使用 Docker run 命令传入环境变量的第四个选项意味着 Docker 映像不包含变量。 但是,变量仍可以看到检查容器实例(例如,使用 docker 容器检查)。 当控制对容器实例的访问或在测试或开发方案中访问时,此选项是可以接受的。

下面是使用 Docker CLI run 命令和 --env 参数传递环境变量的示例。

# PORT=8000 for Django and 5000 for Flask
export PORT=<port-number>

docker run --rm -it \
  --publish $PORT:$PORT \
  --env CONNECTION_STRING=<connection-info> \
  --env DB_NAME=<database-name> \
  <dockerimagename:tag>

如果使用 VS Code 或 PyCharm,则用于处理映像和容器的 UI 选项最终使用 Docker CLI 命令,如上面所示的命令。

最后,在 Azure 中部署容器时指定环境变量不同于在开发环境中使用环境变量。 例如:

  • 对于用于容器的 Web 应用,可以在配置App 服务期间配置应用程序设置。 这些设置可以作为环境变量提供给应用代码,并使用标准的 os.environ 模式进行访问。 如果需要,可以在初始部署后更改值。 有关详细信息,请参阅 Access 应用设置作为环境变量

  • 对于 Azure 容器应用,可以在容器应用的初始配置过程中配置环境变量。 环境变量的后续修改会 创建容器的修订版 。 此外,Azure 容器应用允许在应用程序级别定义机密,然后在环境变量中引用它们。 有关详细信息,请参阅 管理 Azure 容器应用中的机密。

作为另一个选项,可以使用服务连接或帮助你将 Azure 计算服务连接到其他支持服务。 此服务在管理平面中配置计算服务与目标后备服务之间的网络设置和连接信息(例如,生成环境变量)。

查看容器日志

查看容器实例日志,查看代码输出的诊断消息,并排查容器代码中的问题。 下面是在开发环境中运行容器时查看日志的几种方法:

  • 使用 VS Code 或 PyCharm 运行容器,如 VS Code 和 PyCharm 部分所示,可以在 Docker 运行时打开的终端窗口中查看日志。

  • 如果使用带有交互式标志-it的 Docker CLI 运行命令,则会看到命令后面的输出。

  • 在 Docker Desktop,还可以查看正在运行的容器的日志。

在 Azure部署容器时,还可以访问容器日志。 下面是几个 Azure 服务以及如何访问Azure 门户中的容器日志。

Azure 服务 如何访问Azure 门户中的日志
用于容器的 Web 应用 转到 “诊断”并解决问题 资源以查看日志。 诊断 是一种智能交互式体验,可帮助你对应用进行故障排除,无需配置。 有关日志的实时视图,请转到监视 - 日志流。 有关更详细的日志查询和配置,请参阅“监视”下的其他资源。
Azure Container Apps 转到环境资源 诊断并解决问题 以排查环境问题。 更频繁地需要查看容器日志。 在容器资源中的应用程序 - 修订管理,选择修订,并从中可以查看系统和控制台日志。 有关更详细的日志查询和配置,请参阅“监视”下的资源。
Azure 容器实例 转到 “容器 ”资源,然后选择“ 日志”。

对于上面列出的相同服务,下面是用于访问日志的 Azure CLI 命令。

Azure 服务 用于访问日志的 Azure CLI 命令
用于容器的 Web 应用 az webapp log
Azure Container Apps az containerapps logs
Azure 容器实例 az container logs

还支持在 VS Code 中查看日志。 必须 安装用于 VS Code 的 Azure 工具。 下面是在 VS Code 中查看容器(App 服务)日志Web 应用的示例。

Screenshot showing how to view logs in VS Code for Web Apps for Containers.

后续步骤