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.