sigs.k8s.io/controller-runtime@v0.18.2/designs/cache_options.md (about) 1 Cache Options 2 =================== 3 4 This document describes how we imagine the cache options to look in 5 the future. 6 7 ## Goals 8 9 * Align everyone on what settings on the cache we want to support and 10 their configuration surface 11 * Ensure that we support both complicated cache setups and provide an 12 intuitive configuration UX 13 14 ## Non-Goals 15 16 * Describe the design and implementation of the cache itself. 17 The assumption is that the most granular level we will end up with is 18 "per-object multiple namespaces with distinct selectors" and that this 19 can be implemented using a "meta cache" that delegates per object and by 20 extending the current multi-namespace cache 21 * Outline any kind of timeline for when these settings will be implemented. 22 Implementation will happen gradually over time whenever someone steps up 23 to do the actual work 24 25 ## Proposal 26 27 28 ``` 29 const ( 30 AllNamespaces = corev1.NamespaceAll 31 ) 32 33 type Config struct { 34 // LabelSelector specifies a label selector. A nil value allows to 35 // default this. 36 LabelSelector labels.Selector 37 38 // FieldSelector specifics a field selector. A nil value allows to 39 // default this. 40 FieldSelector fields.Selector 41 42 // Transform specifies a transform func. A nil value allows to default 43 // this. 44 Transform toolscache.TransformFunc 45 46 // UnsafeDisableDeepCopy specifies if List and Get requests against the 47 // cache should not DeepCopy. A nil value allows to default this. 48 UnsafeDisableDeepCopy *bool 49 } 50 51 52 type ByObject struct { 53 // Namespaces maps a namespace name to cache setting. If set, only the 54 // namespaces in this map will be cached. 55 // 56 // Settings in the map value that are unset because either the value as a 57 // whole is nil or because the specific setting is nil will be defaulted. 58 // Use an empty value for the specific setting to prevent that. 59 // 60 // It is possible to have specific Config for just some namespaces 61 // but cache all namespaces by using the AllNamespaces const as the map key. 62 // This wil then include all namespaces that do not have a more specific 63 // setting. 64 // 65 // A nil map allows to default this to the cache's DefaultNamespaces setting. 66 // An empty map prevents this. 67 // 68 // This must be unset for cluster-scoped objects. 69 Namespaces map[string]*Config 70 71 // Config will be used for cluster-scoped objects and to default 72 // Config in the Namespaces field. 73 // 74 // It gets defaulted from the cache'sDefaultLabelSelector, DefaultFieldSelector, 75 // DefaultUnsafeDisableDeepCopy and DefaultTransform. 76 Config *Config 77 } 78 79 type Options struct { 80 // ByObject specifies per-object cache settings. If unset for a given 81 // object, this will fall through to Default* settings. 82 ByObject map[client.Object]*ByObject 83 84 // DefaultNamespaces maps namespace names to cache settings. If set, it 85 // will be used for all objects that have a nil Namespaces setting. 86 // 87 // It is possible to have a specific Config for just some namespaces 88 // but cache all namespaces by using the `AllNamespaces` const as the map 89 // key. This wil then include all namespaces that do not have a more 90 // specific setting. 91 // 92 // The options in the Config that are nil will be defaulted from 93 // the respective Default* settings. 94 DefaultNamespaces map[string]*Config 95 96 // DefaultLabelSelector is the label selector that will be used as 97 // the default field label selector for everything that doesn't 98 // have one configured. 99 DefaultLabelSelector labels.Selector 100 101 // DefaultFieldSelector is the field selector that will be used as 102 // the default field selector for everything that doesn't have 103 // one configured. 104 DefaultFieldSelector fields.Selector 105 106 // DefaultUnsafeDisableDeepCopy is the default for UnsafeDisableDeepCopy 107 // for everything that doesn't specify this. 108 DefaultUnsafeDisableDeepCopy *bool 109 110 // DefaultTransform will be used as transform for all object types 111 // unless they have a more specific transform set in ByObject. 112 DefaultTransform toolscache.TransformFunc 113 114 // HTTPClient is the http client to use for the REST client 115 HTTPClient *http.Client 116 117 // Scheme is the scheme to use for mapping objects to GroupVersionKinds 118 Scheme *runtime.Scheme 119 120 // Mapper is the RESTMapper to use for mapping GroupVersionKinds to Resources 121 Mapper meta.RESTMapper 122 123 // SyncPeriod determines the minimum frequency at which watched resources are 124 // reconciled. A lower period will correct entropy more quickly, but reduce 125 // responsiveness to change if there are many watched resources. Change this 126 // value only if you know what you are doing. Defaults to 10 hours if unset. 127 // there will a 10 percent jitter between the SyncPeriod of all controllers 128 // so that all controllers will not send list requests simultaneously. 129 // 130 // This applies to all controllers. 131 // 132 // A period sync happens for two reasons: 133 // 1. To insure against a bug in the controller that causes an object to not 134 // be requeued, when it otherwise should be requeued. 135 // 2. To insure against an unknown bug in controller-runtime, or its dependencies, 136 // that causes an object to not be requeued, when it otherwise should be 137 // requeued, or to be removed from the queue, when it otherwise should not 138 // be removed. 139 // 140 // If you want 141 // 1. to insure against missed watch events, or 142 // 2. to poll services that cannot be watched, 143 // then we recommend that, instead of changing the default period, the 144 // controller requeue, with a constant duration `t`, whenever the controller 145 // is "done" with an object, and would otherwise not requeue it, i.e., we 146 // recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`, 147 // instead of `reconcile.Result{}`. 148 SyncPeriod *time.Duration 149 150 } 151 ``` 152 153 154 ## Example usages 155 156 ### Cache ConfigMaps in the `public` and `kube-system` namespaces and Secrets in the `operator` Namespace 157 158 159 ``` 160 cache.Options{ 161 ByObject: map[client.Object]*cache.ByObject{ 162 &corev1.ConfigMap{}: { 163 Namespaces: map[string]*cache.Config{ 164 "public": {}, 165 "kube-system": {}, 166 }, 167 }, 168 &corev1.Secret{}: {Namespaces: map[string]*Config{ 169 "operator": {}, 170 }}, 171 }, 172 } 173 ``` 174 175 ### Cache ConfigMaps in all namespaces without selector, but have a selector for the `operator` Namespace 176 177 ``` 178 cache.Options{ 179 ByObject: map[client.Object]*cache.ByObject{ 180 &corev1.ConfigMap{}: { 181 Namespaces: map[string]*cache.Config{ 182 cache.AllNamespaces: nil, // No selector for all namespaces... 183 "operator": {LabelSelector: labelSelector}, // except for the operator namespace 184 }, 185 }, 186 }, 187 } 188 ``` 189 190 191 ### Only cache the `operator` namespace for namespaced objects and all namespaces for Deployments 192 193 ``` 194 cache.Options{ 195 ByObject: map[client.Object]*cache.ByObject{ 196 &appsv1.Deployment: {Namespaces: map[string]*cache.Config{ 197 cache.AllNamespaces: nil, 198 }}, 199 }, 200 DefaultNamespaces: map[string]*cache.Config{ 201 "operator": nil, 202 }, 203 } 204 ``` 205 206 ### Use a LabelSelector for everything except Nodes 207 208 ``` 209 cache.Options{ 210 ByObject: map[client.Object]*cache.ByObject{ 211 &corev1.Node: {LabelSelector: labels.Everything()}, 212 }, 213 DefaultLabelSelector: myLabelSelector, 214 } 215 ``` 216 217 ### Only cache namespaced objects in the `foo` and `bar` namespace 218 219 ``` 220 cache.Options{ 221 DefaultNamespaces: map[string]*cache.Config{ 222 "foo": nil, 223 "bar": nil, 224 } 225 } 226 ```