docker在当一个volume的mountpoint在image里原本有数据的情况下,会把image的数据populate到volume中.这个行为在volume被mount到 多个mountpoint的时候,在不同的docker版本行为有差别.
- docker 1.10.3,如果volume mount到多个mountpoint,就不会去populate image中原有的数据到volume中
[lear@~]$docker volume create --name foobar
foobar
[lear@~]$docker run --rm -t -v foobar:/vol/data1 -v foobar:/vol/data2 bergwolf/test ls /vol/data1 /vol/data2
/vol/data1:
/vol/data2:
如果volume只mount到一个目录,还是会populate
[lear@~]$docker run --rm -t -v foobar:/vol/data1 bergwolf/test ls /vol/data1
group hosts mtab resolv.conf
hostname localtime passwd shadow
对应的docker代码实现是:
63 func (daemon *Daemon) populateVolumes(c *container.Container) error {
64 for _, mnt := range c.MountPoints {
65 // skip binds and volumes referenced by other containers (ie, volumes-from)
66 if mnt.Driver == "" || mnt.Volume == nil || len(daemon.volumes.Refs(mnt.Volume)) > 1 {
67 continue
68 }
69
70 logrus.Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, mnt.Name)
71 if err := c.CopyImagePathContent(mnt.Volume, mnt.Destination); err != nil {
72 return err
73 }
74 }
75 return nil
76 }
- docker 1.11.0, 当一个volume mount到多个mountpoint的时候,先mount那个会populate,后面的mountpoint不会
[hyperpublic@runv]$docker run --rm -t -v foobar:/vol/data1 -v foobar:/vol/data2 voltest ls /vol/data1 /vol/data2
/vol/data1:
group hosts mtab resolv.conf
hostname localtime passwd shadow
/vol/data2:
group hosts mtab resolv.conf
hostname localtime passwd shadow
[hyperpublic@runv]$docker run --rm -t -v foobar2:/vol/data2 -v foobar2:/vol/data1 voltest ls /vol/data1 /vol/data2
/vol/data1:
data2_file
/vol/data2:
data2_file
为了简化问题,减少对用户的困扰,hyper的volume会follow docker 1.10.3的行为
- 当volume mount到一个目录的时候,populate image中的数据到volume中
- 当volume mount到多个目录的时候,不做populate