@@ -7,17 +7,59 @@ permalink: /docs/patterns-best-practices
7
7
8
8
# Patterns and Best Practices
9
9
10
- This document describes patters and best practices, to build and run operators, and how to implement them in terms
11
- of Java Operator SDK.
10
+ This document describes patterns and best practices, to build and run operators, and how to implement them in terms of
11
+ Java Operator SDK.
12
+
13
+ See also best practices in [ Operator SDK] ( https://sdk.operatorframework.io/docs/best-practices/best-practices/ ) .
12
14
13
15
## Implementing a Reconciler
14
16
17
+ ### Reconcile All The Resources All the Time
18
+
19
+ The reconciliation can be triggered by events from multiple sources. It could be tempting to check the events and
20
+ reconcile just the related resource or subset of resources that the controller manages. However, this is ** considered as an
21
+ anti-pattern** in operators. If triggered, all resources should be reconciled. Usually this means only
22
+ comparing the target state with the current state in the cache for most of the resource.
23
+ The reason behind this is events not reliable in generally, this means events can be lost. In addition to that operator
24
+ can crash and while down will miss events.
25
+
26
+ In addition to that such approach might even complicate implementation logic in the ` Reconciler ` , since parallel
27
+ execution of the reconciler is not allowed for the same custom resource, there can be multiple events received for the
28
+ same resource or dependent resource during an ongoing execution, ordering those events could be also challenging.
29
+
30
+ Since there is a consensus regarding this in the industry, from v2 the events are not even accessible for
31
+ the ` Reconciler ` .
32
+
15
33
### Idempotency
16
34
17
- ### Sync of Async Way of Resource Handling
35
+ Since all the resources are reconciled during an execution and an execution can be triggered quite often, also
36
+ retries of a reconciliation can happen naturally in operators, the implementation of a ` Reconciler `
37
+ needs to be idempotent. Luckily, since operators are usually managing already declarative resources, this is trivial
38
+ to do in most cases.
39
+
40
+ ### Sync or Async Way of Resource Handling
41
+
42
+ In an implementation of reconciliation there can be a point when reconciler needs to wait a non-insignificant amount
43
+ of time while a resource gets up and running. For example, reconciler would do some additional step only if a Pod is ready
44
+ to receive requests. This problem can be approached in two ways synchronously or asynchronously.
45
+
46
+ The async way is just return from the reconciler, if there are informers properly in place for the target resource,
47
+ reconciliation will be triggered on change. During the reconciliation the pod can be read from the cache of the informer
48
+ and a check on it's state can be conducted again. The benefit of this approach is that it will free up the thread,
49
+ so it can be used to reconcile other resources.
50
+
51
+ The sync way would be to periodically poll the cache of the informer for the pod's state, until the target state
52
+ is reached. This would block the thread until the state is reached, which in some cases could take quite long.
18
53
19
54
## Why to Have Automated Retries?
20
55
56
+ Automatic retries are in place by default, it can be fine-tuned, but in general it's not advised to turn
57
+ of automatic retries. One of the reason is that, issues like network error naturally happens, and are usually
58
+ solved by a retry. Another typical situation is for example when a dependent resource or the custom resource is updated,
59
+ during the update usually there is optimistic version control in place. So if someone updated the resource during
60
+ reconciliation, maybe using ` kubectl ` or another process, the update would fail on a conflict. A retry solves this
61
+ problem simply by executing the reconciliation again.
62
+
21
63
## Managing State
22
64
23
65
## Dependent Resources
0 commit comments