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  }