Skip to content
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

Closed
wants to merge 16 commits into from

Conversation

wallrj
Copy link
Contributor

@wallrj wallrj commented Apr 13, 2017

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

@k8s-ci-robot
Copy link
Contributor

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.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. label Apr 13, 2017
@k8s-reviewable
Copy link

This change is Reviewable

@k8s-ci-robot
Copy link
Contributor

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 @k8s-bot ok to test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

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.

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Apr 13, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: wallrj
We suggest the following additional approver: @smarterclayton

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@wallrj
Copy link
Contributor Author

wallrj commented Apr 13, 2017

I'm struggling to sign the CLA as an employee of jetstack.io.
The branch originally contained commits with my generic email github project email address wallrj@users.noreply.github.com but I've force pushed a new single commit using my jetstack.io address.
(I'm told that jetstack.io have completed the corporate CLA process for CNCF.)

@grodrigues3
Copy link
Contributor

@k8s-bot ok to test

@k8s-ci-robot k8s-ci-robot removed the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Apr 13, 2017
@caesarxuchao
Copy link
Member

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"
Copy link
Member

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.

Copy link
Contributor Author

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)
Copy link
Member

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?

Copy link
Contributor Author

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,
Copy link
Member

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.

Copy link
Contributor Author

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)
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Done.

return fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
}

func buildConfig(kubeconfig string) (*rest.Config, error) {
Copy link
Contributor

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)
Copy link
Contributor

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)
Copy link
Contributor

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)

@0xmichalis
Copy link
Contributor

0xmichalis commented Apr 21, 2017

@rmohr already added an example here

@caesarxuchao
Copy link
Member

@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?

@caesarxuchao
Copy link
Member

@wallrj a few commands you need to run to pass the verification script:

W0418 01:42:06.769] 1 BUILD files not up-to-date.
I0418 01:42:06.870] 
I0418 01:42:06.870] Run ./hack/update-bazel.sh
I0418 01:53:26.662] FAILED   hack/make-rules/../../hack/verify-golint.sh	37s
I0418 01:53:26.662] Skipping hack/make-rules/../../hack/verify-govet.sh
I0418 01:53:26.662] Verifying hack/make-rules/../../hack/verify-import-boss.sh
W0418 01:53:26.763] Some packages passed golint but are not listed in hack/.linted_packages.
W0418 01:53:26.763] Please add them in alphabetical order:
W0418 01:53:26.763] 
W0418 01:53:26.764]   echo staging/src/k8s.io/client-go/examples/informer >> hack/.linted_packages

Also, the CLA check is also failing, have you signed it?

@wallrj
Copy link
Contributor Author

wallrj commented May 2, 2017

Sorry for the delay. And thanks for the review @rmohr and @caesarxuchao.
I have now signed the CLA and I'll address your comments this week.

}

func (c *PodLoggingController) podDelete(obj interface{}) {
pod := obj.(*v1.Pod)
Copy link
Member

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,
Copy link
Member

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

Copy link
Contributor Author

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.
Copy link
Member

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

@ncdc
Copy link
Member

ncdc commented May 31, 2017

@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.

@krmayankk
Copy link

@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 :-)

@caesarxuchao
Copy link
Member

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
```

Copy link
Member

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)
Copy link
Member

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.

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 21, 2017
@k8s-github-robot k8s-github-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 31, 2017
@k8s-ci-robot
Copy link
Contributor

@wallrj: The following tests failed, say /retest to rerun them all:

Test name Commit Details Rerun command
pull-kubernetes-bazel a1e2777 link /test pull-kubernetes-bazel
pull-kubernetes-unit a1e2777 link /test pull-kubernetes-unit
pull-kubernetes-verify a1e2777 link /test pull-kubernetes-verify
pull-kubernetes-e2e-gce-etcd3 a1e2777 link /test pull-kubernetes-e2e-gce-etcd3

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.

@k8s-github-robot
Copy link

Adding do-not-merge/release-note-label-needed because the release note process has not been followed.
One of the following labels is required "release-note", "release-note-action-required", "release-note-experimental" or "release-note-none".
Please see: https://github.com/kubernetes/community/blob/master/contributors/devel/pull-requests.md#write-release-notes-if-needed.

@k8s-github-robot k8s-github-robot added the do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. label Aug 30, 2017
@k8s-github-robot
Copy link

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.

cc @caesarxuchao @wallrj

You can add 'keep-open' label to prevent this from happening again, or add a comment to keep it open another 90 days

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet