在 Windows 上部署支持 CUDA 的 Docker 容器

概述

本指南将帮助你在 Windows 系统上部署一个支持 CUDA 的 Docker 开发容器,该容器基于 Ubuntu 20.04,并预装了 Python、PyTorch 等开发环境,同时配置了 SSH 服务以便远程访问。

前提条件

  1. Windows 10 或 Windows 11(版本 21H2 或更高)
  2. 已安装 Docker Desktop for Windows
  3. 支持 CUDA 的 NVIDIA GPU
  4. 已安装 NVIDIA 显卡驱动(版本 516.xx 或更高)
  5. 已安装 WSL 2(Windows Subsystem for Linux 2)

步骤

1. 验证系统准备情况

首先,确保你的系统满足以下要求:

  • 确认已启用 WSL 2:

    wsl --list --verbose
    
  • 确认已安装 NVIDIA 驱动且支持 CUDA:

    nvidia-smi
    
  • 如果没有安装该驱动的可以移步至我的另一篇blog:“在Windows 系统上安装和配置 NVIDIA 驱动”

2. 安装 NVIDIA Container Toolkit

  1. 下载并安装 NVIDIA Container Toolkit:

  2. 或在 WSL 2 的 Linux 发行版中运行:

    distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
    curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
    curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
    sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
    sudo nvidia-ctk runtime configure --runtime=docker
    sudo systemctl restart docker
    

3. 配置 Docker Desktop

  1. 打开 Docker Desktop 设置
  2. 前往 "General" 确保已勾选 "Use the WSL 2 based engine"
  3. 前往 "Resources" > "WSL Integration" 启用你的 WSL 2 发行版
  4. 前往 "Docker Engine" 并确保配置中包含以下内容:
    {
      "runtimes": {
        "nvidia": {
          "path": "nvidia-container-runtime.exe",
          "runtimeArgs": []
        }
      }
    }
    

4. 创建项目文件

  1. 在你的工作目录中创建以下文件:

    Dockerfile:

    # 使用官方 CUDA 镜像作为基础
    FROM nvidia/cuda:11.8.0-runtime-ubuntu20.04
    
    # 避免安装过程中交互式提示
    ENV DEBIAN_FRONTEND=noninteractive
    
    # 配置 Ubuntu 使用清华源
    RUN sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list && \
        sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
    
    # 安装系统依赖和开发工具,包括 SSH 服务器
    RUN apt-get update && apt-get install -y \
        curl \
        wget \
        git \
        build-essential \
        openssh-server \
        python3 \
        python3-pip \
        sudo \
        && rm -rf /var/lib/apt/lists/*
    
    # 为 VS Code 创建用户并设置密码
    RUN useradd -m -s /bin/bash vscode && \
        echo "vscode:vscode" | chpasswd && \
        usermod -aG sudo vscode && \
        echo "vscode ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
    
    # 配置 SSH
    RUN mkdir /var/run/sshd && \
        sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
        sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
    
    # 安装 Python 包
    USER vscode
    WORKDIR /home/vscode
    RUN pip install numpy pandas torch -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    # 暴露 SSH 端口
    EXPOSE 22
    
    # 启动 SSH 服务
    CMD ["sudo", "/usr/sbin/sshd", "-D"]
    

    docker-compose.yml:

    version: '3.8'
    
    services:
      cuda-dev:
        build:
          context: .
          dockerfile: Dockerfile
        container_name: cuda-dev
        ports:
          - "2222:22"  # 将容器的SSH端口映射到宿主机的2222端口
        runtime: nvidia  # 使用NVIDIA容器运行时以支持GPU
        deploy:
          resources:
            reservations:
              devices:
                - driver: nvidia
                  count: all
                  capabilities: [gpu]
        restart: unless-stopped
        volumes:
          - ./workspace:/home/vscode/workspace  # 可选:挂载工作目录以便持久化代码
        environment:
          - NVIDIA_VISIBLE_DEVICES=all
    

5. 构建和运行容器

  1. 打开 PowerShell 或 WSL 终端,导航到项目目录
  2. 构建 Docker 镜像:
    docker-compose build
    
  3. 启动容器:
    docker-compose up -d
    

6. 测试容器

  1. 验证容器是否正常运行:

    docker ps
    
  2. 测试 SSH 连接:

    ssh -p 2222 vscode@localhost
    

    密码是 vscode

  3. 测试 CUDA 是否可用:

    python3 -c "import torch; print(torch.cuda.is_available())"
    

网络配置:在 Windows 防火墙中开放 2222 端口

为了让宿主机或其他设备能够通过 SSH 访问容器,需要配置 Windows 防火墙,允许对 2222 端口的入站连接。以下是两种方法:

方法一:通过图形化界面操作 (Windows Defender 防火墙)

  1. 打开 Windows Defender 防火墙

    • 在开始菜单搜索“高级安全 Windows Defender 防火墙”并打开它。
    • 或者,按 Win + R,输入 wf.msc 然后回车。
  2. 创建新的入站规则

    • 在左侧窗格中,右键点击“入站规则”,然后选择“新建规则...”。
  3. 规则类型

    • 选择“端口”,然后点击“下一步”。
  4. 协议和端口

    • 选择“TCP”。
    • 选择“特定本地端口”,并在旁边的输入框中输入 2222
    • 点击“下一步”。
  5. 操作

    • 选择“允许连接”,然后点击“下一步”。
  6. 配置文件

    • 根据您的网络环境选择何时应用该规则(通常默认全选“域”、“专用”、“公用”即可),点击“下一步”。
  7. 名称

    • 为该规则起一个易于识别的名称,例如“Docker Container SSH”或“Port 2222 for CUDA Dev”。
    • 可以添加更详细的描述,如“允许通过 SSH 访问运行在 Docker 中的开发容器”。
    • 点击“完成”。

现在,新的规则会出现在入站规则列表中,表示端口 2222 已对外部开放。

方法二:通过 PowerShell (管理员权限)

使用命令行可以快速完成同样的操作。

  1. 以管理员身份运行 PowerShell

    • 在开始菜单搜索“PowerShell”。
    • 右键单击“Windows PowerShell”,然后选择“以管理员身份运行”。
  2. 执行命令创建防火墙规则

    • 将以下命令复制到 PowerShell 中执行:
    New-NetFirewallRule -DisplayName "允许 Docker 容器 SSH (TCP 2222)" -Direction Inbound -LocalPort 2222 -Protocol TCP -Action Allow
    
    • 命令参数解释
      • -DisplayName “...”:规则的名称,便于识别。
      • -Direction Inbound:规则针对入站流量。
      • -LocalPort 2222:开放的本地端口号。
      • -Protocol TCP:协议类型。
      • -Action Allow:执行允许的操作。
  3. 验证规则是否添加成功

    • 可以运行以下命令查看所有包含“2222”端口的规则:
    Get-NetFirewallRule | Where-Object { $_.DisplayName -like "*2222*" } | Format-Table DisplayName, Enabled, Direction, Action
    

注意事项

  • 管理员权限:两种方法都需要管理员权限。
  • 安全性:开放端口会带来一定的安全风险。请确保您信任连接到该端口的设备,并且容器内的 SSH 密码足够强壮(建议使用密钥认证以获得更高安全性)。
  • 即时生效:规则创建后会立即生效,无需重启电脑或 Docker。

故障排除

  1. NVIDIA 驱动问题
    [... 后续内容保持不变 ...]

故障排除

  1. NVIDIA 驱动问题

    • 确保已安装最新 NVIDIA 驱动
    • 运行 nvidia-smi 确认驱动正常工作
  2. WSL 2 问题

    • 确保 WSL 2 已更新到最新版本
    • 运行 wsl --update 更新 WSL
  3. 端口冲突

    • 如果端口 2222 已被占用,请在 docker-compose.yml 中更改端口映射
  4. 权限问题

    • 如果遇到文件权限问题,尝试在 Docker Desktop 设置中启用 "Use the WSL 2 based engine"

使用建议

  1. 可以使用 VS Code 的 Remote - SSH 扩展连接到容器
  2. 将代码放在 workspace 目录中以便持久化存储
  3. 如需其他 Python 包,可以修改 Dockerfile 中的 pip install 命令

参考资料

  1. Docker Desktop for Windows 文档
  2. NVIDIA Container Toolkit 文档
  3. WSL 2 文档

通过以上步骤,你应该能够在 Windows 上成功部署支持 CUDA 的 Docker 容器。如果遇到任何问题,请参考故障排除部分或查阅相关文档。

posted on 2025-09-04 12:02  cmxcxd  阅读(607)  评论(0)    收藏  举报