Skip to content

Commit 575efe5

Browse files
Design proposal: kpt live -- Inventory to ResourceGroup (#2576)
* DD for kpt live apply from STDIN * resolve comments * Update doc with rg fn interaction Co-authored-by: Phani Teja Marupaka <[email protected]>
1 parent ef4c91e commit 575efe5

File tree

1 file changed

+297
-0
lines changed

1 file changed

+297
-0
lines changed
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
# Title
2+
3+
* Author(s): Yuwen Ma <[email protected]>
4+
* Contributor(s):
5+
- Sean Sullivan <[email protected]>
6+
- Sunil Arora <[email protected]>
7+
- Mortent Torkildsen <[email protected]>
8+
- Mengqi Yu <[email protected]>
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

Comments
 (0)