k8s.io/kubernetes@v1.29.3/pkg/kubelet/runtime.go (about)

     1  /*
     2  Copyright 2015 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 kubelet
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"sync"
    23  	"time"
    24  
    25  	utilerrors "k8s.io/apimachinery/pkg/util/errors"
    26  )
    27  
    28  type runtimeState struct {
    29  	sync.RWMutex
    30  	lastBaseRuntimeSync      time.Time
    31  	baseRuntimeSyncThreshold time.Duration
    32  	networkError             error
    33  	runtimeError             error
    34  	storageError             error
    35  	cidr                     string
    36  	healthChecks             []*healthCheck
    37  }
    38  
    39  // A health check function should be efficient and not rely on external
    40  // components (e.g., container runtime).
    41  type healthCheckFnType func() (bool, error)
    42  
    43  type healthCheck struct {
    44  	name string
    45  	fn   healthCheckFnType
    46  }
    47  
    48  func (s *runtimeState) addHealthCheck(name string, f healthCheckFnType) {
    49  	s.Lock()
    50  	defer s.Unlock()
    51  	s.healthChecks = append(s.healthChecks, &healthCheck{name: name, fn: f})
    52  }
    53  
    54  func (s *runtimeState) setRuntimeSync(t time.Time) {
    55  	s.Lock()
    56  	defer s.Unlock()
    57  	s.lastBaseRuntimeSync = t
    58  }
    59  
    60  func (s *runtimeState) setNetworkState(err error) {
    61  	s.Lock()
    62  	defer s.Unlock()
    63  	s.networkError = err
    64  }
    65  
    66  func (s *runtimeState) setRuntimeState(err error) {
    67  	s.Lock()
    68  	defer s.Unlock()
    69  	s.runtimeError = err
    70  }
    71  
    72  func (s *runtimeState) setStorageState(err error) {
    73  	s.Lock()
    74  	defer s.Unlock()
    75  	s.storageError = err
    76  }
    77  
    78  func (s *runtimeState) setPodCIDR(cidr string) {
    79  	s.Lock()
    80  	defer s.Unlock()
    81  	s.cidr = cidr
    82  }
    83  
    84  func (s *runtimeState) podCIDR() string {
    85  	s.RLock()
    86  	defer s.RUnlock()
    87  	return s.cidr
    88  }
    89  
    90  func (s *runtimeState) runtimeErrors() error {
    91  	s.RLock()
    92  	defer s.RUnlock()
    93  	errs := []error{}
    94  	if s.lastBaseRuntimeSync.IsZero() {
    95  		errs = append(errs, errors.New("container runtime status check may not have completed yet"))
    96  	} else if !s.lastBaseRuntimeSync.Add(s.baseRuntimeSyncThreshold).After(time.Now()) {
    97  		errs = append(errs, errors.New("container runtime is down"))
    98  	}
    99  	for _, hc := range s.healthChecks {
   100  		if ok, err := hc.fn(); !ok {
   101  			errs = append(errs, fmt.Errorf("%s is not healthy: %v", hc.name, err))
   102  		}
   103  	}
   104  	if s.runtimeError != nil {
   105  		errs = append(errs, s.runtimeError)
   106  	}
   107  
   108  	return utilerrors.NewAggregate(errs)
   109  }
   110  
   111  func (s *runtimeState) networkErrors() error {
   112  	s.RLock()
   113  	defer s.RUnlock()
   114  	errs := []error{}
   115  	if s.networkError != nil {
   116  		errs = append(errs, s.networkError)
   117  	}
   118  	return utilerrors.NewAggregate(errs)
   119  }
   120  
   121  func (s *runtimeState) storageErrors() error {
   122  	s.RLock()
   123  	defer s.RUnlock()
   124  	errs := []error{}
   125  	if s.storageError != nil {
   126  		errs = append(errs, s.storageError)
   127  	}
   128  	return utilerrors.NewAggregate(errs)
   129  }
   130  
   131  func newRuntimeState(runtimeSyncThreshold time.Duration) *runtimeState {
   132  	return &runtimeState{
   133  		lastBaseRuntimeSync:      time.Time{},
   134  		baseRuntimeSyncThreshold: runtimeSyncThreshold,
   135  		networkError:             ErrNetworkUnknown,
   136  	}
   137  }