版本信息如下:
a、操作系统: centos 7.6,amd64
b、服务器docker版本:v18.09.2
容器中的/etc/resolv.conf文件,是由宿主机/var/lib/docker/containers/xxxx/resolv.conf文件挂载。在docker restart容器之前,手动修改了/var/lib/docker/containers/xxxx/resolv.conf文件,却发现变更的内容并没有出现在容器中的/etc/resolv.conf文件中。原因是/var/lib/docker/containers/xxxx/resolv.conf文件的内容会被覆盖,而后挂载进容器中。
initializeNetworking( )是本文章的重点,/var/lib/docker/containers/xxxx/resolv.conf文件的内容就是在此处被覆盖。
func (daemon *Daemon) containerStart(container *container.Container, checkpoint string, checkpointDir string, resetRestartManager bool) (err error) {
/*
其他代码
*/
// 初始化网络
if err := daemon.initializeNetworking(container); err != nil {
return err
}
/*
其他代码
*/
// 创建容器
err = daemon.containerd.Create(context.Background(), container.ID, spec, createOptions)
// 启动容器
pid, err := daemon.containerd.Start(context.Background(), container.ID, checkpointDir,
container.StreamConfig.Stdin() != nil || container.Config.Tty,
container.InitializeStdio)
return nil
func (daemon *Daemon) initializeNetworking(container *container.Container) error {
/*
其他代码
*/
if err := daemon.allocateNetwork(container); err != nil {
return err
}
return container.BuildHostnameFile()
}
func (daemon *Daemon) allocateNetwork(container *container.Container) error {
/*
其他代码
*/
defaultNetName := runconfig.DefaultDaemonNetworkMode().NetworkName()
if nConf, ok := container.NetworkSettings.Networks[defaultNetName]; ok {
if err := daemon.connectToNetwork(container, defaultNetName, nConf.EndpointSettings, updateSettings); err != nil {
return err
}
}
/*
其他代码
*/
return nil
}
func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error) {
/*
其他代码
*/
if sb == nil {
// 创建sanbox
sb, err = controller.NewSandbox(container.ID, options...)
/*
其他代码
*/
}
/*
其他代码
*/
return nil
}
func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (Sandbox, error) {
/*
其他代码
*/
var sb *sandbox
sb = &sandbox{
id: sandboxID,
containerID: containerID,
endpoints: []*endpoint{},
epPriority: map[string]int{},
populatedEndpoints: map[string]struct{}{},
config: containerConfig{},
controller: c,
extDNS: []extDNSEntry{},
}
// setupResolutionFiles( )会初始化DNS相关的设置
if err = sb.setupResolutionFiles(); err != nil {
return nil, err
}
/*
其他代码
*/
return sb, nil
}
func (sb *sandbox) setupResolutionFiles() error {
/*
其他代码
*/
return sb.setupDNS()
}
func (sb *sandbox) setupDNS() error {
/*
其他代码
*/
// newRC.Content是宿主机/etc/resolv.conf文件的内容(可能过滤部分内容)
// 将newRC.Content写到/var/lib/docker/containers/xxxx/resolv.conf文件
if err := ioutil.WriteFile(sb.config.resolvConfPath, newRC.Content, filePerm); err != nil {
}
/*
其他代码
*/
return nil
}
修改/var/lib/docker/containers/xxxx/resolv.conf文件的内容后重启容器,并不能起到变更容器/etc/resolv.conf文件的目的,因为将其挂载进容器之前,内容会被覆盖。