|
| 1 | +# Title |
| 2 | + |
| 3 | +* Author(s): Yuwen Ma <[email protected]> |
| 4 | +* Contributor(s): |
| 5 | + - Sean Sullivan <[email protected]> |
| 6 | + |
| 7 | + - Mortent Torkildsen <[email protected]> |
| 8 | + |
| 9 | + - Natasha Sarkar <[email protected]> |
| 10 | + |
| 11 | +* Approver: Sunil Arora <[email protected]> |
| 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. |
0 commit comments