本文档为使用调试室两台服务器的docker的指导文档。不包含docker的深层原理
Chapter 1 Basic Knowledge on docker
https://zhuanlan.zhihu.com/p/442442997
对于深度学习使用者,仅需知道这个东西可以隔离不同的系统,在不涉及到内核的操作的前提下,使两个系统直接各自拥有自己的深度学习环境
Chapter 2 Install
两台服务器都已经安装好了docker,如果自己的虚拟机或者双系统还有需求,参考:
https://zhuanlan.zhihu.com/p/651148141
Chapter 3 dockerhub
dockerhub
添加链接描述是一个存储不同docker系统的网络空间,是系统级别的github,往往在这里都能找到想要的系统
Chapter 4 OS
在深度学习中,一般最常见的使用方式就是使用独立的Ubuntu系统,docker提供了dockerhub和多种独立的系统,为用户提供了更多的选择,安装系统参考:
https://cloud.tencent.com/developer/article/2309562
在这部分前:请仔细阅读一下其他帖子,确认好操作是对容器还是镜像,是在容器内还是在宿主机内
1.安装镜像
dockerhub中提供了很多不同的深度学习环境可供选择,主要是选择想要并且和显卡驱动不冲突的cuda版本进行安装,举例:实验室安装的版本最高兼容cuda12.1(通过nvidia-smi命令查看)
dockerhub搜索 cuda12.1
点击找到pull命令(将镜像下载到本地):
安装cuda-toolkit
安装这个之后,可以在docker内部使用显卡
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
使用installing with apt即可
使用镜像实例化容器:
镜像实例化容器类似通过类实例化出一个实例
推荐使用的命令:
sudo docker run -v /data:/data -itd --gpus all --shm-size=2g 镜像名称 bash
-v:将一个主机的文件夹映射到docker内,注意,docker内的文件更改会影响主机
-it:-i:交互式操作
-t:终端
–gpus:使用gpu
–shm-size=2g:将运行内存设置为2G(防止dataloader爆内存)
/bin/bash 或者bash:使用脚本
不推荐使用-d,还需要再次打开
安装conda
和ubuntu中安装完全一样
安装需要的环境
和ubuntu中安装完全一样
训练
Chapter 5 Basic Use:
docker images:查看全部镜像
docker pull:拉别人的镜像
docker commit:将自己改过的内容保存为新的镜像
docker ps:查看正在运行的docker
docker ps -a:查看所有的docker容器
docker start:开启一个容器
docker attach:进入这个开启的容器
docker stop:关闭一个容器
exit:退出并关闭
Ctrl+P+Q:推出不关闭
Chapter 6 一些配合docker的小工具
1.tmux:由于不方便在docker内开多个终端,tmux变得非常实用
按D的时候松开ctrl+b!!!
在tmux
中,撤销分割窗口(即关闭当前窗格)以及在窗口间切换都可以通过快捷键完成。以下是默认的tmux
快捷键操作,假设你没有更改过默认的前缀键(Ctrl+b
)。
撤销分割窗口(关闭当前窗格)
- 关闭当前窗格:
Ctrl+b
然后按x
,随后会询问你是否确定关闭该窗格,通常需要按y
确认。
如果你只有两个窗格,关闭任意一个都会撤销分割窗口的效果。如果有多个窗格,关闭当前窗格会将窗格的空间重新分配给剩余的窗格。
切换窗口
- 切换到下一个窗口:
Ctrl+b
然后按n
(表示“next”的意思)。 - 切换到上一个窗口:
Ctrl+b
然后按p
(表示“previous”的意思)。
切换窗格
如果你想在同一个tmux
窗口内的不同窗格间切换,可以使用:
- 切换到下一个窗格:
Ctrl+b
然后按o
。 - 切换到指定方向的窗格:
Ctrl+b
然后使用方向键(上下左右)。
创建和关闭窗口
创建和关闭整个窗口的快捷键也许对你有帮助:
- 创建新窗口:
Ctrl+b
然后按c
。 - 关闭当前窗口:关闭窗口中的所有窗格,或者直接在窗口中执行退出命令(如
exit
或按Ctrl+d
),最后一个窗格关闭时,窗口也会被关闭。
记住,tmux
允许你自定义快捷键和命令,所以这些默认键可能在你的配置中已经被更改。如果你发现默认快捷键不起作用,查看你的~/.tmux.conf
配置文件或者使用tmux list-keys
命令来查找当前绑定的快捷键。
2.socat:由于docker和宿主机不是共享端口,需要进行投射:
使用 socat
实现端口转发是一种灵活的方法,可以帮助你在不重启 Docker 容器的情况下,实现宿主机与容器之间的端口映射。以下是如何使用 socat
进行端口转发的详细步骤:
1. 安装 socat
首先,确保你的宿主机已经安装了 socat
。如果还没有安装,可以根据你的操作系统使用相应的包管理器进行安装。
-
对于基于 Debian/Ubuntu 的系统:
sudo apt-get update sudo apt-get install socat
-
对于 CentOS/RHEL:
sudo yum install socat
-
对于 macOS,使用 Homebrew:
brew install socat
2. 确定容器的 IP 地址
为了使用 socat
将数据从宿主机端口转发到容器端口,你需要知道容器的 IP 地址。你可以通过以下命令获取容器的 IP 地址:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
将 container_name_or_id
替换为你的容器名称或 ID。
3. 使用 socat
进行端口转发
现在,使用 socat
监听宿主机的一个端口,并将所有到这个端口的连接转发到容器的指定端口。以下是一个命令示例:
socat TCP-LISTEN:host_port,fork TCP:container_ip:container_port
TCP-LISTEN:host_port,fork
:这部分告诉socat
在宿主机上监听指定的host_port
,并为每个连接创建一个新的进程(fork
)。TCP:container_ip:container_port
:这部分配置了目标地址和端口,即容器的 IP 地址和端口。
例如,如果容器的 IP 地址是 172.17.0.2
,你希望将宿主机的 8080
端口转发到容器的 80
端口,命令如下:
socat TCP-LISTEN:8080,fork TCP:172.17.0.2:80
4. 访问端口
现在,当你在浏览器或其他客户端访问宿主机的 8080
端口时,socat
会将请求转发到容器的 80
端口。这使得你能够访问那些没有在创建时设置端口映射的容器提供的服务。
注意事项
socat
方法是一种临时的解决方案,适用于快速测试或开发环境。对于生产环境,推荐使用 Docker 的端口映射或其他更稳定的网络解决方案。- 保持
socat
进程运行状态,以维持端口转发。你可能需要在后台运行socat
命令或使用类似nohup
的工具。 - 确保宿主机的防火墙设置允许访问你选择的端口。
补充部分:
1.docker内部的内存共享机制:
运行df-h:
Filesystem Size Used Avail Use% Mounted on
overlay 1.9T 1.3T 526G 71% /
tmpfs 64M 0 64M 0% /dev
tmpfs 32G 0 32G 0% /sys/fs/cgroup
shm 64M 19M 46M 29% /dev/shm
/dev/nvme0n1p2 1.9T 1.3T 526G 71% /chz
tmpfs 32G 12K 32G 1% /proc/driver/nvidia
tmpfs 32G 0 32G 0% /proc/asound
tmpfs 32G 0 32G 0% /proc/acpi
tmpfs 32G 0 32G 0% /proc/scsi
tmpfs 32G 0 32G 0% /sys/firmware
tmpfs 32G 0 32G 0% /sys/devices/virtual/powercap
可见shm只有默认的64g,不足以运行dataloader等占用运行内存很多的程序,因此需要通过–shm-size=2g增加
内存空间
下面是你提供的文件系统输出中各个文件夹的含义,以及它们在Docker容器和宿主机中的作用:
-
overlay: 这是Docker使用的一种存储驱动,它允许文件系统层的叠加。在这个上下文中,
overlay
文件系统使得容器可以在不修改宿主机上原有镜像的基础上,进行读写操作。 -
tmpfs: 这是一种临时文件存储方案,直接在内存中创建文件系统。由于它使用RAM(或在必要时使用交换空间),因此访问速度非常快。Docker在多个地方使用
tmpfs
挂载,以提高性能和安全性,因为tmpfs
存储的数据在系统重启后不会保留。-
/dev: 这个
tmpfs
挂载点包含设备文件。在Docker容器中,这通常是空的或仅包含少数必要的设备文件,以隔离容器和提高安全性。 -
/sys/fs/cgroup: 这是cgroup文件系统的挂载点,用于Linux内核的资源限制、审计和隔离。Docker利用cgroup管理和限制容器的资源使用。
-
-
shm: 如前所述,这是和宿主机共享的内存空间,用于POSIX共享内存。它允许容器内进程快速共享数据。
-
/dev/nvme0n1p2: 这是宿主机上的一个物理存储设备分区。在这个上下文中,它可能被挂载到容器内部的某个点,以便容器可以访问存储在这个分区上的数据。
-
/chz: 这可能是一个自定义挂载点,用于将宿主机上的一个目录或设备挂载到容器中。这使得容器可以访问和使用宿主机上的特定数据或文件系统。
-
/proc/driver/nvidia, /proc/asound, /proc/acpi, /proc/scsi, /sys/firmware, /sys/devices/virtual/powercap: 这些挂载点都是Docker容器中的虚拟文件系统,主要用于提供内核和设备信息。它们使容器能够以有限的方式访问和利用宿主机的硬件和系统信息。特别是,NVIDIA相关的挂载点使得容器能够访问宿主机的GPU资源,这对于运行需要大量计算资源的应用(如深度学习模型)非常有用。
每个挂载点都有其特定的用途,旨在通过隔离、性能优化或资源共享来支持容器化应用的运行。
tmpfs
和shm
(共享内存)在Linux系统中都是基于内存的文件系统,它们提供了将数据存储在RAM中的能力,以达到快速访问数据的目的。尽管它们在使用上有很多相似之处,但还是存在一些关键的区别:
tmpfs
- 通用性:
tmpfs
是一种临时文件系统,可以用于任何需要临时存储空间的场合,如临时文件、缓存或会话数据等。它的内容存储在虚拟内存中,包括物理RAM和交换空间。 - 灵活性:你可以挂载
tmpfs
到系统的任意位置,并且可以指定其大小限制。如果tmpfs
未满,它只会占用实际存储的数据所需的内存大小。 - 配置:
tmpfs
的挂载和大小限制可以通过/etc/fstab
文件或在运行时使用mount
命令进行配置和调整。 - 用途:由于
tmpfs
的灵活性和通用性,它被广泛用于操作系统的/tmp
和/var/run
等目录,以及Docker容器中的各种临时存储需求。
shm(共享内存)
- 特定用途:共享内存(
shm
)主要用于进程间通信(IPC),允许多个进程访问和共享同一块内存区域。这是一种非常高效的数据交换方法,因为它避免了数据的复制操作。 - 实现方式:在Linux系统中,
/dev/shm
是tmpfs
的一个实例,专门用于共享内存。这意味着/dev/shm
本质上是tmpfs
,但其主要目的是为了支持共享内存的使用。 - 大小限制:
/dev/shm
的大小默认可能是有限的,通常依赖于系统配置或Docker容器的配置。对于需要大量共享内存的应用,可能需要手动调整其大小。 - 用途:
shm
主要用于需要快速、高效进程间通信的应用程序,如某些数据库、消息传递系统和高性能计算应用。
总结
虽然tmpfs
和/dev/shm
在技术实现上非常相似(事实上,/dev/shm
是tmpfs
的一个特例),它们的主要区别在于用途和意图。tmpfs
用于广泛的临时存储需求,而/dev/shm
主要用于进程间的内存共享。这两种机制都利用了内存的高速特性,但根据应用的特定需求和上下文来选择使用哪一种。