Skip to content

Commit c3dbfc0

Browse files
authored
adr(031): Resource Labels and Namespacing (#443)
* Initial commit * Add alternative labels, add section about mgmt tools * Add pseudo code for various commands * Add TBD results * Add alternative labels for management tools * Fix typo * Add label examples * Add section on custom user-provided labels * Add option 4 for custom user-provided labels * Delete accidentally committed VSC settings file * Update option 2 * Add some more details * Add result item for scope * Add decision results * Mark ADR as accepted
1 parent b4825d3 commit c3dbfc0

File tree

3 files changed

+296
-1
lines changed

3 files changed

+296
-1
lines changed
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
= ADRXXX: Resource Labels and Namespacing
2+
Sascha Lautenschläger <sascha.lautenschlaeger@stackable.tech>
3+
v0.1, 2023-08-25
4+
:status: accepted
5+
6+
* Status: {status}
7+
* Contributors:
8+
** Malte Sander
9+
** Sebastian Bernauer
10+
** Sascha Lautenschläger
11+
** Razvan Mihai
12+
* Date: 2023-08-25
13+
14+
== Context and Problem Statement
15+
16+
This ADR tries to solve a common issue within the SDP. When `stackablectl` (and in the future our Cockpit) deploys
17+
resources into a Kubernetes cluster, we are currently unable to properly identify them afterwards. Adding a common set
18+
of labels to the resources we deploy will solve this issue. Additionally we will use namespaces to track resources
19+
deployed together. The following use-cases are then possible:
20+
21+
* Use-case 1: Uninstalling a demo and stack
22+
* Use-case 2: Remove/purge all resources deployed by Stackable at once
23+
* Use-case 3: Stacklet dependency tree (Only needed when decide against a discovery operator, see ...)
24+
* Use-case 4: Offer users to provide their own custom labels
25+
26+
== Decision Drivers
27+
28+
We want to introduce these common labels, as there is currently no reliable and correct way to determine which resources
29+
where deployed by one of our management tools. Deciding on a common and structured set of labels will help us to more
30+
easily manage resources deployed by us. This includes reading, listing, changing and deleting those resources. The
31+
addition of labels will resolve several long-standing issues in various repositories.
32+
33+
== Considered Options
34+
35+
Kubernetes reserves all labels and annotations in the `kubernetes.io` and `k8s.io` namespaces. See
36+
https://kubernetes.io/docs/reference/labels-annotations-taints/[here] and
37+
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set[here].
38+
39+
=== Preamble
40+
41+
One general decision we have to make is if we ant to introduce scopes for our label keys. In this context, scope refers
42+
to one (or more) domain name labels, otherwise known as subdomains. Scopes would allow us to introduce more granular
43+
(and also grouped) labels. On the other side, we need to consider if we need the added granularity based on the number
44+
and kind of labels we want to add. In general there are two options:
45+
46+
- `<scope>.stackable.tech/<key>=<value>`, with scope being **one** subdomain
47+
- `stackable.tech/<key>=<value>`, no scope
48+
49+
=== Labeling all Resources with a Vendor Label
50+
51+
* `app.kubernetes.io/vendor=Stackable`: This is no official well-known label and also violates the reserved namespaces
52+
above
53+
* `stackable.tech/vendor=Stackable`: Custom label key prefix, duplicate data
54+
* `meta.stackable.tech/vendor=Stackable`: Alternative to above, scoped, still duplicated data
55+
56+
It's hard (or impossible) to use a label without any duplicated data. So `stackable.tech/vendor=Stackable` seems like
57+
a straight-forward and concise option.
58+
59+
'''
60+
61+
A deployed ConfigMap could look like this:
62+
63+
[source,yaml]
64+
----
65+
apiVersion: v1
66+
kind: ConfigMap
67+
metadata:
68+
name: superset-node-default
69+
labels:
70+
app.kubernetes.io/name: superset # reduced set of common labels
71+
stackable.tech/vendor: Stackable # new vendor label
72+
data:
73+
----
74+
75+
[#ns-labels]
76+
=== Labeling Resources deployed within a Demo or Stack
77+
78+
* `stackable.tech/stack=<stack-name>`: Attached to all resources deployed by `stackablectl stack install`
79+
* `stackable.tech/demo=<demo-name>`: Attached to all resources deployed by `stackablectl demo install`
80+
81+
Alternatives to above are:
82+
83+
* `resources.stackable.tech/<stack|demo>=<stack-name|demo-name>`
84+
* `meta.stackable.tech/<stack|demo>=<stack-name|demo-name>`
85+
* `res.stackable.tech/<stack|demo>=<stack-name|demo-name>`
86+
87+
Both `<stack-name>` and `<demo-name>` will be replaced by the selected stack or demo name. We need to make sure that
88+
this value doesn't exceed the maximum length of 63 characters. If the name is too long, we have three options:
89+
90+
* Hard error out, the installation is canceled (Not recommended because stack and demo names are chosen by us)
91+
* We automatically truncate the name to the maximum length: `a-way-too-long-name` becomes `a-way-too-lo<EOL>`
92+
* We automatically truncate the name and add a random suffix: `a-way-too-long-name` becomes `a-way-a1b2c3<EOL>`
93+
94+
'''
95+
96+
A deployed ConfigMap (by running `stackablectl demo install`) could look like this. Notice that resources part of a demo
97+
**and** a stack include labels for both of these scopes.
98+
99+
[source,yaml]
100+
----
101+
apiVersion: v1
102+
kind: ConfigMap
103+
metadata:
104+
name: superset-node-default
105+
labels:
106+
app.kubernetes.io/name: superset # reduced set of common labels
107+
stackable.tech/vendor: Stackable
108+
stackable.tech/stack: nifi-kafka-druid-superset-s3 # new stack label
109+
stackable.tech/demo: nifi-kafka-druid-water-level-data # new demo label
110+
data:
111+
----
112+
113+
=== Namespacing Stacks and Demos
114+
115+
Considered default values for above labels are:
116+
117+
* `stackable-<demo|stack>-<demo-name|stack-name>(-suffix)`: Clearly indicates this namespace belongs to the SDP, we
118+
might run into length limits
119+
* `<demo|stack>-<demo-name|stack-name>(-suffix)`: Less likely we will run into length limits, but we loose the clear
120+
indication this namespace belongs to the SDP.
121+
122+
We need to perform length and character validation for these namespace names. There are two possible paths:
123+
124+
* If the user *doesn't* provide a custom namespace, we need to make sure that the value doesn't exceed it's maximum
125+
length when the stack or demo names are inserted. Truncate the name if needed.
126+
* If the user *does* provide a custom namespace, we need to make sure that the custom namespace length doesn't exceed
127+
it's maximum length. Don't automatically truncate, instead return an error explaining the user needs to shorten the
128+
namespace name.
129+
130+
The maximum length for both cases is 63 characters.
131+
132+
=== Adding Label to indicate which Management Tool was used
133+
134+
The following options are available:
135+
136+
* `app.kubernetes.io/managed-by=stackablectl|stackable-cockpit`: Well-known label, however not recommended because Helm
137+
already uses this label to track which resources are managed by Helm. As we use Helm in the background to install some
138+
of our manifests, we would potentially break Helms (uninstall) behavior.
139+
* `stackable.tech/managed-by=stackablectl|stackable-cockpit`: Doesn't collide with Helm
140+
* `stackable.tech/deployed-by=stackablectl|stackable-cockpit`: Alternative to above
141+
142+
Alternatives are:
143+
144+
* `management.stackable.tech/managed-by=stackablectl|stackable-cockpit`
145+
* `tools.stackable.tech/managed-by=stackablectl|stackable-cockpit`
146+
* `mgmt.stackable.tech/managed-by=stackablectl|stackable-cockpit`
147+
148+
'''
149+
150+
A deployed ConfigMap could look like this.:
151+
152+
[source,yaml]
153+
----
154+
apiVersion: v1
155+
kind: ConfigMap
156+
metadata:
157+
name: superset-node-default
158+
labels:
159+
app.kubernetes.io/name: superset # reduced set of common labels
160+
stackable.tech/vendor: Stackable
161+
stackable.tech/managed-by: stackablectl # new management tool label
162+
data:
163+
----
164+
165+
=== Enabling Custom Labels provided by Users
166+
167+
When providing support for user-controlled custom labels, we need to think about the degree of freedom we want to
168+
support. Possible levels where custom labels could be attached are: cluster, role, and role group level. We also need
169+
to make sure the custom user-provided labels don't collide with our labels. We can either:
170+
171+
* print out a warning and don't apply the invalid label(s)
172+
* hard-error and bail
173+
174+
==== Option 1 - Cluster Level Labels
175+
176+
[source,yaml]
177+
----
178+
---
179+
apiVersion: example.stackable.tech/v1alpha1
180+
kind: ExampleCluster
181+
metadata:
182+
name: example
183+
spec:
184+
clusterConfig:
185+
labels:
186+
foo: bar
187+
baz: foo
188+
----
189+
190+
==== Option 2 - Role (and Role Group) Level Labels
191+
192+
[source,yaml]
193+
----
194+
---
195+
apiVersion: example.stackable.tech/v1alpha1
196+
kind: ExampleCluster
197+
metadata:
198+
name: example
199+
labels:
200+
foo: bar
201+
baz: foo
202+
spec:
203+
----
204+
205+
==== Option 3 - Only Role Level Labels
206+
207+
This option is highly dependant on the outcome of the PodDisruptionBudget ADR. This options requires the introduction
208+
of `roleGroup` discussed in the mentioned ADR.
209+
210+
[source,yaml]
211+
----
212+
---
213+
apiVersion: example.stackable.tech/v1alpha1
214+
kind: ExampleCluster
215+
metadata:
216+
name: example
217+
spec:
218+
roleConfig:
219+
labels:
220+
foo: bar
221+
baz: foo
222+
----
223+
224+
==== Option 4 - Leave as is
225+
226+
Continue to use `podOverrides`. Don't introduce dedicated support for labels using above mentioned options 1-3.
227+
228+
== Thoughts on the Implementation
229+
230+
=== General Notes
231+
232+
* Each stack/demo will be deployed into its own namespace. This enables `stackablectl demo installed`
233+
* Each namespace has a label attached, see xref:#ns-labels[above].
234+
235+
=== `stackablectl demo install <name>`
236+
237+
[source]
238+
----
239+
if -n set {
240+
if ns exists -> Error or propose different ns
241+
} else {
242+
if ns exists {
243+
echo "Already installed. Install again?"
244+
ns += suffix
245+
}
246+
}
247+
248+
if demo/stack not supports ns {
249+
return Error
250+
}
251+
252+
if ns not exists {
253+
create_ns_with_label()
254+
}
255+
256+
template_plain_yaml_cluster_scope()
257+
258+
install_demo()
259+
----
260+
261+
=== `stackablectl demo uninstall <name>`
262+
263+
[source]
264+
----
265+
for chart in helmCharts.reverse() {
266+
chart.uninstall()
267+
}
268+
269+
// AuthClass, SecretClass, ClusterRole, ClusterRoleBinding, etc...
270+
delete_resources_with_label()
271+
272+
// Also deletes PVCs, operators are not uninstalled
273+
delete_ns_with_label()
274+
----
275+
276+
=== `stackablectl demo installed`
277+
278+
[source]
279+
----
280+
for demo in demos_with_label("demo-*") {
281+
echo demo
282+
}
283+
----
284+
285+
== Results
286+
287+
* **Scope:** Do not use scopes for now. Add it in the future if needed.
288+
* **Labeling all Resources with a Vendor Label:** Yes, use `stackable.tech/vendor=Stackable`
289+
* **Labeling Resources deployed within a Demo or Stack:** Yes, use `stackable-<demo|stack>-<demo-name|stack-name>(-suffix)`
290+
with `suffix` being optional and the implementation not yet decided on.
291+
* **Namespacing Stacks and Demos:** Yes, use `stackable-<demo|stack>-<demo-name|stack-name>(-suffix)`
292+
* **Adding Label to indicate which Management Tool was used:** Yes, use
293+
`stackable.tech/managed-by=stackablectl|stackable-cockpit`
294+
* **Enabling Custom Labels provided by Users:** No support for now. Add it in the future if this feature is requested.

modules/contributor/partials/current_adrs.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@
2727
**** xref:adr/ADR028-automatic-stackable-version.adoc[]
2828
**** xref:adr/ADR029-database-connection.adoc[]
2929
**** xref:adr/ADR030-allowed-pod-disruptions.adoc[]
30+
**** xref:adr/ADR031-resource-labels.adoc[]

ui

0 commit comments

Comments
 (0)