1. When the kubelet constructs the cri mounts for the container which references an image volume source type, It passes the missing mount attributes to the CRI implementation, including readOnly, propagation, and recursiveReadOnly. When the readOnly field of the containerMount is explicitly set to false, the kubelet will take the readOnlyas true to the CRI implementation because the image volume plugin requires the mount to be read-only.

2. Fix a bug where the pod is unexpectedly running when the `image` volume source type is used and mounted to `/etc/hosts` in the container.
This commit is contained in:
carlory 2024-11-05 16:35:59 +08:00
parent 2529d7d5a6
commit b6c9c2d6fa
2 changed files with 65 additions and 63 deletions

View File

@ -277,18 +277,6 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
mounts := []kubecontainer.Mount{} mounts := []kubecontainer.Mount{}
var cleanupAction func() var cleanupAction func()
for i, mount := range container.VolumeMounts { for i, mount := range container.VolumeMounts {
// Check if the mount is referencing an OCI volume
if imageVolumes != nil && utilfeature.DefaultFeatureGate.Enabled(features.ImageVolume) {
if image, ok := imageVolumes[mount.Name]; ok {
mounts = append(mounts, kubecontainer.Mount{
Name: mount.Name,
ContainerPath: mount.MountPath,
Image: image,
})
continue
}
}
// do not mount /etc/hosts if container is already mounting on the path // do not mount /etc/hosts if container is already mounting on the path
mountEtcHostsFile = mountEtcHostsFile && (mount.MountPath != etcHostsPath) mountEtcHostsFile = mountEtcHostsFile && (mount.MountPath != etcHostsPath)
vol, ok := podVolumes[mount.Name] vol, ok := podVolumes[mount.Name]
@ -306,7 +294,19 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
vol.SELinuxLabeled = true vol.SELinuxLabeled = true
relabelVolume = true relabelVolume = true
} }
hostPath, err := volumeutil.GetPath(vol.Mounter)
var (
hostPath string
image *runtimeapi.ImageSpec
err error
)
if imageVolumes != nil && utilfeature.DefaultFeatureGate.Enabled(features.ImageVolume) {
image = imageVolumes[mount.Name]
}
if image == nil {
hostPath, err = volumeutil.GetPath(vol.Mounter)
if err != nil { if err != nil {
return nil, cleanupAction, err return nil, cleanupAction, err
} }
@ -367,9 +367,10 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
} }
// Docker Volume Mounts fail on Windows if it is not of the form C:/ // Docker Volume Mounts fail on Windows if it is not of the form C:/
if volumeutil.IsWindowsLocalPath(runtime.GOOS, hostPath) { if hostPath != "" && volumeutil.IsWindowsLocalPath(runtime.GOOS, hostPath) {
hostPath = volumeutil.MakeAbsolutePath(runtime.GOOS, hostPath) hostPath = volumeutil.MakeAbsolutePath(runtime.GOOS, hostPath)
} }
}
containerPath := mount.MountPath containerPath := mount.MountPath
// IsAbs returns false for UNC path/SMB shares/named pipes in Windows. So check for those specifically and skip MakeAbsolutePath // IsAbs returns false for UNC path/SMB shares/named pipes in Windows. So check for those specifically and skip MakeAbsolutePath
@ -396,6 +397,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
Name: mount.Name, Name: mount.Name,
ContainerPath: containerPath, ContainerPath: containerPath,
HostPath: hostPath, HostPath: hostPath,
Image: image,
ReadOnly: mount.ReadOnly || mustMountRO, ReadOnly: mount.ReadOnly || mustMountRO,
RecursiveReadOnly: rro, RecursiveReadOnly: rro,
SELinuxRelabel: relabelVolume, SELinuxRelabel: relabelVolume,

View File

@ -67,8 +67,8 @@ func (o *imagePlugin) ConstructVolumeSpec(volumeName, mountPath string) (volume.
func (o *imagePlugin) GetAttributes() volume.Attributes { func (o *imagePlugin) GetAttributes() volume.Attributes {
return volume.Attributes{ return volume.Attributes{
ReadOnly: true, ReadOnly: true,
Managed: true, Managed: false,
SELinuxRelabel: true, SELinuxRelabel: false,
} }
} }