...

Source file src/k8s.io/kubernetes/pkg/kubelet/util/node_startup_latency_tracker.go

Documentation: k8s.io/kubernetes/pkg/kubelet/util

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package util
    18  
    19  import (
    20  	"sync"
    21  	"time"
    22  
    23  	"k8s.io/kubernetes/pkg/kubelet/metrics"
    24  	"k8s.io/utils/clock"
    25  )
    26  
    27  type NodeStartupLatencyTracker interface {
    28  	// This function may be called across Kubelet restart.
    29  	RecordAttemptRegisterNode()
    30  	// This function should not be called across Kubelet restart.
    31  	RecordRegisteredNewNode()
    32  	// This function may be called across Kubelet restart.
    33  	RecordNodeReady()
    34  }
    35  
    36  type basicNodeStartupLatencyTracker struct {
    37  	lock sync.Mutex
    38  
    39  	bootTime                     time.Time
    40  	kubeletStartTime             time.Time
    41  	firstRegistrationAttemptTime time.Time
    42  	firstRegisteredNewNodeTime   time.Time
    43  	firstNodeReadyTime           time.Time
    44  
    45  	// For testability
    46  	clock clock.Clock
    47  }
    48  
    49  func NewNodeStartupLatencyTracker() NodeStartupLatencyTracker {
    50  	bootTime, err := GetBootTime()
    51  	if err != nil {
    52  		bootTime = time.Time{}
    53  	}
    54  	return &basicNodeStartupLatencyTracker{
    55  		bootTime:         bootTime,
    56  		kubeletStartTime: time.Now(),
    57  		clock:            clock.RealClock{},
    58  	}
    59  }
    60  
    61  func (n *basicNodeStartupLatencyTracker) RecordAttemptRegisterNode() {
    62  	n.lock.Lock()
    63  	defer n.lock.Unlock()
    64  
    65  	if !n.firstRegistrationAttemptTime.IsZero() {
    66  		return
    67  	}
    68  
    69  	n.firstRegistrationAttemptTime = n.clock.Now()
    70  }
    71  
    72  func (n *basicNodeStartupLatencyTracker) RecordRegisteredNewNode() {
    73  	n.lock.Lock()
    74  	defer n.lock.Unlock()
    75  
    76  	if n.firstRegistrationAttemptTime.IsZero() || !n.firstRegisteredNewNodeTime.IsZero() {
    77  		return
    78  	}
    79  
    80  	n.firstRegisteredNewNodeTime = n.clock.Now()
    81  
    82  	if !n.bootTime.IsZero() {
    83  		metrics.NodeStartupPreKubeletDuration.Set(n.kubeletStartTime.Sub(n.bootTime).Seconds())
    84  	}
    85  	metrics.NodeStartupPreRegistrationDuration.Set(n.firstRegistrationAttemptTime.Sub(n.kubeletStartTime).Seconds())
    86  	metrics.NodeStartupRegistrationDuration.Set(n.firstRegisteredNewNodeTime.Sub(n.firstRegistrationAttemptTime).Seconds())
    87  }
    88  
    89  func (n *basicNodeStartupLatencyTracker) RecordNodeReady() {
    90  	n.lock.Lock()
    91  	defer n.lock.Unlock()
    92  
    93  	if n.firstRegisteredNewNodeTime.IsZero() || !n.firstNodeReadyTime.IsZero() {
    94  		return
    95  	}
    96  
    97  	n.firstNodeReadyTime = n.clock.Now()
    98  
    99  	metrics.NodeStartupPostRegistrationDuration.Set(n.firstNodeReadyTime.Sub(n.firstRegisteredNewNodeTime).Seconds())
   100  	if !n.bootTime.IsZero() {
   101  		metrics.NodeStartupDuration.Set(n.firstNodeReadyTime.Sub(n.bootTime).Seconds())
   102  	}
   103  }
   104  

View as plain text