docker 存储导致 /dev/sdb2磁盘溢满
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker 存储导致 /dev/sdb2磁盘溢满相关的知识,希望对你有一定的参考价值。
参考技术A linux 系统报错: cannot create temp file for here-document: No space left on device,显然是磁盘完全占用,无剩余方法:
首先,查看磁盘的使用情况的,命令:df -h, /dev/sdb2 作为我服务器默认根目录所在,最重要的是默认系统软件安装,安装了许多包,/dev/sdb2磁盘爆满
然后, 查看/dev/sdb2磁盘内不同文件夹具体占用情况,命令:du -sh ./*,其中./var占用最大,同理进入/var目录下进一步查看,./lib占用最大,/var/lib目录是系统默认包安装地址,发现其下的docker占用磁盘317G;
原因:随着docker image 和container的增多,导致磁盘过度占用;
最简单的解决方法:将 dcoker 存储目录转移到其他空余磁盘
首先:暂停docker服务:sudo systermctl stop docekr.service
然后:转移docker 存储,并在/va/lib/目录创建对应软链接:
sudo mv /var/lib/docker /mnt/
cd /var/lib; sudo ln -st /mnt/docker dokcer
/va/lib/目录需要创建链接原因:docker 的默认存储路径(Docker Root Dir)在/var/lib/docker ,原来的创建的images和containers的配置文件需要在/var/lib/docker下查找,故转移/var/lib/docker之后,必须将对应的转移文件地址参数传递给系统,否则无法查找到之前创建的images和containers,不能有效加载到docker环境;
最后:重新启动docker服务
sudo systermctl daemon-reload # 重新加载系统变量,主要是/var/lib/docker-->/mnt/docker链接的加载
sudo systermctl start docker.service # 重启
经验小结:
没有创建链接前,我将docker的配置文件中的存储目录修改为/mnt/docker ,虽然docker运行了,但是docker之间创建的images和containers都未能加载到环境中蹦年使用,添加了软链接之后,就可以全部加载原来的images和containers,之后我将docker系统配置又修改回去了,有了/var/lib/docker指向/mnt/docker的系统链接之后,不再需要修改docker的任何配置文件了;
ubuntu18.04 docker配置文件: /etc/systemd/system/multi-user.target.wants/docker.service
参考博文:
https://blog.csdn.net/zb408832388/article/details/103481443
https://blog.csdn.net/zb408832388/article/details/103481443
https://www.jianshu.com/p/ef4a2268bdf1
Docker:在多个容器上共享 /dev/snd 会导致“设备或资源繁忙”
【中文标题】Docker:在多个容器上共享 /dev/snd 会导致“设备或资源繁忙”【英文标题】:Docker : sharing /dev/snd on multiple containers leads to "device or resource busy" 【发布时间】:2019-01-22 09:15:51 【问题描述】:当adding host device (--device /dev/snd
) 到 Docker 容器时,有时会遇到Device or resource busy
错误。
示例
我已经通过一个涉及音频的最小示例 (alsa
) 重现了该问题。这是我的Dockerfile
(生成图像docker-device-example
):
FROM debian:buster
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
alsa-utils \
&& rm -rf /var/lib/apt/lists/*
我正在运行以下命令(speaker-test
是一个生成可用于测试扬声器的音调的工具),/dev/snd
共享:
docker run --rm \
-i -t \
--device /dev/snd \
docker-device-example \
speaker-test
问题
运行上一条命令时,会播放粉红噪音,但仅在某些情况下:
如果我没有在主机上播放任何声音:例如,如果我正在播放视频,并且即使视频暂停,命令也会失败 如果我没有运行另一个容器来访问/dev/snd
设备
看起来/dev/snd
在使用时被“锁定”了,如果是这样,我得到以下输出(错误由最后两行表示):
speaker-test 1.1.6
Playback device is default
Stream parameters are 48000Hz, S16_LE, 1 channels
Using 16 octaves of pink noise
ALSA lib pcm_dmix.c:1099:(snd_pcm_dmix_open) unable to open slave
Playback open error: -16,Device or resource busy
反之亦然,如果播放粉红噪音(在容器上),那么我无法在我的主机(Ubuntu)上播放任何声音。但是我主机上的命令不会失败并显示相同的消息。相反,主机上的命令(如aplay test.wav
播放简单的声音)被无限期阻止(即使容器随后关闭)。
我尝试通过运行strace aplay test.way
进行调试,并且该命令似乎在poll
系统调用上被阻止:
poll([fd=3, events=POLLIN|POLLERR|POLLNVAL], 1, 4294967295
问题
如何同时播放来自 2 个(或更多)不同容器或来自我的主机和一个容器的声音?
其他信息
我已经用/dev/snd
重现了这个问题,但我不知道在使用其他设备时是否会发生类似的事情,或者它是否只是与声音设备或alsa
有关。
另请注意,当同时运行多个 speaker-test
或 aplay
命令并且全部在我的主机上(不涉及容器)时,会播放所有声音。
【问题讨论】:
【参考方案1】:我不知道如何用 ALSA 解决这个问题,但可以提供 2 种可能的方法来使用 pulseaudio。如果这些设置失败,请在映像中安装 pulseaudio
以确保完成依赖项。
ALSA 直接访问声音硬件并阻止其他客户端访问它。但是可以设置 ALSA 来服务多个客户。这必须由其他人来回答。可能一些ALSA dmix plugin 设置是要走的路。
-
带有共享套接字的 Pulseaudio:
创建脉冲音频套接字:
pactl load-module module-native-protocol-unix socket=/tmp/pulseaudio.socket
为 pulseaudio 客户端创建 /tmp/pulseaudio.client.conf
:
default-server = unix:/tmp/pulseaudio.socket
# Prevent a server running in the container
autospawn = no
daemon-binary = /bin/true
# Prevent the use of shared memory
enable-shm = false
与 docker 共享套接字和配置文件,并设置环境变量 PULSE_SERVER
和 PULSE_COOKIE
。容器用户必须与主机上的相同:
docker run --rm \
--env PULSE_SERVER=unix:/tmp/pulseaudio.socket \
--env PULSE_COOKIE=/tmp/pulseaudio.cookie \
--volume /tmp/pulseaudio.socket:/tmp/pulseaudio.socket \
--volume /tmp/pulseaudio.client.conf:/etc/pulse/client.conf \
--user $(id -u):$(id -g) \
imagename
cookie 将由 pulseaudio 自己创建。
-
基于 TCP 的 Pulseaudio:
从主机获取IP地址:
# either an arbitrary IPv4 address
Hostip="$(ip -4 -o a | awk 'print $4' | cut -d/ -f1 | grep -v 127.0.0.1 | head -n1)"
# or especially IP from docker daemon
Hostip="$(ip -4 -o a| grep docker0 | awk 'print $4' | cut -d/ -f1)"
运行 docker 镜像。你需要一个空闲的 TCP 端口,这里使用了34567
。
(TCP 端口号必须在cat /proc/sys/net/ipv4/ip_local_port_range
范围内,并且不得在使用中。请与ss -nlp | grep 34567
核对。)
docker run --rm \
--name pulsecontainer \
--env PULSE_SERVER=tcp:$Hostip:34567 \
imagename
docker run
后获取容器的 IP:
Containerip="$(docker inspect --format ' .NetworkSettings.IPAddress ' pulsecontainer)"
加载用容器IP认证的pulseaudio TCP模块:
pactl load-module module-native-protocol-tcp port=34567 auth-ip-acl=$Containerip
请注意,TCP 模块是在容器启动并运行后加载的。需要一点时间,pulseaudio 服务器才可用于容器应用程序。
如果 TCP 连接失败,请检查 iptables
和 ufw
设置。
如何总结这些设置:https://github.com/mviereck/x11docker/wiki/Container-sound:-ALSA-or-Pulseaudio
【讨论】:
第一个解决方案完美运行,谢谢!使用pulseaudio
对我来说不是问题。 FI,第二个解决方案不起作用(播放声音的命令挂起并使用Playback open error: -2,No such file or directory
崩溃),但由于我在同一主机上运行容器,第一个解决方案更适合。如果只有 ALSA 对我的问题没有更多答案,我会很快接受这个答案。
@norbjd 我重新检查了 TCP 设置,它在这里工作。也许$Hostip
需要在您的系统上检查,您可能必须使用另一个 IPv4 地址。请注意,pactl load-module
准备就绪并可以从容器访问之前需要很短的时间。
我尝试等待并使用其他 $Hostip
,但我无法使用解决方案 2 从容器播放声音。从容器运行 aplay -L
时,我注意到我刚收到null
;而我在做解决方案1时得到了一个default
(描述:Playback/recording through the PulseAudio sound server
)。也许问题来自这里?我还注意到播放声音时的错误不是立即的,命令在崩溃前挂起〜5s(如果不设置PULSE_SERVER
,命令会立即崩溃)。
@norbjd 感谢您的测试!这里aplay -L
和speaker-test
都通过TCP 工作。在这两种模式下,我都会得到Playback/recording through the PulseAudio sound server
。也许pactl load-module
在您的系统上失败了?它应该打印一个模块编号。也许您以某种方式提供了错误的$Containerip
?无论如何,如果共享套接字已经满足您的需求,那就可以了。差异可能与使用的容器系统有关;我正在使用 debian 图像进行测试。
另外,iptables
设置可以禁止 TCP 连接。以上是关于docker 存储导致 /dev/sdb2磁盘溢满的主要内容,如果未能解决你的问题,请参考以下文章
docker /dev/mapper/centos-root 空间满了,怎么办
docker /dev/mapper/centos-root 空间满了,怎么办