github.phpd.cn/cilium/cilium@v1.6.12/pkg/k8s/error_helpers.go (about) 1 // Copyright 2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package k8s 16 17 import ( 18 "strings" 19 "time" 20 21 "github.com/cilium/cilium/pkg/lock" 22 ) 23 24 var ( 25 26 // k8sErrMsgMU guards additions and removals to k8sErrMsg, which stores a 27 // time after which a repeat error message can be printed 28 k8sErrMsgMU lock.Mutex 29 k8sErrMsg = map[string]time.Time{} 30 k8sErrLogTimeout = time.Minute 31 ) 32 33 // k8sErrorUpdateCheckUnmuteTime returns a boolean indicating whether we should 34 // log errmsg or not. It manages once-per-k8sErrLogTimeout entry in k8sErrMsg. 35 // When errmsg is new or more than k8sErrLogTimeout has passed since the last 36 // invocation that returned true, it returns true. 37 func k8sErrorUpdateCheckUnmuteTime(errstr string, now time.Time) bool { 38 k8sErrMsgMU.Lock() 39 defer k8sErrMsgMU.Unlock() 40 41 if unmuteDeadline, ok := k8sErrMsg[errstr]; !ok || now.After(unmuteDeadline) { 42 k8sErrMsg[errstr] = now.Add(k8sErrLogTimeout) 43 return true 44 } 45 46 return false 47 } 48 49 // K8sErrorHandler handles the error messages in a non verbose way by omitting 50 // repeated instances of the same error message for a timeout defined with 51 // k8sErrLogTimeout. 52 func K8sErrorHandler(e error) { 53 if e == nil { 54 return 55 } 56 57 // We rate-limit certain categories of error message. These are matched 58 // below, with a default behaviour to print everything else without 59 // rate-limiting. 60 // Note: We also have side-effects in some of the special cases. 61 now := time.Now() 62 errstr := e.Error() 63 switch { 64 // This can occur when cilium comes up before the k8s API server, and keeps 65 // trying to connect. 66 case strings.Contains(errstr, "connection refused"): 67 if k8sErrorUpdateCheckUnmuteTime(errstr, now) { 68 log.WithError(e).Error("k8sError") 69 } 70 71 // k8s does not allow us to watch both ThirdPartyResource and 72 // CustomResourceDefinition. This would occur when a user mixes these within 73 // the k8s cluster, and might occur when upgrading from versions of cilium 74 // that used ThirdPartyResource to define CiliumNetworkPolicy. 75 case strings.Contains(errstr, "Failed to list *v2.CiliumNetworkPolicy: the server could not find the requested resource"): 76 if k8sErrorUpdateCheckUnmuteTime(errstr, now) { 77 log.WithError(e).Error("No Cilium Network Policy CRD defined in the cluster, please set `--skip-crd-creation=false` to avoid seeing this error.") 78 } 79 80 // fromCIDR and toCIDR used to expect an "ip" subfield (so, they were a YAML 81 // map with one field) but common usage and expectation would simply list the 82 // CIDR ranges and IPs desired as a YAML list. In these cases we would see 83 // this decode error. We have since changed the definition to be a simple 84 // list of strings. 85 case strings.Contains(errstr, "Unable to decode an event from the watch stream: unable to decode watch event"), 86 strings.Contains(errstr, "Failed to list *v1.CiliumNetworkPolicy: only encoded map or array can be decoded into a struct"), 87 strings.Contains(errstr, "Failed to list *v2.CiliumNetworkPolicy: only encoded map or array can be decoded into a struct"), 88 strings.Contains(errstr, "Failed to list *v2.CiliumNetworkPolicy: v2.CiliumNetworkPolicyList:"): 89 if k8sErrorUpdateCheckUnmuteTime(errstr, now) { 90 log.WithError(e).Error("Unable to decode k8s watch event") 91 } 92 93 default: 94 log.WithError(e).Error("k8sError") 95 } 96 }