|
| 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. |
0 commit comments