项目开发--基于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#/

相关推荐
吴半杯1 小时前
gateway漏洞(CVE-2022-22947)
docker·kubernetes·gateway
今天我刷leetcode了吗1 小时前
docker 配置同宿主机共同网段的IP 同时通过通网段的另一个电脑实现远程连接docker
tcp/ip·docker·电脑
lwprain2 小时前
常用docker应用部署,wordpress、mysql、tomcat、nginx、redis
mysql·docker·tomcat
Code_Artist3 小时前
使用Portainer来管理并编排Docker容器
docker·云原生·容器
mengao12344 小时前
centos 服务器 docker 使用代理
服务器·docker·centos
Eternal-Student4 小时前
【docker 保存】将Docker镜像保存为一个离线的tar归档文件
运维·docker·容器
不是二师兄的八戒4 小时前
本地 PHP 和 Java 开发环境 Docker 化与配置开机自启
java·docker·php
码农小丘4 小时前
一篇保姆式centos/ubuntu安装docker
运维·docker·容器
Eternal-Student4 小时前
【1.2 Getting Started--->Installation Guide】
docker
灼烧的疯狂5 小时前
K8S + Jenkins 做CICD
容器·kubernetes·jenkins