cri: Make sure host sandbox files exist before adding them to mounts

As `setupSandboxFiles` was done in sandbox controller, it is difficult
here to know if the sandbox controller has done and where the host path
in. Make sure the host path exists before adding them to linux container
mounts, otherwise, the container would generate some unnecessary mounts.

Signed-off-by: Zhang Tianyang <burning9699@gmail.com>
This commit is contained in:
Zhang Tianyang 2024-01-13 17:44:52 +08:00
parent b87d78f456
commit 5611db5309
2 changed files with 59 additions and 56 deletions

View File

@ -1008,34 +1008,47 @@ func (c *criService) linuxContainerMounts(sandboxID string, config *runtime.Cont
}
if !isInCRIMounts(etcHosts, config.GetMounts()) {
hostpath := c.getSandboxHosts(sandboxID)
// /etc/hosts could be delegated to remote sandbox controller. That file isn't required to be existed
// in host side for some sandbox runtimes. Skip it if we don't need it.
if _, err := c.os.Stat(hostpath); err == nil {
mounts = append(mounts, &runtime.Mount{
ContainerPath: etcHosts,
HostPath: c.getSandboxHosts(sandboxID),
HostPath: hostpath,
Readonly: securityContext.GetReadonlyRootfs(),
SelinuxRelabel: true,
UidMappings: uidMappings,
GidMappings: gidMappings,
})
}
}
// Mount sandbox resolv.config.
// TODO: Need to figure out whether we should always mount it as read-only
if !isInCRIMounts(resolvConfPath, config.GetMounts()) {
hostpath := c.getResolvPath(sandboxID)
// The ownership of /etc/resolv.conf could be delegated to remote sandbox controller. That file isn't
// required to be existed in host side for some sandbox runtimes. Skip it if we don't need it.
if _, err := c.os.Stat(hostpath); err == nil {
mounts = append(mounts, &runtime.Mount{
ContainerPath: resolvConfPath,
HostPath: c.getResolvPath(sandboxID),
HostPath: hostpath,
Readonly: securityContext.GetReadonlyRootfs(),
SelinuxRelabel: true,
UidMappings: uidMappings,
GidMappings: gidMappings,
})
}
}
if !isInCRIMounts(devShm, config.GetMounts()) {
sandboxDevShm := c.getSandboxDevShm(sandboxID)
if securityContext.GetNamespaceOptions().GetIpc() == runtime.NamespaceMode_NODE {
sandboxDevShm = devShm
}
// The ownership of /dev/shm could be delegated to remote sandbox controller. That file isn't required
// to be existed in host side for some sandbox runtimes. Skip it if we don't need it.
if _, err := c.os.Stat(sandboxDevShm); err == nil {
mounts = append(mounts, &runtime.Mount{
ContainerPath: devShm,
HostPath: sandboxDevShm,
@ -1054,6 +1067,7 @@ func (c *criService) linuxContainerMounts(sandboxID string, config *runtime.Cont
// mappings and it should work fine.
})
}
}
return mounts
}

View File

@ -733,32 +733,21 @@ func TestLinuxContainerMounts(t *testing.T) {
expectedMounts: nil,
},
{
desc: "should skip hostname mount if the old sandbox doesn't have hostname file",
desc: "should skip sandbox mounts if the old sandbox doesn't have sandbox file",
statFn: func(path string) (os.FileInfo, error) {
assert.Equal(t, filepath.Join(testRootDir, sandboxesDir, testSandboxID, "hostname"), path)
sandboxRootDir := filepath.Join(testRootDir, sandboxesDir, testSandboxID)
sandboxStateDir := filepath.Join(testStateDir, sandboxesDir, testSandboxID)
switch path {
case filepath.Join(sandboxRootDir, "hostname"), filepath.Join(sandboxRootDir, "hosts"),
filepath.Join(sandboxRootDir, "resolv.conf"), filepath.Join(sandboxStateDir, "shm"):
return nil, errors.New("random error")
default:
t.Fatalf("expected sandbox files, got: %s", path)
}
return nil, nil
},
securityContext: &runtime.LinuxContainerSecurityContext{},
expectedMounts: []*runtime.Mount{
{
ContainerPath: "/etc/hosts",
HostPath: filepath.Join(testRootDir, sandboxesDir, testSandboxID, "hosts"),
Readonly: false,
SelinuxRelabel: true,
},
{
ContainerPath: resolvConfPath,
HostPath: filepath.Join(testRootDir, sandboxesDir, testSandboxID, "resolv.conf"),
Readonly: false,
SelinuxRelabel: true,
},
{
ContainerPath: "/dev/shm",
HostPath: filepath.Join(testStateDir, sandboxesDir, testSandboxID, "shm"),
Readonly: false,
SelinuxRelabel: true,
},
},
expectedMounts: nil,
},
} {
test := test