Kubeletソース分析のdiskSpaceManager
12527 ワード
kubernetesバージョンv 1.5.0 diskSpaceManagerの構造体kubelet
diskSpaceManagerの宣言および初期化宣言
k 8 sを初期化する.io/kubernetes/pkg/kubelet/kubelet.go NewMainKubelet関数で初期化
このインタフェースの戻り値はdiskSpaceManagerで、実際の戻り値はrealDiskSpaceManager構造体です.したがって、すべてのdiskSpaceManagerのインタフェース実装はrealDiskSpaceManagerに従って表示する必要があります.realDiskSpaceManagerの構造は次のとおりです.
realDiskSpaceManager構造で実装されているdiskSpaceManagerインタフェースを確認します.
上記の2つの方法は最終的にdmを呼び出す.3つのパラメータを使用したisSpaceAvailable()
ファイルシステムタイプ
有効かどうかを判断するディスク予約領域のサイズ
RootFSとImagesFsで使用されるディスクの取得に使用されるcAdvisorのインタフェース
インタフェースはBool値、true or falseを返します.
dmを見続けます.getFsInfo()インタフェース:
diskSpaceManagerの使用
// Kubelet is the main kubelet implementation.
type Kubelet struct {
...
// Diskspace manager.
diskSpaceManager diskSpaceManager
// Cached MachineInfo returned by cadvisor.
machineInfo *cadvisorapi.MachineInfo
// Syncs pods statuses with apiserver; also used as a cache of statuses.
statusManager status.Manager
// VolumeManager runs a set of asynchronous loops that figure out which
// volumes need to be attached/mounted/unmounted/detached based on the pods
// scheduled on this node and makes it so.
volumeManager volumemanager.VolumeManager
// Cloud provider interface.
cloud cloudprovider.Interface
autoDetectCloudProvider bool
// Reference to this node.
nodeRef *api.ObjectReference
// Container runtime.
containerRuntime kubecontainer.Runtime
// reasonCache caches the failure reason of the last creation of all containers, which is
// used for generating ContainerStatus.
reasonCache *ReasonCache
...
experimentalHostUserNamespaceDefaulting bool
}
diskSpaceManagerの宣言および初期化宣言
// Implementation is thread-safe.
type diskSpaceManager interface {
// Checks the available disk space
IsRootDiskSpaceAvailable() (bool, error)
IsRuntimeDiskSpaceAvailable() (bool, error)
}
type DiskSpacePolicy struct {
// free disk space threshold for filesystem holding docker images.
DockerFreeDiskMB int
// free disk space threshold for root filesystem. Host volumes are created on root fs.
RootFreeDiskMB int
}
k 8 sを初期化する.io/kubernetes/pkg/kubelet/kubelet.go NewMainKubelet関数で初期化
diskSpaceManager, err := newDiskSpaceManager(kubeDeps.CAdvisorInterface, diskSpacePolicy)
if err != nil {
return nil, fmt.Errorf("failed to initialize disk manager: %v", err)
}
func newDiskSpaceManager(cadvisorInterface cadvisor.Interface, policy DiskSpacePolicy) (diskSpaceManager, error) {
// validate policy
err := validatePolicy(policy)
if err != nil {
return nil, err
}
dm := &realDiskSpaceManager{
cadvisor: cadvisorInterface,
policy: policy,
cachedInfo: map[string]fsInfo{},
}
return dm, nil
}
LowDiskSpaceThresholdMB 256M
fs.Int32Var(&s.LowDiskSpaceThresholdMB, "low-diskspace-threshold-mb", s.LowDiskSpaceThresholdMB, "The absolute free disk space, in MB, to maintain. When disk space falls below this threshold, new pods would be rejected. Default: 256")
このインタフェースの戻り値はdiskSpaceManagerで、実際の戻り値はrealDiskSpaceManager構造体です.したがって、すべてのdiskSpaceManagerのインタフェース実装はrealDiskSpaceManagerに従って表示する必要があります.realDiskSpaceManagerの構造は次のとおりです.
type realDiskSpaceManager struct {
cadvisor cadvisor.Interface
cachedInfo map[string]fsInfo // cache of filesystem info.
lock sync.Mutex // protecting cachedInfo.
policy DiskSpacePolicy // thresholds. Set at creation time.
}
realDiskSpaceManager構造で実装されているdiskSpaceManagerインタフェースを確認します.
func (dm *realDiskSpaceManager) IsRuntimeDiskSpaceAvailable() (bool, error) {
return dm.isSpaceAvailable("runtime", dm.policy.DockerFreeDiskMB, dm.cadvisor.ImagesFsInfo)
}
func (dm *realDiskSpaceManager) IsRootDiskSpaceAvailable() (bool, error) {
return dm.isSpaceAvailable("root", dm.policy.RootFreeDiskMB, dm.cadvisor.RootFsInfo)
}
上記の2つの方法は最終的にdmを呼び出す.3つのパラメータを使用したisSpaceAvailable()
ファイルシステムタイプ
有効かどうかを判断するディスク予約領域のサイズ
RootFSとImagesFsで使用されるディスクの取得に使用されるcAdvisorのインタフェース
インタフェースはBool値、true or falseを返します.
func (dm *realDiskSpaceManager) isSpaceAvailable(fsType string, threshold int, f func() (cadvisorapi.FsInfo, error)) (bool, error) {
fsInfo, err := dm.getFsInfo(fsType, f)
if err != nil {
return true, fmt.Errorf("failed to get fs info for %q: %v", fsType, err)
}
if fsInfo.Capacity == 0 {
return true, fmt.Errorf("could not determine capacity for %q fs. Info: %+v", fsType, fsInfo)
}
if fsInfo.Available < 0 {
return true, fmt.Errorf("wrong available space for %q: %+v", fsType, fsInfo)
}
if fsInfo.Available < int64(threshold)*mb {
glog.Infof("Running out of space on disk for %q: available %d MB, threshold %d MB", fsType, fsInfo.Available/mb, threshold)
return false, nil
}
return true, nil
}
dmを見続けます.getFsInfo()インタフェース:
func (dm *realDiskSpaceManager) getFsInfo(fsType string, f func() (cadvisorapi.FsInfo, error)) (fsInfo, error) {
dm.lock.Lock()
defer dm.lock.Unlock()
fsi := fsInfo{}
if info, ok := dm.cachedInfo[fsType]; ok {
timeLimit := time.Now().Add(-2 * time.Second)
if info.Timestamp.After(timeLimit) {
fsi = info
}
}
if fsi.Timestamp.IsZero() {
fs, err := f()
if err != nil {
return fsInfo{}, err
}
fsi.Timestamp = time.Now()
fsi.Usage = int64(fs.Usage)
fsi.Capacity = int64(fs.Capacity)
fsi.Available = int64(fs.Available)
dm.cachedInfo[fsType] = fsi
}
return fsi, nil
}
diskSpaceManagerの使用
// handleOutOfDisk detects if pods can't fit due to lack of disk space.
func (kl *Kubelet) isOutOfDisk() bool {
// Check disk space once globally and reject or accept all new pods.
withinBounds, err := kl.diskSpaceManager.IsRuntimeDiskSpaceAvailable()
// Assume enough space in case of errors.
if err != nil {
glog.Errorf("Failed to check if disk space is available for the runtime: %v", err)
} else if !withinBounds {
return true
}
withinBounds, err = kl.diskSpaceManager.IsRootDiskSpaceAvailable()
// Assume enough space in case of errors.
if err != nil {
glog.Errorf("Failed to check if disk space is available on the root partition: %v", err)
} else if !withinBounds {
return true
}
return false
}