Skip to content

Commit 0697e99

Browse files
committed
Docs for watching Kubernetes API objects from a controller.
1 parent 44fd909 commit 0697e99

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

docs/watching_kubernetes_resources.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Watching Kubernetes resources
2+
3+
## Run the sharedinformers to watch the types
4+
5+
Setup the informers and related objects that are shared across all controllers
6+
run by the controller manager. The following steps are done once per-controller-manager
7+
(go binary), not once per-controller (go package).
8+
9+
**Step 1:** If `pkg/controller/sharedinformer/informers.go` does not already exist, create it.
10+
11+
This is automatically created for you by `apiserver-boot` when creating a resource for
12+
releases alpha.18+.
13+
14+
**Step 2:** Enable watching Kubernetes types and initializing the ClientSet
15+
16+
This will require that the controller-manager and apiserver are run as aggregated
17+
with a core apiserver, as the controller-manager will be watch both core and custom
18+
types.
19+
20+
Setting this to true will also allow your controller to read/write to the core apiserver using the
21+
`ClientSet` passed into your controller's `Init` function through `si.KubernetesClientSet`.
22+
23+
```go
24+
// SetupKubernetesTypes registers the config for watching Kubernetes types
25+
func (si *SharedInformers) SetupKubernetesTypes() bool {
26+
return true
27+
}
28+
```
29+
30+
**Step 3:** Start the informers for the resources you want to watch
31+
32+
For each Kind you that want to get notified about when it is created/updated/deleted,
33+
`Run` a corresponding Informer in `StartAdditionalInformers`.
34+
35+
**Note:** If you want to watch Deployments, you do not need to start informers for all
36+
group/versions. You only need to watch 1 group/version and other Deployment group/versions
37+
will be converted to the group/version you are watching.
38+
39+
```go
40+
// StartAdditionalInformers starts watching Deployments
41+
func (si *SharedInformers) StartAdditionalInformers(shutdown <-chan struct{}) {
42+
go si.KubernetesFactory.Apps().V1beta1().Deployments().Informer().Run(shutdown)
43+
}
44+
```
45+
46+
## Register your controller with the informer
47+
48+
**Step 1:** Map the Kubernetes resource instance to the key of an instance of your resource
49+
50+
When receiving a notification for the Kubernetes resource (e.g. Deployment) you want
51+
to run the `Reconcile` loop for your resource instance that owns the Kubernetes resource.
52+
If you write an `OwnerReference` for each of the Kubernetes resources created by your resource,
53+
you may look at that field to find the key for your resource.
54+
55+
- Cast the argument to the type
56+
- **Note:** double check the group/version are consistent between
57+
- the informer you started in pkg/controller/sharedinformers/informers.go
58+
- the type you cast the argument to
59+
- the informer with which you register your reconcile loop (Step 2)
60+
61+
```go
62+
func (c *FooControllerImpl) DeploymentToFoo(i interface{}) (string, error) {
63+
d, _ := i.(*v1beta1.Deployment)
64+
log.Printf("Deployment update: %v", d.Name)
65+
if len(d.OwnerReferences) == 1 && d.OwnerReferences[0].Kind == "Foo" {
66+
return d.Namespace + "/" + d.OwnerReferences[0].Name, nil
67+
} else {
68+
// Not owned
69+
return "", nil
70+
}
71+
}
72+
```
73+
74+
**Step 2:** Register your resource Reconcile with the informer
75+
76+
In your controller init function tie it all together:
77+
- The sharedinformer you started that watches for events
78+
- The conversion from a Deployment to the key of your resource
79+
- The reconcile function that takes the key of one of your resources
80+
81+
```go
82+
func (c *FooControllerImpl) Init(
83+
config *rest.Config,
84+
si *sharedinformers.SharedInformers,
85+
reconcileKey func(key string) error) {
86+
...
87+
si.Watch(
88+
"FooDeployment",
89+
si.KubernetesFactory.Extensions().V1beta1().Deployments().Informer(),
90+
c.DeploymentToFoo, reconcileKey)
91+
}
92+
```
93+
94+
### Create/delete/update the Kubernetes from your controller reconcile loop
95+
96+
Use the si.KubernetesClientSet from within your controllers `Reconcile` function
97+
to update Kubernetes objects.
98+
99+
**Note**: Consider using a `Lister` for reading and indexing cached objects to reduce load
100+
on the apiserver.

0 commit comments

Comments
 (0)