项目开发--基于docker实现模型容器化服务

背景

基于docker实现模型容器化服务当中遇到的问题

解决方案

问题1:docker-compose build 和 docker-compose up -d分别是什么作用?

docker-compose build 和 docker-compose up -d 是 Docker Compose 命令,用于构建和管理多容器 Docker 应用程序。它们的作用如下:

bash 复制代码
docker-compose build

作用:构建 Docker 镜像。

使用场景:当你对 Dockerfile 或 docker-compose.yml 文件进行了更改(例如更新了依赖项或修改了构建指令)时,需要重新构建镜像。

详细说明:

这个命令根据 Dockerfile 文件中的指令构建 Docker 镜像,并根据 docker-compose.yml 文件中的服务定义来执行构建过程。

构建过程中 Docker 会从 Dockerfile 中读取指令,例如安装依赖、复制文件等,并生成一个新的镜像。

这个命令不会启动容器,只是创建或更新镜像。

bash 复制代码
docker-compose up -d

作用:启动或重新启动 Docker 容器。

使用场景:当你想启动定义在 docker-compose.yml 文件中的服务(容器)时,使用这个命令。

详细说明:

-d 参数表示在后台(detached mode)启动容器,这样你不会被容器的日志信息干扰。如果不使用 -d,容器会在前台运行,日志会输出到你的终端。

如果镜像尚未构建或已更改,docker-compose up 会自动调用 docker-compose build 来构建镜像,然后启动容器。

启动时,Docker Compose 会创建或启动 docker-compose.yml 文件中定义的服务容器,并将它们连接到指定的网络和卷(volumes)。

总结

docker-compose build:用于构建 Docker 镜像,通常在修改 Dockerfile 或 requirements.txt 后使用。

docker-compose up -d:用于启动或重新启动容器,并在后台运行它们。

通常,工作流程是先使用 docker-compose build 构建镜像,然后使用 docker-compose up -d 启动容器。如果只是更新了代码或配置文件而不修改 Dockerfile,直接使用 docker-compose up -d 也可以自动构建镜像并启动容器。

问题2:如何进入新构建的容器当中

要进入新构建的 Docker 容器,你可以使用以下步骤:

  1. 查找容器 ID 或名称
    首先,你需要找到你想要进入的容器的 ID 或名称。使用以下命令列出所有运行中的容器:
bash 复制代码
docker ps

这将显示一个容器列表,包括容器的 ID、名称和其他信息。

  1. 使用 docker exec 进入容器
    一旦你找到了容器的 ID 或名称,你可以使用 docker exec 命令进入容器的交互式 shell。例如,如果你想进入一个名为 my_container 的容器,可以运行:
bash 复制代码
docker exec -it my_container /bin/bash

或,如果容器使用 sh 而不是 bash,可以运行:

bash 复制代码
docker exec -it my_container /bin/sh
  1. 示例
    假设你有一个容器 ID 为 abc123,可以使用:
bash 复制代码
docker exec -it abc123 /bin/bash
  1. 在 Dockerfile 中使用非 root 用户
    如果你在 Dockerfile 中创建了一个非 root 用户,并且想以该用户身份进入容器,可以指定用户:
bash 复制代码
docker exec -it --user <username> my_container /bin/bash

注意事项

-it 参数:-i 代表交互模式(interactive),-t 代表分配一个伪终端(pseudo-TTY),这两个参数通常一起使用。

Shell 类型:不同的容器可能使用不同的 shell(例如 /bin/bash、/bin/sh),你需要根据实际情况选择合适的 shell。

问题3:模型保存的方法区别

使用pickle和使用torch.save保存的模型有什么区别?

pickle 和 torch.save 是两种不同的序列化方法,它们在保存模型时有一些关键的区别:

库和用途:

pickle 是 Python 标准库中的一个模块,用于序列化和反序列化 Python 对象结构,它不仅限于 PyTorch 模型,可以用于任何 Python 对象。

torch.save 是 PyTorch 库提供的一个函数,专门用于保存 PyTorch 模型和张量。它不仅保存模型的参数,还可以保存模型的结构。

兼容性:

使用 pickle 保存的模型在不同版本的 Python 或 PyTorch 之间可能会遇到兼容性问题,因为 pickle 格式可能会随着 Python 版本的更新而改变。

torch.save 通常提供了更好的向后兼容性,尤其是在 PyTorch 的不同版本之间。

效率:

torch.save 通常在保存 PyTorch 模型时更加高效,因为它是专门为 PyTorch 数据类型设计的。

pickle 可能在处理大型模型或张量时不如 torch.save 高效。

安全性:

pickle 可以序列化几乎所有的 Python 对象,包括那些可能执行任意代码的对象。因此,如果从不可信任的源加载 pickle 文件,可能会有安全风险。

torch.save 只处理 PyTorch 相关的数据,相对来说更安全。

使用场景:

如果你需要在不同的 Python 环境或项目中共享模型,或者需要序列化非 PyTorch 对象,可能会选择 pickle。

对于 PyTorch 模型,通常推荐使用 torch.save,因为它提供了更好的兼容性和效率。

模型结构保存:

使用 pickle 可能无法正确保存模型的结构,特别是如果模型定义在保存和加载时不可见(例如,模型定义在某个特定的脚本中,而该脚本在加载模型时未被执行)。

torch.save 允许你保存模型的结构,这样即使模型定义在加载时不可用,也可以正确地恢复模型。

总结来说,对于 PyTorch 模型,推荐使用 torch.save,因为它提供了更好的兼容性、效率和安全性。而 pickle 更适合通用的 Python 对象序列化,但需要注意安全性和兼容性问题。

问题4:如何让docker容器启动的时候能使用cuda进行模型推理加速

要让 Docker 容器启动时能够使用 CUDA 进行模型推理加速,您需要确保以下几个方面:

  1. 安装 NVIDIA Docker 支持
    NVIDIA Docker(nvidia-docker)提供了对 NVIDIA GPU 的支持,并允许 Docker 容器访问主机上的 GPU。您需要安装 NVIDIA Container Toolkit。

安装 NVIDIA Container Toolkit

添加 NVIDIA 的软件包源:

bash 复制代码
sudo mkdir -p /etc/systemd/system/docker.service.d

创建文件 /etc/systemd/system/docker.service.d/override.conf,内容如下:

ini 复制代码
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --host=fd:// --add-runtime=nvidia=/usr/bin/nvidia-container-runtime

安装 NVIDIA Container Toolkit:

bash 复制代码
sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker

验证安装:

使用以下命令验证 NVIDIA 运行时是否可用:

bash 复制代码
docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi

这应该会显示您 GPU 的信息。

  1. 编写 Dockerfile 使用 CUDA
    确保 Dockerfile 使用了正确的 CUDA 基础镜像,并且安装了必要的 CUDA 库和驱动。以下是一个基本示例 Dockerfile:
bash 复制代码
# 使用 NVIDIA 的 CUDA 镜像作为基础镜像
FROM nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu20.04

# 安装 Python 和其他依赖
RUN apt-get update && apt-get install -y \
    python3-pip \
    python3-dev \
    && rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /opt

# 复制 requirements 文件并安装 Python 包
COPY requirements.txt ./
RUN pip3 install -r requirements.txt

# 复制项目文件
COPY . .

# 设置容器启动命令
CMD ["python3", "main.py"]
  1. 配置 Docker Compose 使用 GPU
    在 docker-compose.yml 文件中,配置使用 GPU 资源。以下是一个示例:
yaml 复制代码
version: "3.8"

services:
  web:
    build: .
    ports:
      - "8890:8890"
    restart: always
    volumes:
      - ".:/opt/"
    working_dir: "/opt/"
    command: uvicorn main:app --reload --host 0.0.0.0 --port 8890
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: "nvidia"
              count: all
              capabilities: [gpu]
  1. 运行 Docker 容器
    使用 docker-compose 启动容器:
bash 复制代码
docker-compose up -d
  1. 在代码中检查 GPU 可用性
    确保您的模型代码中能够识别和使用 GPU。例如,如果使用 PyTorch,可以通过以下代码检查 GPU 是否可用:
python 复制代码
import torch

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f'Using device: {device}')

对于 TensorFlow,可以使用:

python 复制代码
import tensorflow as tf

print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU')))

总结

安装 NVIDIA Container Toolkit 以支持 Docker 容器使用 GPU。

编写 Dockerfile 使用 CUDA 基础镜像,并安装必要的 CUDA 库。

配置 Docker Compose 使用 GPU 资源。

验证和运行容器 确保 GPU 可以被正确识别和使用。

通过这些步骤,您应该能够在 Docker 容器中启用 CUDA 加速进行模型推理。

问题5:如何实现容器的迭代

在使用 docker-compose 时,容器的迭代包括了容器的启动与关闭、版本控制以及持久化存储。以下是如何实现这些迭代的步骤:

bash 复制代码
docker-compose down
docker-compose build
docker-compose up -d

容器的启动与关闭

启动容器:

bash 复制代码
docker-compose up -d

这个命令会启动 docker-compose.yml 文件中定义的服务,-d 参数表示在后台运行。

停止容器:

bash 复制代码
docker-compose down

这个命令会停止所有由 docker-compose.yml 定义的服务,并可以选择性地移除网络和数据卷。

重启容器:

bash 复制代码
docker-compose restart

这个命令会重启所有服务。

关闭并移除容器:

bash 复制代码
docker-compose down --volumes

这个命令会停止容器并移除容器,--volumes 参数表示同时移除数据卷。

版本号

在 docker-compose 中,版本号通常与使用的 Docker 镜像版本相关。你可以在 docker-compose.yml 文件中指定使用特定版本的镜像:

yaml 复制代码
services:
  your-service:
    image: your-image:1.0.0

当你需要更新服务到新版本时,只需更改版本号并重新部署:

bash 复制代码
docker-compose up -d

持久化存储

在 docker-compose.yml 中,你可以定义数据卷来实现持久化存储:

yaml 复制代码
volumes:
  your-volume:

services:
  your-service:
    volumes:
      - your-volume:/path/in/container

创建数据卷:

docker-compose up -d 时,如果数据卷不存在,docker-compose 会自动创建。

访问数据卷:

在服务中,你可以通过挂载的数据卷路径来访问持久化的数据。

备份数据卷:

你可以使用 docker-compose down -v 来备份数据卷,这会停止服务并删除容器,但保留数据卷。

迁移数据卷:

如果需要迁移数据卷,可以使用 docker-compose 的卷驱动或手动复制数据。

版本控制:

对于 docker-compose.yml 文件本身,你可以使用版本控制系统(如 Git)来管理其变更历史。每次更新配置或服务后,提交更改到版本控制系统。

问题6:容器的上传和下载

docker-compose build没有问题的容器如何去上传和下载

在使用 Docker Compose 时,构建(build)镜像只是容器生命周期的第一步。上传(push)和下载(pull)镜像通常是指与 Docker 镜像仓库交互,如 Docker Hub、GitHub Container Registry、GitLab Container Registry 或其他私有仓库。以下是如何上传和下载 Docker 镜像的步骤:

上传(Push)镜像到 Docker Hub

登录到 Docker Hub:

在命令行中使用 docker login 命令登录到 Docker Hub。你需要提供你的 Docker Hub 用户名和密码。

bash 复制代码
docker login

构建 Docker 镜像:

使用 docker-compose build 构建你的镜像。Docker Compose 会根据 docker-compose.yml 文件中的服务定义来构建镜像。

bash 复制代码
docker-compose build

标记(Tag)镜像:

在上传到 Docker Hub 之前,你需要为你的镜像打上标签。这包括仓库名、用户名和标签(通常是版本号)。

bash 复制代码
docker tag local-image:tag your-dockerhub-username/repo-name:tag

例如,如果你的本地镜像名为 myapp,你想将其上传到 Docker Hub 上的 myusername/myapp 仓库,并且你想标记为 latest:

bash 复制代码
docker tag myapp:latest myusername/myapp:latest

上传镜像:

使用 docker push 命令将镜像上传到 Docker Hub。

bash 复制代码
docker push your-dockerhub-username/repo-name:tag

使用上面的例子:

bash 复制代码
docker push myusername/myapp:latest

从 Docker Hub 下载(Pull)镜像

拉取镜像:

使用 docker pull 命令从 Docker Hub 下载镜像。

bash 复制代码
docker pull your-dockerhub-username/repo-name:tag

例如:

bash 复制代码
docker pull myusername/myapp:latest

注意事项

确保在上传镜像之前,你已经正确登录到 Docker Hub。

如果你的镜像很大,上传可能需要一些时间。

在 docker-compose.yml 文件中,你可以使用 image 属性来指定使用哪个镜像,无论是本地的还是远程仓库的。

如果你使用的是私有仓库,你需要确保你有正确的权限,并且可能需要处理认证问题。

如果你想要在 docker-compose.yml 中直接使用远程镜像,你可以在服务定义中指定 image 的值,例如:

yaml 复制代码
service:
  image: myusername/myapp:latest

在上传和下载镜像时,确保遵守 Docker Hub 或其他仓库的服务条款。

参考资料

https://blog.csdn.net/gongdiwudu/article/details/131987709#/

相关推荐
小张是铁粉2 小时前
docker学习二天之镜像操作与容器操作
学习·docker·容器
烟雨书信2 小时前
Docker文件操作、数据卷、挂载
运维·docker·容器
IT成长日记2 小时前
【Docker基础】Docker数据卷管理:docker volume prune及其参数详解
运维·docker·容器·volume·prune
这儿有一堆花2 小时前
Docker编译环境搭建与开发实战指南
运维·docker·容器
LuckyLay2 小时前
Compose 高级用法详解——AI教你学Docker
运维·docker·容器
Uluoyu3 小时前
redisSearch docker安装
运维·redis·docker·容器
IT成长日记7 小时前
【Docker基础】Docker数据持久化与卷(Volume)介绍
运维·docker·容器·数据持久化·volume·
热爱生活的猴子7 小时前
阿里云服务器正确配置 Docker 国内镜像的方法
服务器·阿里云·docker
FrankYoou11 小时前
Jenkins 与 GitLab CI/CD 的核心对比
java·docker
隆里卡那唔11 小时前
在dify中通过http请求neo4j时为什么需要将localhost变为host.docker.internal
http·docker·neo4j