...

Source file src/k8s.io/kubernetes/pkg/kubelet/configmap/configmap_manager.go

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

     1  /*
     2  Copyright 2017 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 configmap
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"time"
    23  
    24  	v1 "k8s.io/api/core/v1"
    25  	clientset "k8s.io/client-go/kubernetes"
    26  	podutil "k8s.io/kubernetes/pkg/api/v1/pod"
    27  	corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
    28  	"k8s.io/kubernetes/pkg/kubelet/util/manager"
    29  
    30  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    31  	"k8s.io/apimachinery/pkg/runtime"
    32  	"k8s.io/apimachinery/pkg/util/sets"
    33  	"k8s.io/apimachinery/pkg/watch"
    34  	"k8s.io/utils/clock"
    35  )
    36  
    37  // Manager interface provides methods for Kubelet to manage ConfigMap.
    38  type Manager interface {
    39  	// Get configmap by configmap namespace and name.
    40  	GetConfigMap(namespace, name string) (*v1.ConfigMap, error)
    41  
    42  	// WARNING: Register/UnregisterPod functions should be efficient,
    43  	// i.e. should not block on network operations.
    44  
    45  	// RegisterPod registers all configmaps from a given pod.
    46  	RegisterPod(pod *v1.Pod)
    47  
    48  	// UnregisterPod unregisters configmaps from a given pod that are not
    49  	// used by any other registered pod.
    50  	UnregisterPod(pod *v1.Pod)
    51  }
    52  
    53  // simpleConfigMapManager implements ConfigMap Manager interface with
    54  // simple operations to apiserver.
    55  type simpleConfigMapManager struct {
    56  	kubeClient clientset.Interface
    57  }
    58  
    59  // NewSimpleConfigMapManager creates a new ConfigMapManager instance.
    60  func NewSimpleConfigMapManager(kubeClient clientset.Interface) Manager {
    61  	return &simpleConfigMapManager{kubeClient: kubeClient}
    62  }
    63  
    64  func (s *simpleConfigMapManager) GetConfigMap(namespace, name string) (*v1.ConfigMap, error) {
    65  	return s.kubeClient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, metav1.GetOptions{})
    66  }
    67  
    68  func (s *simpleConfigMapManager) RegisterPod(pod *v1.Pod) {
    69  }
    70  
    71  func (s *simpleConfigMapManager) UnregisterPod(pod *v1.Pod) {
    72  }
    73  
    74  // configMapManager keeps a cache of all configmaps necessary
    75  // for registered pods. Different implementation of the store
    76  // may result in different semantics for freshness of configmaps
    77  // (e.g. ttl-based implementation vs watch-based implementation).
    78  type configMapManager struct {
    79  	manager manager.Manager
    80  }
    81  
    82  func (c *configMapManager) GetConfigMap(namespace, name string) (*v1.ConfigMap, error) {
    83  	object, err := c.manager.GetObject(namespace, name)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	if configmap, ok := object.(*v1.ConfigMap); ok {
    88  		return configmap, nil
    89  	}
    90  	return nil, fmt.Errorf("unexpected object type: %v", object)
    91  }
    92  
    93  func (c *configMapManager) RegisterPod(pod *v1.Pod) {
    94  	c.manager.RegisterPod(pod)
    95  }
    96  
    97  func (c *configMapManager) UnregisterPod(pod *v1.Pod) {
    98  	c.manager.UnregisterPod(pod)
    99  }
   100  
   101  func getConfigMapNames(pod *v1.Pod) sets.String {
   102  	result := sets.NewString()
   103  	podutil.VisitPodConfigmapNames(pod, func(name string) bool {
   104  		result.Insert(name)
   105  		return true
   106  	})
   107  	return result
   108  }
   109  
   110  const (
   111  	defaultTTL = time.Minute
   112  )
   113  
   114  // NewCachingConfigMapManager creates a manager that keeps a cache of all configmaps
   115  // necessary for registered pods.
   116  // It implement the following logic:
   117  //   - whenever a pod is create or updated, the cached versions of all configmaps
   118  //     are invalidated
   119  //   - every GetObject() call tries to fetch the value from local cache; if it is
   120  //     not there, invalidated or too old, we fetch it from apiserver and refresh the
   121  //     value in cache; otherwise it is just fetched from cache
   122  func NewCachingConfigMapManager(kubeClient clientset.Interface, getTTL manager.GetObjectTTLFunc) Manager {
   123  	getConfigMap := func(namespace, name string, opts metav1.GetOptions) (runtime.Object, error) {
   124  		return kubeClient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, opts)
   125  	}
   126  	configMapStore := manager.NewObjectStore(getConfigMap, clock.RealClock{}, getTTL, defaultTTL)
   127  	return &configMapManager{
   128  		manager: manager.NewCacheBasedManager(configMapStore, getConfigMapNames),
   129  	}
   130  }
   131  
   132  // NewWatchingConfigMapManager creates a manager that keeps a cache of all configmaps
   133  // necessary for registered pods.
   134  // It implements the following logic:
   135  //   - whenever a pod is created or updated, we start individual watches for all
   136  //     referenced objects that aren't referenced from other registered pods
   137  //   - every GetObject() returns a value from local cache propagated via watches
   138  func NewWatchingConfigMapManager(kubeClient clientset.Interface, resyncInterval time.Duration) Manager {
   139  	listConfigMap := func(namespace string, opts metav1.ListOptions) (runtime.Object, error) {
   140  		return kubeClient.CoreV1().ConfigMaps(namespace).List(context.TODO(), opts)
   141  	}
   142  	watchConfigMap := func(namespace string, opts metav1.ListOptions) (watch.Interface, error) {
   143  		return kubeClient.CoreV1().ConfigMaps(namespace).Watch(context.TODO(), opts)
   144  	}
   145  	newConfigMap := func() runtime.Object {
   146  		return &v1.ConfigMap{}
   147  	}
   148  	isImmutable := func(object runtime.Object) bool {
   149  		if configMap, ok := object.(*v1.ConfigMap); ok {
   150  			return configMap.Immutable != nil && *configMap.Immutable
   151  		}
   152  		return false
   153  	}
   154  	gr := corev1.Resource("configmap")
   155  	return &configMapManager{
   156  		manager: manager.NewWatchBasedManager(listConfigMap, watchConfigMap, newConfigMap, isImmutable, gr, resyncInterval, getConfigMapNames),
   157  	}
   158  }
   159  

View as plain text