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 }