-
Notifications
You must be signed in to change notification settings - Fork 38.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an Informer example in client-go #44446
Conversation
Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please follow instructions at https://github.com/kubernetes/kubernetes/wiki/CLA-FAQ to sign the CLA. It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Hi @wallrj. Thanks for your PR. I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: wallrj
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
1d601f8
to
32faf96
Compare
I'm struggling to sign the CLA as an employee of jetstack.io. |
@k8s-bot ok to test |
FWIW, #44320 adds an example showing how to use workqueue together with informer. Its emphasis is on the use of the workqueue. |
"k8s.io/client-go/tools/clientcmd" | ||
|
||
// Only required to authenticate against GKE clusters | ||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we keep this line but comment it out? This line recursively introduces a huge dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
s := <-signals | ||
fmt.Printf("received signal %#v, exiting...\n", s) | ||
close(stop) | ||
os.Exit(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why os.Exit(0) is needed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the intent was to exit with status 0 after handling SIGINT.
Default behaviour is to exit with 1.
I agree though, it distracts from the Informer code.
Removed.
source := cache.NewListWatchFromClient( | ||
clientset.Core().RESTClient(), | ||
"pods", | ||
api.NamespaceAll, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be a versioned package like meta/v1 or api/v1? They also have this constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
panic(err) | ||
} | ||
|
||
stop := make(chan struct{}, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't have to be buffered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Done.
32faf96
to
ddd9f5f
Compare
return fmt.Sprintf("%s/%s", pod.Namespace, pod.Name) | ||
} | ||
|
||
func buildConfig(kubeconfig string) (*rest.Config, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This helper method is not needed, BuildConfigFromFlags
, checks if a masterUrl
or a kubeconfigPath
is set. If both are unset, it assumes that it is running from inside the cluster.
// Create the client config. Use kubeconfig if given, otherwise assume in-cluster. | ||
config, err := buildConfig(*kubeconfig) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use glog.Fatal(err)
|
||
clientset, err := kubernetes.NewForConfig(config) | ||
if err != nil { | ||
panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use glog.Fatal(err)
@Kargakis the one you linked to emphasis more on the workqueue and is more complex. I think it doesn't hurt to have a simpler example of how to use informer alone. WDYT? |
@wallrj a few commands you need to run to pass the verification script:
Also, the CLA check is also failing, have you signed it? |
Sorry for the delay. And thanks for the review @rmohr and @caesarxuchao. |
} | ||
|
||
func (c *PodLoggingController) podDelete(obj interface{}) { | ||
pod := obj.(*v1.Pod) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be a cache.DeletedFinalStateUnknown
, so you'll need to check for that as well. If you grep in pkg/controller, you'll find examples.
clientset := fake.NewSimpleClientset(tc.initial...) | ||
factory := informers.NewSharedInformerFactory( | ||
clientset, | ||
time.Hour*24, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also just do 0 for no resync
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
// Type conversion + type assertion? Is this the only way? | ||
p := interface{}(podToAdd).(*v1.Pod) | ||
// XXX: I expected this to trigger the | ||
// cache.ResourceEventHandlerFuncs but it doesn't. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The informer does a list, followed by a watch. The list will only return what's initially known by the fake clientset (tc.initial
). If you want to trigger the event handler functions after the initial list has completed, you'll have to use a fake watch, such as:
fakeWatch := watch.NewFake()
clientset.PrependWatchReactor("pods", core.DefaultWatchReactor(fakeWatch, nil)) // core = "k8s.io/client-go/testing"
fakeWatch.Add(&newPod)
// confirm that the event handler fired
@wallrj I added a line comment showing you how to use the fake watch to get the event handler functions to fire. Let me know if you need more help. |
@ncdc @caesarxuchao i wouldn't block on a great example if this would help a lot of people using the informer. This is an example code. i am guessing @wallrj would loose motivation at some point :-) |
Sorry i'm working on 1.7 release items. I'll try to take another look this week. |
```sh | ||
go run main.go -kubeconfig=$HOME/.kube/config -logtostderr | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain what happens when someone runs this program? Example of this is at: https://github.com/kubernetes/client-go/tree/master/examples/create-update-delete-deployment We're trying to keep READMEs of all the client examples similar to each other.
* Building controllers that coordinate other resources. | ||
Most controllers in [k8s.io/kubernetes/pkg/controller](https://godoc.org/k8s.io/kubernetes/pkg/controller) use informers. | ||
* Capturing resource events for logging to external systems | ||
(e.g. monitor non-"Normal" events and publish metrics to a time series database) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a ## Cleanup
section people can run to clean up the artifacts created by running this example? (For instance: https://github.com/kubernetes/client-go/tree/master/examples/create-update-delete-deployment or https://github.com/kubernetes/client-go/tree/master/examples/in-cluster has this section).
This will help us keep the README files for each client-go example similar.
@wallrj: The following tests failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Adding do-not-merge/release-note-label-needed because the release note process has not been followed. |
This PR hasn't been active in 90 days. Closing this PR. Please reopen if you would like to work towards merging this change, if/when the PR is ready for the next round of review. You can add 'keep-open' label to prevent this from happening again, or add a comment to keep it open another 90 days |
This PR adds an example demonstrating how to use the client-go library to set up an Informer to print out Pod events and to maintain a local store containing Pod configuration synchronized with the Kubernetes API server.
I've copied the work started in kubernetes/client-go#30 and addressed most of the outstanding code review comments:
kubernetes/client-go#30