入门 k8s client-go informer 和 events
https://gitee.com/zongzw/client-go-helloworld所有代码示例及运行方式都在这个链接中。网上讲解 informer和events原理的文章很多,但缺少入门级的使用示例,所以,我把它总结为代码,供初学者上手,先有个感性认识再说别的。...
·
https://gitee.com/zongzw/client-go-helloworld
所有代码示例及运行方式都在这个链接中。
网上讲解 informer和events原理的文章很多,但缺少入门级的使用示例,所以,我把它总结为代码,供初学者上手,先有个感性认识再说别的。
main.go
package main
import (
"fmt"
"os"
"os/signal"
"time"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/events"
)
// 处理信号,并及时关闭stopCh
func handleSignals(stopCh chan struct{}) {
chSigs = make(chan os.Signal)
signal.Notify(chSigs, os.Interrupt)
<-chSigs
close(stopCh)
}
var (
stopCh chan struct{}
chSigs chan os.Signal
cfgInformer cache.SharedIndexInformer
recorder events.EventRecorder
)
func main() {
stopCh = make(chan struct{})
go handleSignals(stopCh)
if len(os.Args) != 2 {
fmt.Println("Usage: <program> <kube.config>")
return
}
// 创建clientset,共informer和events 共用。
kubeConf := os.Args[1]
config, err := clientcmd.BuildConfigFromFlags("", kubeConf)
if nil != err {
panic(err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
// Labelselector可以用来过滤仅需要关注的资源
// matchLabelSelector := func(opts *metav1.ListOptions) {
// // opts.LabelSelector = "somelabel=xyz"
// }
sharedInformerFactory := informers.NewSharedInformerFactoryWithOptions(
clientset,
30*time.Second,
informers.WithNamespace("default"), // for test: limit resource scope to default.
// informers.WithTweakListOptions(matchLabelSelector),
)
// 创建针对configmap的informer
cfgInformer = sharedInformerFactory.Core().V1().ConfigMaps().Informer()
// 为informer添加处理函数
cfgInformer.AddEventHandler(&cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
abc := obj.(*v1.ConfigMap)
fmt.Printf("add %s %s\n", abc.Namespace, abc.Name)
recorder.Eventf(abc, nil, v1.EventTypeNormal, "Deployed", "", "object addition has been notified by informer")
},
UpdateFunc: func(old, cur interface{}) {
orig := old.(*v1.ConfigMap)
newa := cur.(*v1.ConfigMap)
if orig.GetUID() != newa.GetUID() || orig.GetResourceVersion() != newa.GetResourceVersion() {
fmt.Printf("%s %s -> %s %s\n", orig.Namespace, orig.Name, newa.Namespace, newa.Name)
recorder.Eventf(newa, nil, v1.EventTypeNormal, "Deployed", "", "object update has been notified by informer")
}
},
DeleteFunc: func(obj interface{}) {
abc := obj.(*v1.ConfigMap)
fmt.Printf("delete %s %s\n", abc.Namespace, abc.Name)
recorder.Eventf(abc, nil, v1.EventTypeNormal, "Deployed", "", "object deletion has been notified by informer")
},
})
// 创建EventRecorder 过程。
eba := events.NewEventBroadcasterAdapter(clientset)
recorder = eba.NewRecorder("my-event-recorder")
// 开始工作
eba.StartRecordingToSink(stopCh)
sharedInformerFactory.Start(stopCh)
doNilLoop()
}
func doNilLoop() {
for {
select {
case <-stopCh:
return
case <-time.After(1 * time.Second):
// do nothing
}
}
}
编译文件Makefile
# 编译两个平台的二进制静态文件,即不链接任何动态链接库。
binary_build:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -ldflags '-s -w --extldflags "-static -fpic"' -o test-standalone-linux; \
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 \
go build -ldflags '-s -w --extldflags "-static -fpic"' -o test-standalone-darwin
制作docker image启动:Dockerfile
# docker build -t test-standalone:latest -f Dockerfile .
# 因为编译出来的test-standalone-linux 不存在外部依赖,我们可以使用alpine:latest
# 作为base image,这样做出来的docker image只有40.3MB
FROM alpine:latest
COPY test-standalone-linux /
# 默认使用/kube.config 作为启动参数,详见程序实现main.go 和 docker-compose.yml 的卷部分volumes
CMD ["/test-standalone-linux", "/kube.config"]
运行示例及展示效果:docker-compose.yml
version: '3'
services:
test-standalone:
image: test-standalone:latest
volumes:
- /Users/zong/.kube/config:/kube.config
# 启动方式:
# docker-compose up -d --remove-orphans --force-recreate
# 之后,可以使用 docker logs查看日志
# docker logs -f client-go-helloworld_test-standalone_1
# 当我们使用以下命令和文件创建新的configmap的时候,就可以看到docker logs输出的日志。
# $ kubectl apply -f test.yaml
# 日志如下
# add default cm-canary-template-configmap
# delete default cm-canary-template-configmap
# 在k8s的event中也可以看到相关的时间报告。
# $ kubectl get events
# LAST SEEN TYPE REASON OBJECT MESSAGE
# 50s Normal Deployed configmap/cm-canary object addition has been notified by informer
# 43s Normal Deployed configmap/cm-canary object deletion has been notified by informer
测试用test.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-canary
namespace: default
data:
template: "abcdef"
更多推荐
已为社区贡献4条内容
所有评论(0)