Skip to content

Commit b6c9c2d

Browse files
committed
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.
1 parent 2529d7d commit b6c9c2d

File tree

2 files changed

+64
-62
lines changed

2 files changed

+64
-62
lines changed

pkg/kubelet/kubelet_pods.go

Lines changed: 62 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,6 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
277277
mounts := []kubecontainer.Mount{}
278278
var cleanupAction func()
279279
for i, mount := range container.VolumeMounts {
280-
// Check if the mount is referencing an OCI volume
281-
if imageVolumes != nil && utilfeature.DefaultFeatureGate.Enabled(features.ImageVolume) {
282-
if image, ok := imageVolumes[mount.Name]; ok {
283-
mounts = append(mounts, kubecontainer.Mount{
284-
Name: mount.Name,
285-
ContainerPath: mount.MountPath,
286-
Image: image,
287-
})
288-
continue
289-
}
290-
}
291-
292280
// do not mount /etc/hosts if container is already mounting on the path
293281
mountEtcHostsFile = mountEtcHostsFile && (mount.MountPath != etcHostsPath)
294282
vol, ok := podVolumes[mount.Name]
@@ -306,69 +294,82 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
306294
vol.SELinuxLabeled = true
307295
relabelVolume = true
308296
}
309-
hostPath, err := volumeutil.GetPath(vol.Mounter)
310-
if err != nil {
311-
return nil, cleanupAction, err
312-
}
313297

314-
subPath := mount.SubPath
315-
if mount.SubPathExpr != "" {
316-
subPath, err = kubecontainer.ExpandContainerVolumeMounts(mount, expandEnvs)
298+
var (
299+
hostPath string
300+
image *runtimeapi.ImageSpec
301+
err error
302+
)
317303

304+
if imageVolumes != nil && utilfeature.DefaultFeatureGate.Enabled(features.ImageVolume) {
305+
image = imageVolumes[mount.Name]
306+
}
307+
308+
if image == nil {
309+
hostPath, err = volumeutil.GetPath(vol.Mounter)
318310
if err != nil {
319311
return nil, cleanupAction, err
320312
}
321-
}
322313

323-
if subPath != "" {
324-
if utilfs.IsAbs(subPath) {
325-
return nil, cleanupAction, fmt.Errorf("error SubPath `%s` must not be an absolute path", subPath)
326-
}
314+
subPath := mount.SubPath
315+
if mount.SubPathExpr != "" {
316+
subPath, err = kubecontainer.ExpandContainerVolumeMounts(mount, expandEnvs)
327317

328-
err = volumevalidation.ValidatePathNoBacksteps(subPath)
329-
if err != nil {
330-
return nil, cleanupAction, fmt.Errorf("unable to provision SubPath `%s`: %v", subPath, err)
318+
if err != nil {
319+
return nil, cleanupAction, err
320+
}
331321
}
332322

333-
volumePath := hostPath
334-
hostPath = filepath.Join(volumePath, subPath)
335-
336-
if subPathExists, err := hu.PathExists(hostPath); err != nil {
337-
klog.ErrorS(nil, "Could not determine if subPath exists, will not attempt to change its permissions", "path", hostPath)
338-
} else if !subPathExists {
339-
// Create the sub path now because if it's auto-created later when referenced, it may have an
340-
// incorrect ownership and mode. For example, the sub path directory must have at least g+rwx
341-
// when the pod specifies an fsGroup, and if the directory is not created here, Docker will
342-
// later auto-create it with the incorrect mode 0750
343-
// Make extra care not to escape the volume!
344-
perm, err := hu.GetMode(volumePath)
323+
if subPath != "" {
324+
if utilfs.IsAbs(subPath) {
325+
return nil, cleanupAction, fmt.Errorf("error SubPath `%s` must not be an absolute path", subPath)
326+
}
327+
328+
err = volumevalidation.ValidatePathNoBacksteps(subPath)
345329
if err != nil {
346-
return nil, cleanupAction, err
330+
return nil, cleanupAction, fmt.Errorf("unable to provision SubPath `%s`: %v", subPath, err)
331+
}
332+
333+
volumePath := hostPath
334+
hostPath = filepath.Join(volumePath, subPath)
335+
336+
if subPathExists, err := hu.PathExists(hostPath); err != nil {
337+
klog.ErrorS(nil, "Could not determine if subPath exists, will not attempt to change its permissions", "path", hostPath)
338+
} else if !subPathExists {
339+
// Create the sub path now because if it's auto-created later when referenced, it may have an
340+
// incorrect ownership and mode. For example, the sub path directory must have at least g+rwx
341+
// when the pod specifies an fsGroup, and if the directory is not created here, Docker will
342+
// later auto-create it with the incorrect mode 0750
343+
// Make extra care not to escape the volume!
344+
perm, err := hu.GetMode(volumePath)
345+
if err != nil {
346+
return nil, cleanupAction, err
347+
}
348+
if err := subpather.SafeMakeDir(subPath, volumePath, perm); err != nil {
349+
// Don't pass detailed error back to the user because it could give information about host filesystem
350+
klog.ErrorS(err, "Failed to create subPath directory for volumeMount of the container", "containerName", container.Name, "volumeMountName", mount.Name)
351+
return nil, cleanupAction, fmt.Errorf("failed to create subPath directory for volumeMount %q of container %q", mount.Name, container.Name)
352+
}
347353
}
348-
if err := subpather.SafeMakeDir(subPath, volumePath, perm); err != nil {
354+
hostPath, cleanupAction, err = subpather.PrepareSafeSubpath(subpath.Subpath{
355+
VolumeMountIndex: i,
356+
Path: hostPath,
357+
VolumeName: vol.InnerVolumeSpecName,
358+
VolumePath: volumePath,
359+
PodDir: podDir,
360+
ContainerName: container.Name,
361+
})
362+
if err != nil {
349363
// Don't pass detailed error back to the user because it could give information about host filesystem
350-
klog.ErrorS(err, "Failed to create subPath directory for volumeMount of the container", "containerName", container.Name, "volumeMountName", mount.Name)
351-
return nil, cleanupAction, fmt.Errorf("failed to create subPath directory for volumeMount %q of container %q", mount.Name, container.Name)
364+
klog.ErrorS(err, "Failed to prepare subPath for volumeMount of the container", "containerName", container.Name, "volumeMountName", mount.Name)
365+
return nil, cleanupAction, fmt.Errorf("failed to prepare subPath for volumeMount %q of container %q", mount.Name, container.Name)
352366
}
353367
}
354-
hostPath, cleanupAction, err = subpather.PrepareSafeSubpath(subpath.Subpath{
355-
VolumeMountIndex: i,
356-
Path: hostPath,
357-
VolumeName: vol.InnerVolumeSpecName,
358-
VolumePath: volumePath,
359-
PodDir: podDir,
360-
ContainerName: container.Name,
361-
})
362-
if err != nil {
363-
// Don't pass detailed error back to the user because it could give information about host filesystem
364-
klog.ErrorS(err, "Failed to prepare subPath for volumeMount of the container", "containerName", container.Name, "volumeMountName", mount.Name)
365-
return nil, cleanupAction, fmt.Errorf("failed to prepare subPath for volumeMount %q of container %q", mount.Name, container.Name)
366-
}
367-
}
368368

369-
// Docker Volume Mounts fail on Windows if it is not of the form C:/
370-
if volumeutil.IsWindowsLocalPath(runtime.GOOS, hostPath) {
371-
hostPath = volumeutil.MakeAbsolutePath(runtime.GOOS, hostPath)
369+
// Docker Volume Mounts fail on Windows if it is not of the form C:/
370+
if hostPath != "" && volumeutil.IsWindowsLocalPath(runtime.GOOS, hostPath) {
371+
hostPath = volumeutil.MakeAbsolutePath(runtime.GOOS, hostPath)
372+
}
372373
}
373374

374375
containerPath := mount.MountPath
@@ -396,6 +397,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
396397
Name: mount.Name,
397398
ContainerPath: containerPath,
398399
HostPath: hostPath,
400+
Image: image,
399401
ReadOnly: mount.ReadOnly || mustMountRO,
400402
RecursiveReadOnly: rro,
401403
SELinuxRelabel: relabelVolume,

pkg/volume/image/image.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ func (o *imagePlugin) ConstructVolumeSpec(volumeName, mountPath string) (volume.
6767
func (o *imagePlugin) GetAttributes() volume.Attributes {
6868
return volume.Attributes{
6969
ReadOnly: true,
70-
Managed: true,
71-
SELinuxRelabel: true,
70+
Managed: false,
71+
SELinuxRelabel: false,
7272
}
7373
}
7474

0 commit comments

Comments
 (0)