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-testaplay 命令并且全部在我的主机上(不涉及容器)时,会播放所有声音。

【问题讨论】:

【参考方案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_SERVERPULSE_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 连接失败,请检查 iptablesufw 设置。


如何总结这些设置: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 -Lspeaker-test 都通过TCP 工作。在这两种模式下,我都会得到Playback/recording through the PulseAudio sound server。也许pactl load-module 在您的系统上失败了?它应该打印一个模块编号。也许您以某种方式提供了错误的$Containerip?无论如何,如果共享套接字已经满足您的需求,那就可以了。差异可能与使用的容器系统有关;我正在使用 debian 图像进行测试。 另外,iptables 设置可以禁止 TCP 连接。

以上是关于docker 存储导致 /dev/sdb2磁盘溢满的主要内容,如果未能解决你的问题,请参考以下文章

docker中/dev/stdout的理解

docker /dev/mapper/centos-root 空间满了,怎么办

docker /dev/mapper/centos-root 空间满了,怎么办

为啥docker里面的/dev/shm没有bash权限

docker /dev/mapper/centos-root 空间满了,怎么办

多个linux系统共享一个FC存储后,每次重启后/dev/sd*的设备名称都会自动变话,如何固定名称?