Use tmpfs noswap if supported

use the tmpfs noswap option in order
to mount memory-backed volumes if it's supported.

Signed-off-by: Itamar Holder <iholder@redhat.com>
This commit is contained in:
Itamar Holder 2024-05-08 16:07:31 +03:00
parent 8c1983ffc0
commit fb6c78c90b
2 changed files with 88 additions and 5 deletions

View File

@ -0,0 +1,73 @@
/*
Copyright 2024 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 swap
import (
"os"
sysruntime "runtime"
"sync"
"k8s.io/klog/v2"
"k8s.io/mount-utils"
)
var (
tmpfsNoswapOptionSupported bool
tmpfsNoswapOptionAvailabilityOnce sync.Once
)
const TmpfsNoswapOption = "noswap"
func IsTmpfsNoswapOptionSupported(mounter mount.Interface) bool {
isTmpfsNoswapOptionSupportedHelper := func() bool {
if sysruntime.GOOS == "windows" {
return false
}
mountDir, err := os.MkdirTemp("", "tmpfs-noswap-test-")
if err != nil {
klog.InfoS("error creating dir to test if tmpfs noswap is enabled. Assuming not supported", "mount path", mountDir, "error", err)
return false
}
defer func() {
err = os.RemoveAll(mountDir)
if err != nil {
klog.ErrorS(err, "error removing test tmpfs dir", "mount path", mountDir)
}
}()
err = mounter.MountSensitiveWithoutSystemd("tmpfs", mountDir, "tmpfs", []string{TmpfsNoswapOption}, nil)
if err != nil {
klog.InfoS("error mounting tmpfs with the noswap option. Assuming not supported", "error", err)
return false
}
err = mounter.Unmount(mountDir)
if err != nil {
klog.ErrorS(err, "error unmounting test tmpfs dir", "mount path", mountDir)
}
return true
}
tmpfsNoswapOptionAvailabilityOnce.Do(func() {
tmpfsNoswapOptionSupported = isTmpfsNoswapOptionSupportedHelper()
})
return tmpfsNoswapOptionSupported
}

View File

@ -18,6 +18,7 @@ package emptydir
import (
"fmt"
"k8s.io/kubernetes/pkg/kubelet/util/swap"
"os"
"path/filepath"
@ -327,11 +328,7 @@ func (ed *emptyDir) setupTmpfs(dir string) error {
return nil
}
var options []string
// Linux system default is 50% of capacity.
if ed.sizeLimit != nil && ed.sizeLimit.Value() > 0 {
options = []string{fmt.Sprintf("size=%d", ed.sizeLimit.Value())}
}
options := ed.generateTmpfsMountOptions(swap.IsTmpfsNoswapOptionSupported(ed.mounter))
klog.V(3).Infof("pod %v: mounting tmpfs for volume %v", ed.pod.UID, ed.volName)
return ed.mounter.MountSensitiveWithoutSystemd("tmpfs", dir, "tmpfs", options, nil)
@ -555,3 +552,16 @@ func getVolumeSource(spec *volume.Spec) (*v1.EmptyDirVolumeSource, bool) {
return volumeSource, readOnly
}
func (ed *emptyDir) generateTmpfsMountOptions(noswapSupported bool) (options []string) {
// Linux system default is 50% of capacity.
if ed.sizeLimit != nil && ed.sizeLimit.Value() > 0 {
options = append(options, fmt.Sprintf("size=%d", ed.sizeLimit.Value()))
}
if noswapSupported {
options = append(options, swap.TmpfsNoswapOption)
}
return options
}