Skip to content

Commit 645e1f5

Browse files
committed
Update godocs after refactor
1 parent 5a1df6f commit 645e1f5

File tree

8 files changed

+289
-163
lines changed

8 files changed

+289
-163
lines changed

pkg/controller/controller.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ type Controller interface {
5454
Start(stop <-chan struct{}) error
5555
}
5656

57-
// New returns a new Controller registered with mrg.
57+
// New returns a new Controller registered with the Manager. The Manager will ensure that shared Caches have
58+
// been synced before the Controller is Started.
5859
func New(name string, mrg manager.Manager, options Options) (Controller, error) {
5960
if options.Reconcile == nil {
6061
return nil, fmt.Errorf("must specify Reconcile")

pkg/controller/doc.go

+5-158
Original file line numberDiff line numberDiff line change
@@ -15,165 +15,12 @@ limitations under the License.
1515
*/
1616

1717
/*
18-
Package controller provides libraries for building Controllers. Controllers implement Kubernetes APIs
19-
and are central to building Operators, Workload APIs, Configuration APIs, Autoscalers, and more.
18+
Package controller provides types and functions for building Controllers.
2019
21-
Controllers
20+
Creation
2221
23-
Controllers are work queues that enqueue work in response to source.Source events (e.g. Pod Create, Update, Delete)
24-
and trigger reconcile.Reconcile functions when the work is dequeued.
25-
26-
Unlike http handlers, Controllers DO NOT perform work directly in response to events, but instead enqueue
27-
reconcile.Requests so the work is performed eventually.
28-
29-
* Controllers run reconcile.Reconcile functions against objects (provided as name / Namespace).
30-
31-
* Controllers enqueue reconcile.Requests in response events provided by source.Sources.
32-
33-
reconcile
34-
35-
reconcile.Reconcile is a function that may be called at anytime with the name / Namespace of an
36-
object. When called, it will ensure that the state of the system matches what is specified in the object at the
37-
time reconcile is called.
38-
39-
Example: reconcile is run against a ReplicationController object. The ReplicationController specifies 5 replicas.
40-
3 Pods exist in the system. reconcile creates 2 more Pods and sets their OwnerReference to point at the
41-
ReplicationController.
42-
43-
* reconcile works on a single object type. - e.g. it will only reconcile ReplicaSets.
44-
45-
* reconcile is triggered by a reconcile.Request containing the name / Namespace of an object to reconcile.
46-
47-
* reconcile does not care about the event contents or event type triggering the reconcile.Request.
48-
- e.g. it doesn't matter whether a ReplicaSet was created or updated, reconcile will check that the correct
49-
Pods exist either way.
50-
51-
* Users MUST implement reconcile themselves.
52-
53-
Source
54-
55-
resource.Source provides a stream of events. Events may be internal events from watching Kubernetes
56-
APIs (e.g. Pod Create, Update, Delete), or may be synthetic Generic events triggered by cron or WebHooks
57-
(e.g. through a Slackbot or GitHub callback).
58-
59-
Example 1: source.KindSource uses the Kubernetes API Watch endpoint for a GroupVersionKind to provide
60-
Create, Update, Delete events.
61-
62-
Example 2: source.ChannelSource reads Generic events from a channel fed by a WebHook called from a Slackbot.
63-
64-
* Source provides a stream of events for EventHandlers to handle.
65-
66-
* Source may provide either events from Watches (e.g. object Create, Update, Delete) or Generic triggered
67-
from another source (e.g. WebHook callback).
68-
69-
* Users SHOULD use the provided Source implementations instead of implementing their own for nearly all cases.
70-
71-
EventHandler
72-
73-
eventhandler.EventHandler transforms and enqueues events from a source.Source into reconcile.Requests.
74-
75-
Example: a Pod Create event from a Source is provided to the eventhandler.EnqueueHandler, which enqueues a
76-
reconcile.Request containing the name / Namespace of the Pod.
77-
78-
* EventHandler takes an event.Event and enqueues reconcile.Requests
79-
80-
* EventHandlers MAY map an event for an object of one type to a reconcile.Request for an object of another type.
81-
82-
* EventHandlers MAY map an event for an object to multiple reconcile.Requests for different objects.
83-
84-
* Users SHOULD use the provided EventHandler implementations instead of implementing their own for almost all cases.
85-
86-
Predicate
87-
88-
predicate.Predicate allows events to be filtered before they are given to EventHandlers. This allows common
89-
filters to be reused and composed together with EventHandlers.
90-
91-
* Predicate takes and event.Event and returns a bool (true to enqueue)
92-
93-
* Predicates are optional
94-
95-
* Users SHOULD use the provided Predicate implementations, but MAY implement their own Predicates as needed.
96-
97-
PodController Diagram
98-
99-
Source provides event:
100-
101-
* &source.KindSource{"core", "v1", "Pod"} -> (Pod foo/bar Create Event)
102-
103-
EventHandler enqueues Request:
104-
105-
* &eventhandler.Enqueue{} -> (reconcile.Request{"foo", "bar"})
106-
107-
Reconcile is called with the Request:
108-
109-
* Reconcile(reconcile.Request{"foo", "bar"})
110-
111-
112-
controllerManager
113-
114-
controllerManager registers and starts Controllers. It initializes shared dependencies - such as clients, caches,
115-
stop channels, etc and provides these to the Controllers that it manages. controllerManager should be used
116-
anytime multiple Controllers exist within the same program.
117-
118-
Usage
119-
120-
The following example shows creating a new Controller program which Reconciles ReplicaSet objects in response
121-
to Pod or ReplicaSet events. The Reconcile function simply adds a label to the ReplicaSet.
122-
123-
See the example/main.go for a usage example.
124-
125-
Controller Example
126-
127-
1. Watch ReplicaSet and Pods Sources
128-
129-
1.1 ReplicaSet -> eventhandler.EnqueueHandler - enqueue the ReplicaSet Namespace and Name.
130-
131-
1.2 Pod (created by ReplicaSet) -> eventhandler.EnqueueOwnerHandler - enqueue the Owning ReplicaSet key.
132-
133-
2. reconcile ReplicaSet
134-
135-
2.1 ReplicaSet object created -> Read ReplicaSet, try to read Pods -> if is missing create Pods.
136-
137-
2.2 reconcile triggered by creation of Pods -> Read ReplicaSet and Pods, do nothing.
138-
139-
2.3 reconcile triggered by deletion of Pods -> Read ReplicaSet and Pods, create replacement Pods.
140-
141-
Watching and EventHandling
142-
143-
Controllers may Watch multiple Kinds of objects (e.g. Pods, ReplicaSets and Deployments), but they should
144-
enqueue keys for only a single Type. When one Type of object must be be updated in response to changes
145-
in another Type of object, an EnqueueMappedHandler may be used to reconcile the Type that is being
146-
updated and watch the other Type for Events. e.g. Respond to a cluster resize
147-
Event (add / delete Node) by re-reconciling all instances of another Type that cares about the cluster size.
148-
149-
For example, a Deployment controller might use an EnqueueHandler and EnqueueOwnerHandler to:
150-
151-
* Watch for Deployment Events - enqueue the key of the Deployment.
152-
153-
* Watch for ReplicaSet Events - enqueue the key of the Deployment that created the ReplicaSet (e.g the Owner)
154-
155-
Note: reconcile.Requests are deduplicated when they are enqueued. Many Pod Events for the same ReplicaSet
156-
may trigger only 1 reconcile invocation as each Event results in the Handler trying to enqueue
157-
the same reconcile.Request for the ReplicaSet.
158-
159-
Controller Writing Tips
160-
161-
Reconcile Runtime Complexity:
162-
163-
* It is better to write Controllers to perform an O(1) reconcile N times (e.g. on N different objects) instead of
164-
performing an O(N) reconcile 1 time (e.g. on a single object which manages N other objects).
165-
166-
* Example: If you need to update all Services in response to a Node being added - reconcile Services but Watch
167-
Node events (transformed to Service object name / Namespaces) instead of Reconciling the Node and updating all
168-
Services from a single reconcile.
169-
170-
Event Multiplexing:
171-
172-
* reconcile.Requests for the same name / Namespace are deduplicated when they are enqueued. This allows
173-
for Controllers to gracefully handle event storms for a single object. Multiplexing multiple event Sources to
174-
a single object type takes advantage of this.
175-
176-
* Example: Pod events for a ReplicaSet are transformed to a ReplicaSet name / Namespace, so the ReplicaSet
177-
will be Reconciled only 1 time for multiple Pods.
22+
To create a new Controller, first create a manager.Manager and provide it to New. The Manager will
23+
take care of Starting / Stopping the Controller, as well as provide shared Caches and Clients to the
24+
Sources, EventHandlers, Predicates, and Reconcile.
17825
*/
17926
package controller

pkg/controller/example_test.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,21 @@ import (
3030

3131
var mrg manager.Manager
3232

33-
// This example creates a new controller named "pod-controller" with a no-op reconcile function and registers
33+
// This example creates a new Controller named "pod-controller" with a no-op reconcile function. The
34+
// manager.Manager will be used to Start the Controller, and will provide it a shared Cache and Client.
35+
func ExampleNew() {
36+
_, err := controller.New("pod-controller", mrg, controller.Options{
37+
Reconcile: reconcile.Func(func(o reconcile.Request) (reconcile.Result, error) {
38+
// Your business logic to implement the API by creating, updating, deleting objects goes here.
39+
return reconcile.Result{}, nil
40+
}),
41+
})
42+
if err != nil {
43+
log.Fatal(err)
44+
}
45+
}
46+
47+
// This example creates a new Controller named "pod-controller" with a no-op reconcile function and registers
3448
// it with the DefaultControllerManager.
3549
func ExampleController() {
3650
_, err := controller.New("pod-controller", mrg, controller.Options{

pkg/doc.go

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
/*
18+
Package pkg provides libraries for building Controllers. Controllers implement Kubernetes APIs
19+
and are central to building Operators, Workload APIs, Configuration APIs, Autoscalers, and more.
20+
21+
Client
22+
23+
Client provides a Read / Write client for reading and writing objects to an apiserver.
24+
25+
Cache
26+
27+
Cache provides a Read client for reading objects from an apiserver that are stored in a local cache.
28+
Cache supports registering handlers to respond to events that update the cache.
29+
30+
Manager
31+
32+
Manager provides a mechanism for Starting components and provides shared Caches and Clients to the components.
33+
34+
Controller
35+
36+
Controller is a work queue that enqueues work in response to source.Source events (e.g. Pod Create, Update, Delete)
37+
and triggers reconcile.Reconcile functions when the work is dequeued.
38+
39+
Unlike http handlers, Controllers DO NOT perform work directly in response to events, but instead enqueue
40+
reconcile.Requests so the work is performed eventually.
41+
42+
* Controllers run reconcile.Reconcile functions against objects (provided as name / Namespace).
43+
44+
* Controllers enqueue reconcile.Requests in response events provided by source.Sources.
45+
46+
Reconcile
47+
48+
reconcile.Reconcile is a function that may be called at anytime with the Name and Namespace of an
49+
object. When called, it will ensure that the state of the system matches what is specified in the object at the
50+
time Reconcile is called.
51+
52+
Example: Reconcile is run against a ReplicationController object. The ReplicationController specifies 5 replicas.
53+
3 Pods exist in the system. Reconcile creates 2 more Pods and sets their OwnerReference to point at the
54+
ReplicationController.
55+
56+
* reconcile works on a single object type. - e.g. it will only reconcile ReplicaSets.
57+
58+
* reconcile is triggered by a reconcile.Request containing the name / Namespace of an object to reconcile.
59+
60+
* reconcile does not care about the event contents or event type triggering the reconcile.Request.
61+
- e.g. it doesn't matter whether a ReplicaSet was created or updated, reconcile will check that the correct
62+
Pods exist either way.
63+
64+
* Users MUST implement Reconcile for Controllers.
65+
66+
Source
67+
68+
resource.Source provides a stream of events. Events may be internal events from watching Kubernetes
69+
APIs (e.g. Pod Create, Update, Delete), or may be synthetic Generic events triggered by cron or WebHooks
70+
(e.g. through a Slackbot or GitHub callback).
71+
72+
Example 1: source.Kind uses the Kubernetes API Watch endpoint for a GroupVersionKind to provide
73+
Create, Update, Delete events.
74+
75+
Example 2: source.Channel reads Generic events from a channel fed by a WebHook called from a Slackbot.
76+
77+
* source provides a stream of events for EventHandlers to handle.
78+
79+
* source may provide either events from Watches (e.g. object Create, Update, Delete) or Generic triggered
80+
from another source (e.g. WebHook callback).
81+
82+
* Users SHOULD use the provided Source implementations instead of implementing their own for nearly all cases.
83+
84+
EventHandler
85+
86+
eventhandler.EventHandler maps from a source.Source into reconcile.Requests which are enqueued as work for the
87+
Controller.
88+
89+
Example: a Pod Create event from a Source is provided to the eventhandler.EnqueueHandler, which enqueues a
90+
reconcile.Request containing the name / Namespace of the Pod.
91+
92+
* EventHandler takes an event.Event and enqueues reconcile.Requests
93+
94+
* EventHandlers MAY map an event for an object of one type to a reconcile.Request for an object of another type.
95+
96+
* EventHandlers MAY map an event for an object to multiple reconcile.Requests for different objects.
97+
98+
* Users SHOULD use the provided EventHandler implementations instead of implementing their own for almost all cases.
99+
100+
Predicate
101+
102+
predicate.Predicate allows events to be filtered before they are given to EventHandlers. This allows common
103+
filters to be reused and composed together with EventHandlers.
104+
105+
* Predicate takes and event.Event and returns a bool (true to enqueue)
106+
107+
* Predicates are optional
108+
109+
* Users SHOULD use the provided Predicate implementations, but MAY implement their own Predicates as needed.
110+
111+
PodController Diagram
112+
113+
Source provides event:
114+
115+
* &source.KindSource{"core", "v1", "Pod"} -> (Pod foo/bar Create Event)
116+
117+
EventHandler enqueues Request:
118+
119+
* &eventhandler.Enqueue{} -> (reconcile.Request{"foo", "bar"})
120+
121+
Reconcile is called with the Request:
122+
123+
* Reconcile(reconcile.Request{"foo", "bar"})
124+
125+
Usage
126+
127+
The following example shows creating a new Controller program which Reconciles ReplicaSet objects in response
128+
to Pod or ReplicaSet events. The Reconcile function simply adds a label to the ReplicaSet.
129+
130+
See the example/main.go for a usage example.
131+
132+
Controller Example
133+
134+
1. Watch ReplicaSet and Pods Sources
135+
136+
1.1 ReplicaSet -> eventhandler.EnqueueHandler - enqueue the ReplicaSet Namespace and Name.
137+
138+
1.2 Pod (created by ReplicaSet) -> eventhandler.EnqueueOwnerHandler - enqueue the Owning ReplicaSet key.
139+
140+
2. Reconcile ReplicaSet
141+
142+
2.1 ReplicaSet object created -> Read ReplicaSet, try to read Pods -> if is missing create Pods.
143+
144+
2.2 reconcile triggered by creation of Pods -> Read ReplicaSet and Pods, do nothing.
145+
146+
2.3 reconcile triggered by deletion of Pods -> Read ReplicaSet and Pods, create replacement Pods.
147+
148+
Watching and EventHandling
149+
150+
Controllers may Watch multiple Kinds of objects (e.g. Pods, ReplicaSets and Deployments), but they should
151+
enqueue keys for only a single Type. When one Type of object must be be updated in response to changes
152+
in another Type of object, an EnqueueMappedHandler may be used to reconcile the Type that is being
153+
updated and watch the other Type for Events. e.g. Respond to a cluster resize
154+
Event (add / delete Node) by re-reconciling all instances of another Type that cares about the cluster size.
155+
156+
For example, a Deployment controller might use an EnqueueHandler and EnqueueOwnerHandler to:
157+
158+
* Watch for Deployment Events - enqueue the key of the Deployment.
159+
160+
* Watch for ReplicaSet Events - enqueue the key of the Deployment that created the ReplicaSet (e.g the Owner)
161+
162+
Note: reconcile.Requests are deduplicated when they are enqueued. Many Pod Events for the same ReplicaSet
163+
may trigger only 1 reconcile invocation as each Event results in the Handler trying to enqueue
164+
the same reconcile.Request for the ReplicaSet.
165+
166+
Controller Writing Tips
167+
168+
Reconcile Runtime Complexity:
169+
170+
* It is better to write Controllers to perform an O(1) reconcile N times (e.g. on N different objects) instead of
171+
performing an O(N) reconcile 1 time (e.g. on a single object which manages N other objects).
172+
173+
* Example: If you need to update all Services in response to a Node being added - reconcile Services but Watch
174+
Node events (transformed to Service object name / Namespaces) instead of Reconciling the Node and updating all
175+
Services from a single reconcile.
176+
177+
Event Multiplexing:
178+
179+
* reconcile.Requests for the same name / Namespace are deduplicated when they are enqueued. This allows
180+
for Controllers to gracefully handle event storms for a single object. Multiplexing multiple event Sources to
181+
a single object type takes advantage of this.
182+
183+
* Example: Pod events for a ReplicaSet are transformed to a ReplicaSet name / Namespace, so the ReplicaSet
184+
will be Reconciled only 1 time for multiple Pods.
185+
*/
186+
package pkg

0 commit comments

Comments
 (0)