Skip to content

Commit c87f8f2

Browse files
committed
add terminator documentation
On-behalf-of: SAP <[email protected]> Signed-off-by: Simon Bein <[email protected]>
1 parent 082970b commit c87f8f2

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

docs/content/concepts/workspaces/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ nav:
33
- workspace-types.md
44
- virtual-workspaces.md
55
- workspace-initialization.md
6+
- workspace-termination.md
67
- mounts.md
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Workspace Termination
2+
3+
Workspace termination in kcp involves setting up optional cleanup logic when a Workspace is marked for deletion. This process is managed through `terminators`, which are enabled via `WorkspaceType` objects. In kcp, Terminators are the counterpart to [initializers](workspace-initialization.md). This document covers how to configure terminators, the necessary RBAC permissions, URL schemes, and the reasons for using terminators.
4+
5+
## Terminators
6+
7+
Terminators are used to customize the cleanup of workspaces and required resources. Terminators are defined in `WorkspaceType` objects and will be propagated to Workspaces and LogicalClusters. By doing this, users can create controllers processing `LogicalClusters` and running custom cleanup logic. Afterwards the controller has to remove its corresponding terminator. Once all terminators are removed, a logical cluster will be deleted. After a logical-cluster is deleted, its workspace is also ready for deletion.
8+
9+
Terminators are meant to be used specifically to customize deletion logic of LogicalClusters. For resources inside your workspace, you can use traditional Kubernetes finalizers.
10+
11+
### Defining Terminators in WorkspaceTypes
12+
13+
A `WorkspaceType` can specify having a terminator using the `terminator` field. Here is an example of a `WorkspaceType` with a terminator.
14+
15+
```yaml
16+
apiVersion: tenancy.kcp.io/v1alpha1
17+
kind: WorkspaceType
18+
metadata:
19+
name: example
20+
spec:
21+
terminator: true
22+
defaultChildWorkspaceType:
23+
name: universal
24+
path: root
25+
```
26+
27+
Each terminator has a unique name, which gets automatically generated using `<workspace-path-of-WorkspaceType>:<WorkspaceType-name>`. So for example, if you were to apply the aforementioned `WorkspaceType` in the `root` workspace, your terminator would be called `root:example`.
28+
29+
Since `WorkspaceType.spec.terminators` is a boolean field, each `WorkspaceType` comes with a single terminator by default. However each `WorkspaceType` inherits the terminators of its parent WorkspaceType. As a result, it is possible to have multiple terminators on a `WorkspaceType` using [WorkspaceType Extension](../../concepts/workspaces/workspace-types.md#workspace-type-extensions-and-constraints)
30+
31+
In the following example, `child` inherits the terminators of `parent`. As a result, child workspaces will have the `root:child` and `root:parent` terminators set.
32+
33+
```yaml
34+
apiVersion: tenancy.kcp.io/v1alpha1
35+
kind: WorkspaceType
36+
metadata:
37+
name: child
38+
spec:
39+
terminator: true
40+
extend:
41+
with:
42+
- name: parent
43+
path: root
44+
```
45+
46+
### Enforcing Permissions for Terminators
47+
48+
The non-root user must have the `terminate` verb on the `WorkspaceType` that the terminator is for. This ensures that only authorized users can perform termination actions using the virtual workspace endpoint. Here is an example of the `ClusterRole`.
49+
50+
```yaml
51+
apiVersion: rbac.authorization.k8s.io/v1
52+
kind: ClusterRole
53+
metadata:
54+
name: terminate-example-workspacetype
55+
rules:
56+
- apiGroups: ["tenancy.kcp.io"]
57+
resources: ["workspacetypes"]
58+
resourceNames: ["example"]
59+
verbs: ["terminate"]
60+
```
61+
62+
You can then bind this role to a user or a group.
63+
64+
```yaml
65+
apiVersion: rbac.authorization.k8s.io/v1
66+
kind: ClusterRoleBinding
67+
metadata:
68+
name: terminate-example-workspacetype-binding
69+
subjects:
70+
- kind: User
71+
name: user1
72+
apiGroup: rbac.authorization.k8s.io
73+
roleRef:
74+
kind: ClusterRole
75+
name: terminate-example-workspacetype
76+
apiGroup: rbac.authorization.k8s.io
77+
```
78+
79+
## Writing Custom Termination Controllers
80+
81+
Custom Termination Controllers are responsible for handling termination logic for custom WorkspaceTypes. They interact with kcp by:
82+
83+
1. Watching for `LogicalClusters` (the backing object behind Workspaces) which are marked for deletion and have the corresponding terminator set
84+
2. Running any custom cleanup logic
85+
3. Removing the corresponding terminator from the `.status.terminators` list of the `LogicalCluster` after cleanup logic has successfully finished
86+
87+
In order to simplify these processes, kcp provides the `terminating` virtual workspace.
88+
89+
### The `terminating` Virtual Workspace
90+
91+
As a service provider, you can use the `terminatingworkspaces` virtual workspace to manage workspace resources in the terminating phase. This virtual workspace allows you to fetch `LogicalCluster` objects which have a DeletionTimeStamp and request termination by a specific controller.
92+
93+
You can retrieve the url for the TerminatingVirtualWorkspace directly from the `.status.virtualWorkspaces` field of the corresponding `WorkspaceType`. Returning to our previous example using a custom `WorkspaceType` called "example", you will receive the following output:
94+
95+
```sh
96+
$ kubectl get workspacetype example -o yaml
97+
...
98+
status:
99+
virtualWorkspaces:
100+
- url: https://<shard-url>/services/terminatingworkspaces/root:example
101+
```
102+
103+
You can use this url to construct a kubeconfig for your controller. To do so, use the url directly as the `cluster.server` in your kubeconfig and provide the subject with sufficient permissions (see [Enforcing Permissions for Terminators](#enforcing-permissions-for-terminators))
104+
105+
### Practical Tips
106+
107+
When writing a custom terminator controller, the following needs to be taken into account:
108+
109+
* We strongly recommend to use [multicluster-runtime](github.com/kcp-dev/multicluster-runtime) to build your controller in order to properly handle which `LogicalCluster` originates from which workspace
110+
* You need to update `LogicalClusters` using patches; They cannot be updated using the update api

0 commit comments

Comments
 (0)