/ dev在Docker中如何工作?

时间:2018-07-22 19:52:02

标签: docker

我的/dev/random遇到了一些问题,在某些服务器上我将其替换为/dev/urandom

lrwxrwxrwx 1 root root 12 Jul 22 21:04 /dev/random -> /dev/urandom

此后,我用Docker替换了一些基础架构。我认为,在主机上替换/dev/random就足够了。但是在启动服务时,我很快注意到一些RNG操作被阻止,因为它使用了/dev/random的原始实现。

我编写了一个小测试程序来证明这种行为:

package main

import (
    "fmt"
    "os"
)

func main() {

    f, err := os.Open("/dev/random")
    if err != nil {
        panic(err)
    }

    chunk := make([]byte, 1024)
    index := 0
    for {
        index = index + 1
        _, err := f.Read(chunk)
        if err != nil {
            panic(err)
        }
        fmt.Println("iteration ", index)
    }
}

在主机(具有符号链接)上执行此程序可以按预期工作-在关闭它之前,它不会阻塞并运行。

在容器中运行该代码时,它将在第一次迭代后(至少在我的计算机上)阻塞。

我显然可以通过将随机文件装入容器来解决此问题:

docker run -it --rm -v /dev/random:/dev/random bla

但这不是这个问题的重点。我想知道以下内容:

  • Docker如何设置/ dev中列出的设备
  • 为什么它不仅仅使用主机的(某些)设备文件。

1 个答案:

答案 0 :(得分:1)

除非您明确指示,否则Docker绝不会使用任何主机系统的文件系统。 /dev中的设备文件是烘烤到图像中的任何东西(如果有的话)。

还要注意,传统的Unix设备模型是设备“文件”是字符专用或块专用设备,以及一对主设备号和次设备号,并且任何实际处理都在内核中完成。相关地,主机的内核在所有Docker容器之间共享。因此,如果您修复主机的/dev/random的无效实现,那么您的容器也将继承此修复程序;但仅更改主机/dev中的内容将没有任何效果。