Docker+PyCharm远程调试&环境隔离解决方案

Docker+PyCharm+Miniconda实现深度学习代码远程调试和环境隔离

本文详细介绍了如何在局域网环境下,利用Docker、PyCharm和Miniconda构建一个高效的深度学习远程调试平台。首先在服务器(server)上,通过Docker构建包含不同CUDA环境的镜像,以运行容器并实现环境的隔离。通过位于主机(host)的PyCharm,将项目代码deploy至容器中,从而实现远程debug或代码运行。为了处理容器内产生的大量数据文件,这些文件将被挂载到服务器的存储设备上。此外,通过在服务器(Windows系统)上设置文件分享,与主机建立连接,便于用户在主机上访问和浏览由深度学习应用产生的数据。这种配置确保Host内的项目代码只能在Host上被修改,而server上的数据文件只能在host上被预览且不可更改,从而最大程度上保障了数据的安全性和完整性。

环境说明

  • Windows 11 23H2
  • Docker Desktop 4.34.2(Windows)
  • Docker Engine v27.2.0
  • PyCharm 2024.2.1
  • GeForce 3060Ti

路由配置

WAN口接入互联网,LAN口接host和servers,为LAN口配置静态ip(例如本文主图的静态ip配置)。

关于路由:我选用的是水星(Mercury)MR100GP-AC 商用5口千兆有线路由-250元。

Docker设置(Windows系统)

以Windows上Docker Desktop 4.34.2 (167172)为例。

环境配置

docker图标右键,switch to Linux containers切换至Linux container!如果显示switch to Windows containers说明已经在Linux container环境了,跳过该步骤即可。

设置里builders把desktop-Linux设置为default builder.

网络配置

设置里general->expose daemon on tcp://localhost:2375选项开启。(让其他软件可以调用docker的daemon接口)

that only can be accessed via tcp://127.0.0.1, My inner IP address 192.168.3.9 doesn't work. The document said to edit the C:\ProgramData\Docker\config\daemon.json and add "hosts": ["tcp://0.0.0.0:2375"], but it's doesn't work for any IP address, I'm very sure I did it as the document.

不要尝试上述方案,因为不起作用。请按下述方式进行。

管理员身份运行Windows powershell,运行(监听+防火墙):

bash 复制代码
netsh interface portproxy add v4tov4 listenport=2375 connectaddress=127.0.0.1 connectport=2375 listenaddress=192.168.1.3 protocol=tcp
netsh advfirewall firewall add rule name="docker_daemon" dir=in action=allow protocol=TCP localport=2375

listenaddress=192.168.1.3是我server的静态ip,你应当修改为你的server的实际地址。

设置docker的proxy才能拉取镜像,或者换源(大部分镜像最近都失效了或者只能在校园/公司网内部使用)。

注意,上述ip和port应当改成你自己局域网内的proxy地址。

连接测试

pycharm(2024.2): settings->build,execution,deployment->docker

通过TCP socket连接server's docker,若virtual machine path那个框内有项目,可以先把里面的项目删掉。看是否显示connection successful.

然后你可以在pycharm里远程控制docker on the server.(找到侧边栏services或快捷键alt+8)。你可以自行探索一下pycharm的远程docker控制功能有哪些。

构建image

直接pull image

我构建好的镜像已上传my docker hub,可以直接pull,避免手动构建失败:

  • GeForce 3060Ti适用
  • 此镜像从nvidia官方镜像nvidia/cuda:11.3.1-cudnn8-runtime-ubuntu20.04构建
bash 复制代码
docker pull sylvanding/my-cuda:11.3.1-cudnn8-runtime-ubuntu20.04

image push命令:

bash 复制代码
docker push sylvanding/my-cuda:11.3.1-cudnn8-runtime-ubuntu20.04
# The push refers to repository [docker.io/sylvanding/my-cuda]

从Dockerfile手动构建

我的server使用GeForce 3060Ti(以此为例),我们从nvidia官方镜像nvidia/cuda:11.3.1-cudnn8-runtime-ubuntu20.04开始构建dockerfile:

  • 继承官方cuda和cudnn runtime环境
  • 安装工具包(最重要的是openssh-server将用于pycharm远程连接)
  • 修改root用户登录密码
  • 修改openssh配置文件,允许远程连接
  • 安装nvidia-container-toolkit(会根据当前容器环境自动选择合适的版本),从而使nvidia-smi等命令可以运行
  • 安装miniconda
  • 设置工作目录和暴露接口

上述dockerfile文件如下:

dockerfile 复制代码
FROM nvidia/cuda:11.3.1-cudnn8-runtime-ubuntu20.04

LABEL maintainer="sylvanding@qq.com"

# set env
# https://stackoverflow.com/questions/61388002/how-to-avoid-question-during-the-docker-build
ENV TZ=Asia/Shanghai \
    DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
    wget \
    curl \
    git \
    bzip2 \
    vim \
    openssh-server \
    && rm -rf /var/lib/apt/lists/*

# change root pwd
ARG USERPWD=123456
RUN echo "root:${USERPWD}" | chpasswd

# openssh config
RUN mkdir /var/run/sshd
RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config.d/ssh_config.conf \
    && echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config.d/ssh_config.conf
RUN service ssh restart

# install nvidia-container-toolkit
# https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
## configure the production repository
RUN curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o \
    /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
    && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
        sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
        tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
## update the packages list from the repository
RUN apt-get update
## install the NVIDIA Container Toolkit packages
RUN apt-get install -y nvidia-container-toolkit

# install Miniconda
# https://docs.anaconda.com/miniconda/#quick-command-line-install
RUN mkdir -p ~/miniconda3
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
RUN bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
RUN rm ~/miniconda3/miniconda.sh
## initialize newly-installed Miniconda
RUN ~/miniconda3/bin/conda init bash

WORKDIR /repos

EXPOSE 22 8080

各个组件的版本选择:显卡驱动 → CUDA → CUDA Toolkit → cuDNN → Pytorch

通过命令构建image
bash 复制代码
docker build --build-arg HTTP_PROXY=http://192.168.1.2:10811 -f ./path/to/your/Dockerfile -t sylvanding/my-cuda:11.3.1-cudnn8-runtime-ubuntu20.04 .

注意:修改你的http_proxy才能顺利构建环境(国内)。

在pycharm里构建image

打开编写的dockerfile,edit设置build image的配置:

name是你这个run configuration的名称,server选择你刚刚添加的docker服务器接口,注意:在build args中添加http_proxy才能顺利构建环境(国内)。之前设置的proxy只是docker desktop的proxy,这里构建镜像时要再次指定! 最后,apply和run。

创建容器

pycharm里选中image右键create container.

docker run配置:

  • server: 设置为之前配置的网络docker
  • bind ports: 将container 22端口映射到server的2222端口
  • bind mounts: 将container的/repos工作路径挂载到server的E:\repos,方便以后直接在server(Windows)里设置E:\repos文件夹网络共享文件
  • env variables: 为container设置proxy,记得更换为你自己的
  • run options: --gpus all
bash 复制代码
docker run -p 2222:22 -v E:\repos:/repos --env http_proxy=http://192.168.1.2:10811 --env https_proxy=http://192.168.1.2:10811 --name cuda113-cudnn8-ubuntu20 --pull missing --restart always --gpus all sylvanding/my-cuda:11.3.1-cudnn8-runtime-ubuntu20.04 

☑️ container创建成功:

PyCharm项目部署和远程同步(基于Windows文件共享)

pycharm项目部署

settings->deployment->new SFTP

新建ssh连接

❌ 若test connection提示:Cannot connect to remote host: net.schmizz.sshj.transport.TransportException: Server closed connection during identification exchange,首先尝试重启ssh服务docker exec cuda113-cudnn8-ubuntu20 service ssh restart. 若依然无法连接,检查/etc/ssh/sshd_config.d/*.conf/etc/ssh/sshd_config等ssh配置文件和防火墙配置,修改正确后重启ssh服务再次进行test connection.

root path设置为工作目录;Rsync可根据个人需求选择是否开启。

设置项目mapping路径:local path是本地项目路径 --mapping>> deployment path是server上相对于root path的远程项目路径。

向server的development path推送项目:选中需要推送的项目(比如我的project是DBlink),工具栏tools->deployment->upload...,建议开启automatic upload.

⚠️ 不推荐使用Deployment中的 Mapping 设置,为记录的完整性在此列出相关操作。更推荐在配置远程interpreter 时直接设置项目同步(见下一节),原因如下:

  • Deployment 功能主要用于将本地开发环境中的文件部署到远程服务器上。这包括将代码文件、资源和相关配置文件传输到线上环境或开发测试服务器中。
  • SSH 连接解释器中的 Sync Folders 设置,主要用于同步本地和远程解释器环境中的文件,以便在远程服务器上运行和测试代码,同时保持本地和远程环境的代码一致性。非常适合于远程开发场景,可以在本地编辑代码并直接在远程环境下运行和调试。

Deployment 主要用于部署,而 Sync Folders 更侧重于持续的开发和实时调试。如果是开发过程中频繁需要测试代码,即利用远程资源和环境,则使用 SSH 解释器的 Sync Folders 更为合适;如果主要是将更新推送到生产或测试环境,使用 Deployment 功能会更直接有效。 ------generated by GPT

推送成功结果查看:

pycharm远程miniconda环境解释器配置

通过ssh连接远程container,调用miniconda,获取miniconda中的所有虚拟python环境。设置双向文件同步。

settings->project->python interpreter->add interpreter ->on ssh

⚠️ 这里并非创建基于docker的interpreter,因为我的之前run的container cuda环境在多个项目中是可以复用的,因此我们在container中用miniconda创建虚拟环境是一种更好的选择。

自动读取远程环境配置...

选择conda environment,设置conda虚拟环境。sync folders填写工作路径/repos/your project name,勾选自动上传到服务器。

查看interpreter配置结果:

查看同步情况:

查看从container->server的挂载是否成功:

Windows文件共享

⚠️ 测试发现,pycharm可以实现本地文件的Automatic upload,但无法实现服务器端文件更新后传回本地。事实上,在深度学习模型训练、测试过程中产生的大量数据文件也不需要传回本地,可以使用Windows的文件共享实现在server端共享挂载的文件夹,在本地预览server上的文件,选择需要的数据文件进行下载,降低本地存储大小

在host和server(均为Windows操作系统)上开启网络共享。

server

server : 在局域网上共享container挂载的E:\repos:/repos.

server上也可以管理共享或查看所有共享:

host

Host: 在host上挂载server共享的repos文件夹:

这样,数据文件存放在远端电脑,而host可以通过文件共享的方式预览文件(并不会下载文件到本地)。

Windows通过SSH连接实现远程显存监控

Server(Windows)

Windows开启SSH-server服务

检查 OpenSSH 的可用性

管理员身份打开powershell并运行:

bash 复制代码
Get-WindowsCapability -Online | Where-Object Name -like  'OpenSSH*'

如果任何 SSH 客户端或服务器功能不可用,请根据 PowerShell (Admin) 中的要求使用以下命令。

安装 OpenSSH 服务器
bash 复制代码
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

再次检查可用性。

修改ssh-server配置文件

默认情况下,OpenSSH 客户端和 OpenSSH 服务器位于以下目录:C:\Windows\System32\OpenSSH. 管理员身份打开记事本,再在记事本里打开配置文件sshd_config_default.

修改如下部分:

  • PermitRootLogin yes
  • PasswordAuthentication yes

保存。搜索service服务:

找到openssh ssh server服务,修改启动方式为"自动",点"启动"。然后apply and ok.

Host(-)

Host通过ssh服务测试连接server(Windows ssh):

bash 复制代码
ssh admin@192.168.1.3

显卡状态监控:

bash 复制代码
nvidia-smi -l 5

测试pytorch能否正常使用显卡

参考官方文档安装pytorch后,尝试运行下述代码:

python 复制代码
import torch

print(torch.cuda.is_available())

输出true,则pytorch cuda版运行正常。


原创声明:©️ 本文为博主原创文章,转载需注明出处------https://blog.csdn.net/IYXUAN

相关推荐
阿尔帕兹1 小时前
构建 HTTP 服务端与 Docker 镜像:从开发到测试
网络协议·http·docker
ZHOU西口2 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
神里大人4 小时前
idea、pycharm等软件的文件名红色怎么变绿色
java·pycharm·intellij-idea
张小生1804 小时前
PyCharm中 argparse 库 的使用方法
python·pycharm
叶知安4 小时前
如何用pycharm连接sagemath?
ide·python·pycharm
景天科技苑5 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge6 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇6 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
川石课堂软件测试8 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
昌sit!14 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes