github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/docs/design-docs/01-live-invenstory-to-rg.md (about) 1 # Title 2 3 * Author(s): Yuwen Ma <yuwenma@google.com> 4 * Contributor(s): 5 - Sean Sullivan <seans@google.com> 6 - Sunil Arora <sunilarora@google.com> 7 - Mortent Torkildsen <mortent@google.com> 8 - Mengqi Yu <mengqiy@google.com> 9 - Natasha Sarkar <natashasarkar@google.com> 10 11 * Approver: Sunil Arora <sunilarora@google.com> 12 13 ## Why 14 15 This design is aimed at making `kpt live` be hydration-tool-neutral so that `kpt live` 16 applicable use cases can be expanded to `kustomize build`, `helm templates` and raw 17 kubernetes manifests. 18 19 ### Non-goal 20 - This doc is not aimed at designing a unified hydration between kpt and kustomize 21 - This doc is not aimed at changing the kpt in-place hydration models. 22 23 ## Design 24 25 We propose to make `kpt live` support reading configurations from standard input, 26 detach the Inventory from Kptfile and simplify the Inventory-ResourceGroup mechanism 27 to use ResourceGroup only. 28 29 ### Read standard input resources 30 31 We will change the existing `kpt live apply` from STDIN to not require the existence of Kptfile ( 32 to be more specific, the `inventory` file from Kptfile). As long as the STDIN contains 33 one and only one valid ResourceGroup, `kpt live apply` should be able to create/match the 34 ResourceGroup in cluster. 35 36 ### Initialize a `ResourceGroup` object 37 38 `kpt live init` will create a ResourceGroup CR in resourcegroup.yaml. 39 40 By default, the ResoureGroup will have name and namespace assigned as below. And users can 41 override via existing flags "--name" and "--namespace". 42 43 - metadata.name: A client-provided valid RFC 1123 DNS subdomain name. Default value has prefix “inventory-” with 44 8 digit numbers. E.g. "inventory-02014045" 45 - metadata.namespace: a valid namespace. default to value "default" 46 47 If users want to reuse an existing inventory (from Kptfile) or ResourceGroup (which has been deployed to the cluster), 48 they shall provide the value of the inventory's inventory-id or the ResourceGroup's "metadata.labels[0].cli-utils.sigs.k8s.io/inventory-id" 49 via "--inventory-id" flag. 50 51 ### Convert Inventory to ResourceGroup 52 53 The client-side Inventory is considered as the identifier of the cluster-side 54 ResourceGroup CR. Right now, the Inventory is stored in the Kptfile to guarantee 55 the ResourceGroup is unique. This requires Kptfile to exist to use `kpt live apply`. 56 57 To split the Inventory from Kptfile to resourcegroup.yaml and convert the Inventory to 58 ResourceGroup, `kpt live migrate` should be extended to map the inventory.name, 59 inventory.namespace, inventory.inventoryID to ResourceGroup CR metadata.name, 60 metadata.namespace, metadata.labels.cli-utils.sigs.k8s.io/inventory-id correspondingly. 61 62 Inventory in Kptfile 63 ```yaml 64 apiVersion: kpt.dev/v1 65 kind: Kptfile 66 inventory: 67 name: <INVENTORY_NAME> 68 namespace: <INVENTORY_NAMESPACE> 69 inventoryID: <INVENTORY_ID> 70 ``` 71 resoucegroup.yaml 72 ```yaml 73 apiVersion: kpt.dev/v1alpha1 74 kind: ResourceGroup 75 metadata: 76 name: <INVENTORY_NAME> 77 namespace: <INVENTORY_NAMESPACE> 78 labels: 79 cli-utils.sigs.k8s.io/inventory-id: <INVENTORY_ID> 80 ``` 81 82 ### Simplify the Inventory 83 84 Current inventory contains inventory-id which is required to match the label `cli-utils.sigs.k8s.io/inventory-id`. 85 86 For new users, they should no longer need to be exposed to the inventory-id, but kpt will 87 build one composed by `name-namespace` on the fly. 88 89 For existing users, the inventory-id is still 90 required in the standalone ResourceGroup file to guarantee the adoption matches, unless they use "--inventory-policy=adopt" 91 to override the label. This flag is only required as a one-off via `kpt live apply -` to override the label to `name-namespace`. 92 93 ### ResourceGroup as a singleton object 94 95 `kpt live apply [--rg-file] -` from STDIN accepts and only accepts a single 96 ResourceGroup, including the ResourceGroup provided by the flag. It detects 97 1. If more than one ResourceGroup is found, raise errors and display all the ResourceGroup objects. 98 2. If no ResourceGroup is found in STDIN and and Kptfile inventory does not exists, raise errors and suggest users to 99 run kpt live init 100 3. If no ResourceGroup is found in STDIN and Kptfile inventory exists, raise errors and 101 suggest users to run kpt live migrate 102 103 ### New flags 104 105 #### `--rg-file` 106 107 - description: The file path to the ResourceGroup CR, default to `resourcegroup.yaml` 108 - short form `--rg` 109 - This flag will be added to `kpt live init`, `kpt live migrate` and `kpt live apply` 110 111 #### `--name` for inventory 112 113 - description: The name for the ResourceGroup 114 - This flag will continue to be used by `kpt live init`. Rather than overriding the 115 inventory.name in Kptfile, it will override the default metadata.name in the standalone ResourceGroup file. 116 117 #### `--namespace` for inventory 118 119 - description: The namespace for the ResourceGroup 120 - This flag will continue to be used by `kpt live init`, Rather than overriding the 121 inventory.namespace in Kptfile, it will override the default metadata.namespace in the standalone ResourceGroup file. 122 123 #### `--inventory-id` for inventory 124 125 - description: Inventory identifier. This is used to detect overlap between 126 two sets of ResourceGroup managed resources that might use the same name and namespace. 127 - This flag will continue to be accepted by `kpt live init` for backward compatibility reasons. 128 If given, ResourceGroup will store the inventory-id value in "metadata.labels[0].cli-utils.sigs.k8s.io/inventory-id" 129 of the ResourceGroup. 130 If not given, the ResourceGroup labels will be empty and the value of "<name>-<namespace>" will be 131 used as the "cli-utils.sigs.k8s.io/inventory-id" label in `kpt live apply` from STD. 132 133 ### `resoucegroup.yaml` interaction with `kpt fn` commands 134 135 All `kpt fn` commands should treat `resoucegroup.yaml` as a special resource 136 and not modify it in any scenario. It should not be considered as a meta resource and 137 `include-meta-resources` flag should not include the `ResourceGroup` resource in 138 the `ResourceList`. In the future, we can add a new flag `--include-rg` if there are 139 valid use-cases to modify or include `ResourceGroup` resource in `ResourceList`. 140 141 ## User Guide 142 143 ### To hydrate via kustomize and deploy via kpt 144 145 #### Day 1 146 147 ##### For new users to start from scratch (no Kptfile) 148 User can run `kpt live init [--rg-file=resourcegroup.yaml]` to create a 149 ResourceGroup object and store it in a resourcegroup.yaml file. 150 Users can customize the file path with the flag “--rg-file”. 151 152 ##### For existing kpt users to migrate from Kptfile 153 Users run `kpt live migrate [--rg-file=resourcegroup.yaml]` to convert the 154 Inventory object from Kptfile to a standalone resourcegroup.yaml file. 155 Users can customize the file path with the flag “--rg-file”. 156 157 ##### [optional]: Add shareable ResourceGroup to kustomize resources 158 If the ResourceGroup is expected to be shared in the Gitops workflow, users can add 159 the resourcegroup.yaml file path to the .resources field in kustomization.yaml. 160 This simplifies the Day N deployment by omitting the “–rg-file“ flag. 161 162 #### Day N 163 164 - Users can configure the hydration rules in kustomization.yaml 165 - Users can run `kustomize build <DIR> | kpt live apply -` to hydrate and deploy 166 the kustomize-managed configurations. If resourcegroup.yaml is not added to 167 kustomize .resources field, users should provide the “–rg-file“ flag. 168 `kustomize build <DIR> | kpt live apply –rg-file <resourcegroup.yaml> -` 169 170 ### To hydrate via helm and deploy via kpt 171 172 #### Day 1 173 174 ##### For new users to start from scratch (no Kptfile) 175 User can run `kpt live init --rg-file=<DIR>/resourcegroup.yaml` to create 176 a ResourceGroup object and store it in the helm template <DIR>. 177 178 ##### For existing kpt users to migrate from Kptfile 179 Users run `kpt live migrate --rg-file=<DIR>/resourcegroup.yaml` to convert 180 the Inventory object from Kptfile to a standalone resourcegroup.yaml file. 181 182 #### Day N 183 184 Users can run `helm templates <DIR> | kpt live apply -` to hydrate and deploy the 185 helm-managed resources. 186 187 See kpt issue #2399 for expected Inventory usage in package publisher/consumer. 188 189 ## FAQ 190 191 ### Will Inventory be deprecated from Kptfile? 192 193 Kpt still supports inventory in Kptfile and it is not required to migrate to the 194 standalone rg-path. In fact, users who do not use STDIN in `kpt live apply` 195 will still have inventory read from Kptfile by default unless the –inventory-path flag 196 is given. 197 198 ### Why not kpt live apply -k? 199 200 We originally propose to use a single command kpt live apply -k (similar idea as 201 kubectl apply -k ) to kustomize-hydrate and kpt-deploy the resources, storing the 202 inventory in the annotation fields of the kustomization.yaml (See below). 203 The inventory can be auto added to kustomization.yaml by kpt live init 204 ```yaml 205 apiVersion: kustomize.config.k8s.io/v1beta1 206 kind: Kustomization 207 metadata: 208 annotations: 209 kpt-inventory-id: 210 kpt-inventory-name: 211 kpt-inventory-namespace: 212 ``` 213 #### Pros 214 215 - Extreme simple user steps. Kustomize users only need to install kpt and run kpt live 216 init. Then they can start using kpt live apply to deploy their kustomize resources. 217 No manual changes to any configurations. 218 - Easy to understand. The command is similar to kubectl apply -k which makes it easier 219 to be accepted and remembered. 220 221 There are two main reasons to abandon this approach: 222 - Making Kpt a hydration-neutral deployment tool helps it better hook up with different 223 hydration tools. 224 - kpt is not planning to treat kustomize differently and thus it does not make sense to 225 provide kustomize a shortcut. 226 227 ## Alternatives Considered 228 229 ### Use Inventory metadata to store ResourceGroup info 230 231 Store the Kptfile inventory to a standalone Inventory object. Since the inventory is 232 the metadata of the cluster side ResourceGroup, hiding the ResourceGroup behind 233 inventory provides users simpler syntax and mitigates the probability of overriding 234 the ResourceGroup unintentionally (e.g. via kubectl apply). 235 236 inventory.yaml 237 ```yaml 238 apiVersion: kpt.dev/v1 239 kind: Inventory 240 metadata: 241 name: <INVENTORY_NAME> 242 namespace: <INVENTORY_NAMESPACE> 243 inventoryID: <INVENTORY_ID> 244 ``` 245 246 #### Pros 247 248 - Simpler resource syntax 249 - Mitigate unintentional resourceGroup override. 250 251 #### Cons 252 - The client-side inventory requires users to manage. 253 This new resource increases the overall complexity of the kpt actuation config. 254 We frequently receive user confusions about the difference between ResourceGroup 255 and Inventory and why they cannot configure inventory like other kubernetes resource 256 (adoption mismatch errors). 257 258 ### Use Inventory spec to store ResourceGroup info 259 260 261 inventory.yaml 262 ```yaml 263 apiVersion: kpt.dev/v1 264 kind: Inventory 265 spec: 266 resourceGroup: 267 name: <INVENTORY_NAME> 268 Namespace: <INVENTORY_NAMESPACE> 269 labels: 270 cli-utils.sigs.k8s.io/inventory-id: <INVENTORY_ID> 271 ``` 272 #### Pros 273 274 - Obey the kubernetes convention and make it clearer that users are expected to provide the resourceGroup kind with name, namespace and labels. 275 - Mitigate unintentional resourceGroup override. 276 277 #### Cons 278 More complex syntax than ResourceGroup or Inventory metadata solution 279 280 ### Add a controller for ResourceGroup pruning; No client-side Inventory 281 282 Inventory is a [cli-utils object](https://github.com/kubernetes-sigs/cli-utils/blob/52b000849deb2b233f0a58e9be16ca2725a4c9cf/pkg/inventory/inventory.go#L30) used to store the [ResourceGroup metadata](https://docs.google.com/document/d/1x_02xGKZH6YGuc3K-KNeY4KmADPAwzrlQKkvTNXYekc/edit#heading=h.265kfx5ku27). 283 It is stored in Kptfile .Inventory and required by `kpt live apply`. In lieu of a user configuration, it is more of a data for kpt to identify the corresponding ResourceGroup for pruning. This adds non-trivial overheads for users to understand, maintain and retrieve the inventory. 284 285 The alternative proposal is to remove the inventory but use a new controller to prune the resource. 286 The controller will be installed together with ResourceGroup CRD (in each `kpt live apply`). 287 It will find the previous ResourceGroup CR from current resources, three-way merging and deploying 288 the new resources and update the ResourceGroup. 289 290 #### Pros 291 - Improve the user experience on using kpt live and minimize the confusions around inventory and ResourceGroup 292 - Eliminate the pain points on retrieving the missing Inventory (list all ResourceGroup, check the .spec.resources and try one by one until not encounter the “missing adoption” error). 293 294 #### Cons 295 The controller needs multiple requests to find out the previous ResourceGroup CR. This causes heavy traffic in a production cluster. 296 The controller cannot 100% guarantee the resourceGroup reverse lookup are accurate. 297 Since the pruning happens on the cluster side, kpt can no longer provide real-time status updates.