{"id":20832894,"url":"https://github.com/udhos/kubegroup","last_synced_at":"2025-05-08T01:40:46.129Z","repository":{"id":59045796,"uuid":"531311293","full_name":"udhos/kubegroup","owner":"udhos","description":"kubegroup provides autodiscovery for groupcache peer pods in kubernetes cluster","archived":false,"fork":false,"pushed_at":"2025-05-01T00:13:23.000Z","size":146,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-01T01:25:20.887Z","etag":null,"topics":["autodiscovery","go","golang","groupcache","kubernetes","pod"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/udhos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-09-01T00:53:16.000Z","updated_at":"2025-05-01T00:13:23.000Z","dependencies_parsed_at":"2024-02-13T04:29:30.018Z","dependency_job_id":"97e92334-e98e-4bbe-8273-99fd99eee225","html_url":"https://github.com/udhos/kubegroup","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udhos%2Fkubegroup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udhos%2Fkubegroup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udhos%2Fkubegroup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/udhos%2Fkubegroup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/udhos","download_url":"https://codeload.github.com/udhos/kubegroup/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252983761,"owners_count":21835758,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["autodiscovery","go","golang","groupcache","kubernetes","pod"],"created_at":"2024-11-18T00:13:36.274Z","updated_at":"2025-05-08T01:40:46.108Z","avatar_url":"https://github.com/udhos.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![license](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/udhos/kubegroup/blob/main/LICENSE)\n[![Go Report Card](https://goreportcard.com/badge/github.com/udhos/kubegroup)](https://goreportcard.com/report/github.com/udhos/kubegroup)\n[![Go Reference](https://pkg.go.dev/badge/github.com/udhos/kubegroup.svg)](https://pkg.go.dev/github.com/udhos/kubegroup)\n\n# kubegroup\n\n[kubegroup](https://github.com/udhos/kubegroup) provides peer autodiscovery for pods running [groupcache](https://github.com/mailgun/groupcache) within a kubernetes cluster.\n\nPeer pods are automatically discovered by continuously watching for other pods with the same label `app=\u003cvalue\u003e` as in the current pod, in current pod's namespace.\n\n# Metrics\n\n```\nkubegroup_peers: Gauge: Number of peer PODs discovered.\nkubegroup_events: Counter: Number of events received.\n```\n\n# Usage for groupcache3\n\nImport these packages.\n\n```go\nimport (\n\t\"github.com/groupcache/groupcache-go/v3\"\n\t\"github.com/groupcache/groupcache-go/v3/transport\"\n\t\"github.com/udhos/kube/kubeclient\"\n\t\"github.com/udhos/kubegroup/kubegroup\"\n)\n```\n\nInitialize groupcache3 and add kubegroup auto-discovery with `kubegroup.UpdatePeers()`.\n\n```go\ngroupcachePort := \":5000\"\n\n// 1. start groupcache3 daemon\n\nmyIP, errAddr := kubegroup.FindMyAddress()\nif errAddr != nil {\n  log.Fatalf(\"find my address: %v\", errAddr)\n}\n\nmyAddr := myIP + groupCachePort\n\ndaemon, errDaemon := groupcache.ListenAndServe(context.TODO(), myAddr, groupcache.Options{})\nif errDaemon != nil {\n  log.Fatalf(\"groupcache daemon: %v\", errDaemon)\n}\n\n// 2. spawn peering autodiscovery\n\nconst debug = true\n\nclientsetOpt := kubeclient.Options{DebugLog: debug}\nclientset, errClientset := kubeclient.New(clientsetOpt)\nif errClientset != nil {\n  log.Fatalf(\"kubeclient: %v\", errClientset)\n}\n\noptions := kubegroup.Options{\n  Client:                clientset,\n  Peers:                 daemon,\n  LabelSelector:         \"app=miniapi\",\n  GroupCachePort:        groupCachePort,\n  Debug:                 debug,\n  MetricsRegisterer:     prometheus.DefaultRegisterer,\n  MetricsGatherer:       prometheus.DefaultGatherer,\n}\n\ndiscoveryGroup, errDiscovery := kubegroup.UpdatePeers(options)\nif errDiscovery != nil {\n  log.Fatalf(\"kubegroup: %v\", errDiscovery)\n}\n\n// 3. create groupcache groups\n\nttl := time.Minute\n\ngetter := groupcache.GetterFunc(\n  func(_ context.Context, filePath string, dest transport.Sink) error {\n\n    log.Printf(\"cache miss, loading file: %s (ttl:%v)\",\n      filePath, ttl)\n\n    data, errRead := os.ReadFile(filePath)\n    if errRead != nil {\n      return errRead\n    }\n\n    var expire time.Time // zero value for expire means no expiration\n    if app.groupCacheExpire != 0 {\n      expire = time.Now().Add(ttl)\n    }\n\n    return dest.SetBytes(data, expire)\n  },\n)\n\ncache, errGroup := daemon.NewGroup(\"files\", 1_000_000, getter)\nif errGroup != nil {\n  log.Fatalf(\"new group: %v\", errGroup)\n}\n\n// 4. query cache\n\nvar data []byte\n\nerrGet := cache.Get(context.TODO(), \"filename.txt\", transport.AllocatingByteSliceSink(\u0026data))\nif errGet != nil {\n  log.Printf(\"cache error: %v\", errGet)\n} else {\n  log.Printf(\"cache response: %s\", string(data))\n}\n\n// 5. when you need to stop kubegroup auto-discovery\n\ndiscoveryGroup.Close() // release kubegroup resources\n```\n\n# Example for groupcache3\n\nSee [./examples/kubegroup-example3](./examples/kubegroup-example3)\n\n# Usage for groupcache2\n\nImport the package `github.com/udhos/kubegroup/kubegroup`.\n\n```go\nimport \"github.com/udhos/kubegroup/kubegroup\"\n```\n\nInitialize auto-discovery with `kubegroup.UpdatePeers()`.\n\n```go\ngroupcachePort := \":5000\"\n\n// 1. get my groupcache URL\nmyURL, errURL = kubegroup.FindMyURL(groupcachePort)\n\nworkspace := groupcache.NewWorkspace()\n\n// 2. spawn groupcache peering server\npool := groupcache.NewHTTPPoolOptsWithWorkspace(workspace, myURL, \u0026groupcache.HTTPPoolOptions{})\nserver := \u0026http.Server{Addr: groupcachePort, Handler: pool}\ngo func() {\n    log.Printf(\"groupcache server: listening on %s\", groupcachePort)\n    err := server.ListenAndServe()\n    log.Printf(\"groupcache server: exited: %v\", err)\n}()\n\n// 3. spawn peering autodiscovery\n\nclientset, errClientset := kubeclient.New(kubeclient.Options{})\nif errClientset != nil {\n  log.Fatalf(\"kubeclient: %v\", errClientset)\n}\n\noptions := kubegroup.Options{\n  Client:                clientset,\n  Pool:                  pool,\n  LabelSelector:         \"app=my-app\",\n  GroupCachePort:        groupCachePort,\n  MetricsRegisterer:     prometheus.DefaultRegisterer,\n  MetricsGatherer:       prometheus.DefaultGatherer,\n}\n\ngroup, errGroup := kubegroup.UpdatePeers(options)\nif errGroup != nil {\n  log.Fatalf(\"kubegroup: %v\", errGroup)\n}\n\n// 4. create groupcache groups, etc: groupOne := groupcache.NewGroup()\n\n// 5. before shutdown you might stop kubegroup to release resources\n\ngroup.Close() // release kubegroup resources\nserver.Shutdown(...) // do not forget to shutdown the peering server\n```\n\n# Example\n\nSee [./examples/kubegroup-example](./examples/kubegroup-example)\n\n# POD Permissions\n\nThe application PODs will need permissions to get/list/watch PODs against kubernetes API, as illustrated by the role below.\n\n## Role\n\n```yaml\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: role-name\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - 'pods'\n  verbs:\n  - 'get'\n  - 'list'\n  - 'watch'\n```\n\nExample chart template: https://github.com/udhos/gateboard/blob/main/charts/gateboard/templates/role.yaml\n\n## Role Binding\n\n```yaml\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: rolebinding-name\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: role-name\nsubjects:\n- kind: ServiceAccount\n  name: put-pod-service-account-here\n  namespace: put-pod-namespace-here\n```\n\nExample chart template: https://github.com/udhos/gateboard/blob/main/charts/gateboard/templates/rolebinding.yaml\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fudhos%2Fkubegroup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fudhos%2Fkubegroup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fudhos%2Fkubegroup/lists"}