kubernetes/pkg/kubelet/kubelet_pods_windows_test.go
Akihiro Suda c7f52b34f3
kubelet: KEP-3857: Recursive Read-only (RRO) mounts
See <https://kep.k8s.io/3857>.

An example manifest:
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: rro
spec:
  volumes:
    - name: mnt
      hostPath:
        # tmpfs is mounted on /mnt/tmpfs
        path: /mnt
  containers:
    - name: busybox
      image: busybox
      args: ["sleep", "infinity"]
      volumeMounts:
        # /mnt-rro/tmpfs is not writable
        - name: mnt
          mountPath: /mnt-rro
          readOnly: true
          mountPropagation: None
          recursiveReadOnly: IfPossible
        # /mnt-ro/tmpfs is writable
        - name: mnt
          mountPath: /mnt-ro
          readOnly: true
        # /mnt-rw/tmpfs is writable
        - name: mnt
          mountPath: /mnt-rw
```

Requirements:
- Feature gate "RecursiveReadOnlyMounts" to be enabled
- Linux kernel >= 5.12
- runc >= 1.1

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2024-03-10 03:00:59 +09:00

156 lines
4.0 KiB
Go

/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kubelet
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/subpath"
)
func TestMakeMountsWindows(t *testing.T) {
container := v1.Container{
VolumeMounts: []v1.VolumeMount{
{
MountPath: "c:/etc/hosts",
Name: "disk",
ReadOnly: false,
},
{
MountPath: "c:/mnt/path3",
Name: "disk",
ReadOnly: true,
},
{
MountPath: "c:/mnt/path4",
Name: "disk4",
ReadOnly: false,
},
{
MountPath: "c:/mnt/path5",
Name: "disk5",
ReadOnly: false,
},
{
MountPath: `\mnt\path6`,
Name: "disk6",
ReadOnly: false,
},
{
MountPath: `/mnt/path7`,
Name: "disk7",
ReadOnly: false,
},
{
MountPath: `\\.\pipe\pipe1`,
Name: "pipe1",
ReadOnly: false,
},
},
}
podVolumes := kubecontainer.VolumeMap{
"disk": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/mnt/disk"}},
"disk4": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/mnt/host"}},
"disk5": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "c:/var/lib/kubelet/podID/volumes/empty/disk5"}},
"disk6": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `/mnt/disk6`}},
"disk7": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `\mnt\disk7`}},
"pipe1": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: `\\.\pipe\pipe1`}},
}
pod := v1.Pod{
Spec: v1.PodSpec{
HostNetwork: true,
},
}
fhu := hostutil.NewFakeHostUtil(nil)
fsp := &subpath.FakeSubpath{}
podDir, err := os.MkdirTemp("", "test-rotate-logs")
require.NoError(t, err)
defer os.RemoveAll(podDir)
mounts, _, err := makeMounts(&pod, podDir, &container, "fakepodname", "", []string{""}, podVolumes, fhu, fsp, nil, false)
require.NoError(t, err)
expectedMounts := []kubecontainer.Mount{
{
Name: "disk",
ContainerPath: "c:/etc/hosts",
HostPath: "c:/mnt/disk",
ReadOnly: false,
SELinuxRelabel: false,
},
{
Name: "disk",
ContainerPath: "c:/mnt/path3",
HostPath: "c:/mnt/disk",
ReadOnly: true,
SELinuxRelabel: false,
},
{
Name: "disk4",
ContainerPath: "c:/mnt/path4",
HostPath: "c:/mnt/host",
ReadOnly: false,
SELinuxRelabel: false,
},
{
Name: "disk5",
ContainerPath: "c:/mnt/path5",
HostPath: "c:/var/lib/kubelet/podID/volumes/empty/disk5",
ReadOnly: false,
SELinuxRelabel: false,
},
{
Name: "disk6",
ContainerPath: `c:\mnt\path6`,
HostPath: `c:/mnt/disk6`,
ReadOnly: false,
SELinuxRelabel: false,
},
{
Name: "disk7",
ContainerPath: `c:/mnt/path7`,
HostPath: `c:\mnt\disk7`,
ReadOnly: false,
SELinuxRelabel: false,
},
{
Name: "pipe1",
ContainerPath: `\\.\pipe\pipe1`,
HostPath: `\\.\pipe\pipe1`,
ReadOnly: false,
SELinuxRelabel: false,
},
{
Name: "k8s-managed-etc-hosts",
ContainerPath: `C:\Windows\System32\drivers\etc\hosts`,
HostPath: filepath.Join(podDir, "etc-hosts"),
ReadOnly: false,
SELinuxRelabel: true,
},
}
assert.Equal(t, expectedMounts, mounts, "mounts of container %+v", container)
}