Skip to content

Commit 436eac7

Browse files
committed
Add FAQs
This adds a series of FAQs. A decent amount of this should be migrated to the KB book.
1 parent fcc2f0f commit 436eac7

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

FAQ.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# FAQ
2+
3+
### Q: How do I know which type of object a controller references?
4+
5+
**A**: Each controller should only reconcile one object type. Other
6+
affected objects should be mapped to a single type of root object, using
7+
the `EnqueueRequestForOwner` or `EnqueueRequestsFromMapFunc` event
8+
handlers, and potentially indicies. Then, your Reconcile method should
9+
attempt to reconcile *all* state for that given root objects.
10+
11+
### Q: How do I have different logic in my reconciler for different types of events (e.g. create, update, delete)?
12+
13+
**A**: You should not. Reconcile functions should be idempotent, and
14+
should always reconcile state by reading all the state it needs, then
15+
writing updates. This allows your reconciler to correctly respond to
16+
generic events, adjust to skipped or coalesced events, and easily deal
17+
with application startup. The controller will enqueue reconcile requests
18+
for both old and new objects if a mapping changes, but it's your
19+
responsibility to make sure you have enough information to be able clean
20+
up state that's no longer referenced.
21+
22+
### Q: My cache might be stale if I read from a cache! How should I deal with that?
23+
24+
**A**: There are several different approaches that can be taken, depending
25+
on your situation.
26+
27+
- When you can, take advantage of optimistic locking: use deterministic
28+
names for objects you create, so that the Kubernetes API server will
29+
warn you if the object already exists. May controllers in Kubernetes
30+
take this approach: the StatefulSet controller appends a specific number
31+
to each pod that it creates, while the Deployment controller hashes the
32+
pod template spec and appends that.
33+
34+
- In the few cases when you cannot take advantage of deterministic names
35+
(e.g. when using generateName), it may
36+
be useful in to track which actions you took, and assume that they need
37+
to be repeated if they don't occur after a given time (e.g. using
38+
a requeue result). This is what the ReplicaSet controller does.
39+
40+
In general, write your controller with the assumption that information
41+
will eventually be correct, but may be slightly out of date. Make sure
42+
that your reconcile function enforces the entire state of the world each
43+
time it runs. If none of this works for you, you can always construct
44+
a client that reads directly from the API server, but this is generally
45+
considered to be a last resort, and the two approaches above should
46+
generally cover most circumstances.
47+
48+
### Q: Where's the fake client? How do I use it?
49+
50+
**A**: The fake client
51+
[exists](https://godoc.org/sigs.k8s.io/controller-runtime/pkg/client/fake),
52+
but we generally reccomend using
53+
[envtest.Environment](https://godoc.org/sigs.k8s.io/controller-runtime/pkg/envtest#Environment)
54+
to test against a real API server. In our experience, tests using fake
55+
clients gradually re-implement poorly-written impressions of a real API
56+
server, which leads to hard-to-maintain, complex test code.
57+
58+
### Q: How should I write tests? Any suggestions for getting started?
59+
60+
- Use the aforementioned
61+
[envtest.Environment](https://godoc.org/sigs.k8s.io/controller-runtime/pkg/envtest#Environment)
62+
to spin up a real API server instead of trying to mock one out.
63+
64+
- Structure your tests to check the that the state of the world is as you
65+
expect it, *not* that a particular set of API calls were made, when
66+
working with Kubernetes APIs. This will allow you to more easily
67+
refactor and improve the internals of your controllers without changing
68+
your tests.
69+
70+
- Remember that any time you're interacting with the API server, changes
71+
may have some delay between write time and reconcile time.
72+
73+
### Q: What are these errors about no Kind being registered for a type?
74+
75+
**A**: You're probably missing a fully-set-up Scheme. Schemes record the
76+
mapping between Go types and group-version-kinds in Kubernetes. In
77+
general, your application should have its own Scheme containing the types
78+
from the API groups that it needs (be they Kubernetes types or your own).
79+
See the [scheme builder
80+
docs](https://godoc.org/sigs.k8s.io/controller-runtime/pkg/scheme) for
81+
more information.

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ Contributors:
3434
* [Documentation Changes](/.github/PULL_REQUEST_TEMPLATE/docs.md)
3535
* [Test/Build/Other Changes](/.github/PULL_REQUEST_TEMPLATE/other.md)
3636

37+
## FAQ
38+
39+
See [FAQ.md](FAQ.md)
40+
3741
## Community, discussion, contribution, and support
3842

3943
Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/).

0 commit comments

Comments
 (0)