{"id":21172431,"url":"https://github.com/reallyliri/kubescout","last_synced_at":"2026-02-23T21:47:48.901Z","repository":{"id":39702832,"uuid":"418121191","full_name":"ReallyLiri/kubescout","owner":"ReallyLiri","description":"Scout for alarming issues across your Kubernetes clusters","archived":false,"fork":false,"pushed_at":"2021-12-09T12:28:28.000Z","size":642,"stargazers_count":124,"open_issues_count":8,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-09T20:53:12.030Z","etag":null,"topics":["alert","alerting","docker","golang","kubernetes","kubernetes-monitoring","kubernetes-troubleshooting","monitoring","monitoring-tool"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ReallyLiri.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}},"created_at":"2021-10-17T12:14:45.000Z","updated_at":"2025-06-14T22:37:04.000Z","dependencies_parsed_at":"2022-07-13T12:10:48.914Z","dependency_job_id":null,"html_url":"https://github.com/ReallyLiri/kubescout","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/ReallyLiri/kubescout","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReallyLiri%2Fkubescout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReallyLiri%2Fkubescout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReallyLiri%2Fkubescout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReallyLiri%2Fkubescout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ReallyLiri","download_url":"https://codeload.github.com/ReallyLiri/kubescout/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReallyLiri%2Fkubescout/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267368932,"owners_count":24076093,"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","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["alert","alerting","docker","golang","kubernetes","kubernetes-monitoring","kubernetes-troubleshooting","monitoring","monitoring-tool"],"created_at":"2024-11-20T16:25:46.656Z","updated_at":"2026-02-23T21:47:48.870Z","avatar_url":"https://github.com/ReallyLiri.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kube-Scout\n\n[![Open Source Love](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/)\n[![CI](https://github.com/ReallyLiri/kubescout/actions/workflows/ci.yaml/badge.svg?)](https://github.com/ReallyLiri/kubescout/actions/workflows/ci.yaml)\n[![DockerBuild](https://github.com/ReallyLiri/kubescout/actions/workflows/docker-build.yaml/badge.svg?)](https://github.com/ReallyLiri/kubescout/actions/workflows/docker-build.yaml)\n[![Release](https://github.com/ReallyLiri/kubescout/actions/workflows/release.yaml/badge.svg?)](https://github.com/ReallyLiri/kubescout/actions/workflows/release.yaml)\n[![Go project version](https://badge.fury.io/go/github.com%2Freallyliri%2Fkubescout.svg?)](https://badge.fury.io/go/github.com%2Freallyliri%2Fkubescout)\n[![GoDoc](https://godoc.org/github.com/reallyliri/kubescout?status.svg)](https://pkg.go.dev/github.com/reallyliri/kubescout)\n[![Docker](https://img.shields.io/docker/v/reallyliri/kubescout?color=%232dd59f\u0026label=Docker)](https://hub.docker.com/repository/docker/reallyliri/kubescout)\n\n![icon](kubescout.png)\n\nAn alerting tool for Kubernetes clusters issues of all types, in real time, with intelligent redundancy, and easily\nextendable api.\n\n- [Kube-Scout](#kube-scout)\n    + [Output Example](#output-example-)\n\n    * [Problems Coverage and Roadmap](#problems-coverage-and-roadmap)\n    * [CLI](#cli)\n        + [Install](#install)\n    * [Monitoring Setup](#monitoring-setup)\n        + [Install using Helm](#install-using-helm)\n        + [Run as a Kubernetes Job](#run-as-a-kubernetes-job)\n        + [Run as a Kubernetes CronJob](#run-as-a-kubernetes-cronjob)\n        + [Run as Docker](#run-as-docker)\n        + [Native](#native)\n        + [Native Cronjob](#native-cronjob)\n        + [Go Package](#go-package)\n    * [Test and Build](#test-and-build)\n\n### Output Example\n\n```\nPod default/test-2-broken-image-7cbf974df9-gbnk9 is un-healthy:\nContainer test-2-broken-image still waiting due to ImagePullBackOff: Back-off pulling image \"nginx:l4t3st\"\nEvent by kubelet: Failed x4 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\n\tFailed to pull image \"nginx:l4t3st\": rpc error: code = Unknown desc = Error response from daemon: manifest for nginx:l4t3st not found: manifest unknown: manifest unknown\nEvent by kubelet: Failed x4 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\n\tError: ErrImagePull\nEvent by kubelet: Failed x6 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\n\tError: ImagePullBackOff\n----------------\nPod default/test-3-excessive-resources-699d58f55f-9gfft is un-healthy:\nUnschedulable: 0/1 nodes are available: 1 Insufficient memory. (last transition: 4 minutes ago)\nEvent by default-scheduler: FailedScheduling since 27 Oct 21 14:20 UTC (last seen 4 minutes ago):\n\t0/1 nodes are available: 1 Insufficient memory.\n----------------\nPod default/test-4-crashlooping-dbdd84589-jvplc is un-healthy:\nContainer test-4-crashlooping is in CrashLoopBackOff: restarted 5 times, last exit due to Error (exit code 1)\nEvent by kubelet: BackOff x7 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\n\tBack-off restarting failed container\nLogs of container test-4-crashlooping:\n--------\n1\n2\n3\n4\n5\n--------\n----------------\nPod default/test-5-completed-757685986-r4tg2 is un-healthy:\nContainer test-5-completed is in CrashLoopBackOff: restarted 5 times, last exit due to Completed (exit code 0)\nEvent by kubelet: BackOff x8 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\n\tBack-off restarting failed container\nLogs of container test-5-completed:\n--------\n1\n2\n3\n4\n5\n--------\n----------------\nPod default/test-6-crashlooping-init-644545f5b7-bsvrn is un-healthy:\nContainer test-6-crashlooping-init-container (init) is in CrashLoopBackOff: restarted 5 times, last exit due to Error (exit code 1)\ntest-6-crashlooping-init-container (init) terminated due to Error (exit code 1)\nContainer test-6-crashlooping-init-container (init) restarted 5 times\nEvent by kubelet: BackOff x8 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\n\tBack-off restarting failed container\nLogs of container test-6-crashlooping-init-container:\n--------\n1\n2\n3\n4\n5\n--------\n----------------\n```\n\nOr in json format:\n\n```json\n{\n  \"alerts_by_cluster_name\": {\n    \"minikube\": [\n      {\n        \"cluster_name\": \"minikube\",\n        \"namespace\": \"default\",\n        \"name\": \"test-2-broken-image-7cbf974df9-gbnk9\",\n        \"kind\": \"Pod\",\n        \"messages\": [\n          \"Container test-2-broken-image still waiting due to ErrImagePull: rpc error: code = Unknown desc = Error response from daemon: manifest for nginx:l4t3st not found: manifest unknown: manifest unknown\",\n          \"Container test-2-broken-image still waiting due to ImagePullBackOff: Back-off pulling image \\\"nginx:l4t3st\\\"\"\n        ],\n        \"events\": [\n          \"Event by kubelet: Failed x4 since 27 Oct 21 14:20 UTC (last seen 1 minute ago):\\n\\tFailed to pull image \\\"nginx:l4t3st\\\": rpc error: code = Unknown desc = Error response from daemon: manifest for nginx:l4t3st not found: manifest unknown: manifest unknown\",\n          \"Event by kubelet: Failed x4 since 27 Oct 21 14:20 UTC (last seen 1 minute ago):\\n\\tError: ErrImagePull\",\n          \"Event by kubelet: Failed x6 since 27 Oct 21 14:20 UTC (last seen 1 minute ago):\\n\\tError: ImagePullBackOff\"\n        ],\n        \"timestamp\": \"2021-10-27T14:24:21.181725Z\"\n      },\n      {\n        \"cluster_name\": \"minikube\",\n        \"namespace\": \"default\",\n        \"name\": \"test-3-excessive-resources-699d58f55f-9gfft\",\n        \"kind\": \"Pod\",\n        \"messages\": [\n          \"Unschedulable: 0/1 nodes are available: 1 Insufficient memory. (last transition: 3 minutes ago)\"\n        ],\n        \"events\": [\n          \"Event by default-scheduler: FailedScheduling since 27 Oct 21 14:20 UTC (last seen 3 minutes ago):\\n\\t0/1 nodes are available: 1 Insufficient memory.\"\n        ],\n        \"timestamp\": \"2021-10-27T14:24:21.181725Z\"\n      },\n      {\n        \"cluster_name\": \"minikube\",\n        \"namespace\": \"default\",\n        \"name\": \"test-4-crashlooping-dbdd84589-jvplc\",\n        \"kind\": \"Pod\",\n        \"messages\": [\n          \"Container test-4-crashlooping is in CrashLoopBackOff: restarted 5 times, last exit due to Error (exit code 1)\"\n        ],\n        \"events\": [\n          \"Event by kubelet: BackOff x7 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\\n\\tBack-off restarting failed container\"\n        ],\n        \"logs_by_container_name\": {\n          \"test-4-crashlooping\": \"1\\n2\\n3\\n4\\n5\"\n        },\n        \"timestamp\": \"2021-10-27T14:24:21.181725Z\"\n      },\n      {\n        \"cluster_name\": \"minikube\",\n        \"namespace\": \"default\",\n        \"name\": \"test-5-completed-757685986-r4tg2\",\n        \"kind\": \"Pod\",\n        \"messages\": [\n          \"Container test-5-completed is in CrashLoopBackOff: restarted 5 times, last exit due to Completed (exit code 0)\"\n        ],\n        \"events\": [\n          \"Event by kubelet: BackOff x8 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\\n\\tBack-off restarting failed container\"\n        ],\n        \"logs_by_container_name\": {\n          \"test-5-completed\": \"1\\n2\\n3\\n4\\n5\"\n        },\n        \"timestamp\": \"2021-10-27T14:24:21.181725Z\"\n      },\n      {\n        \"cluster_name\": \"minikube\",\n        \"namespace\": \"default\",\n        \"name\": \"test-6-crashlooping-init-644545f5b7-bsvrn\",\n        \"kind\": \"Pod\",\n        \"messages\": [\n          \"Container test-6-crashlooping-init-container (init) is in CrashLoopBackOff: restarted 5 times, last exit due to Error (exit code 1)\"\n        ],\n        \"events\": [\n          \"Event by kubelet: BackOff x8 since 27 Oct 21 14:20 UTC (last seen 2 minutes ago):\\n\\tBack-off restarting failed container\"\n        ],\n        \"logs_by_container_name\": {\n          \"test-6-crashlooping-init-container\": \"1\\n2\\n3\\n4\\n5\"\n        },\n        \"timestamp\": \"2021-10-27T14:24:21.181725Z\"\n      }\n    ]\n  }\n}\n```\n\n![slack](https://i.imgur.com/03yuM55.png)\n\n## Problems Coverage and Roadmap\n\n* \u0026check; Pod evictions\n    + _ Clean up\n* \u0026check; Pod stuck terminating\n    + _ Graceful clean up\n* \u0026check; Pod pending/unschedulable/pull-backoff\n* \u0026check; Pod stuck initializing\n* \u0026check; Pod excessively restating or crashloops\n* \u0026check; Logs of relevant containers when applicable\n* \u0026check; Node taints/unready\n* \u0026check; Warning events on any entity\n* _ Node excessive disk usage per fs partition\n* _ Node excessive process allocation\n* _ Node excessive inode allocation\n* Warning/errors in native logs\n    + _ Docker\n    + _ Containerd\n    + _ Kubelet\n    + _ System\n* _ Helm failures\n\n## CLI\n\n```\nNAME:\n   kubescout - 0.1.15 - Scout for alarming issues in your Kubernetes cluster\n\nUSAGE:\n   kubescout                    [optional flags]\n\nOPTIONS:\n   --verbose, --vv                        Verbose logging (default: false) [$VERBOSE]\n   --logs-tail value                      Specifies the logs tail length when reporting logs from a problematic pod, use 0 to disable log extraction (default: 250) [$LOGS_TAIL]\n   --events-limit value                   Maximum number of namespace events to fetch (default: 150) [$EVENTS_LIMIT]\n   --kubeconfig value, -k value           kubeconfig file path, defaults to env var KUBECONFIG or ~/.kube/config, can be omitted when running in cluster [$KUBECONFIG]\n   --time-format value, -f value          timestamp print format (default: \"02 Jan 06 15:04 MST\") [$TIME_FORMAT]\n   --locale value, -l value               timestamp print localization (default: \"UTC\") [$LOCALE]\n   --pod-creation-grace-sec value         grace period in seconds since pod creation before checking its statuses (default: 5) [$POD_CREATION_GRACE_SEC]\n   --pod-starting-grace-sec value         grace period in seconds since pod creation before alarming on non running states (default: 600) [$POD_STARTING_GRACE_SEC]\n   --pod-termination-grace-sec value      grace period in seconds since pod termination (default: 60) [$POD_TERMINATION_GRACE_SEC]\n   --pod-restart-grace-count value        grace count for pod restarts (default: 3) [$POD_RESTART_GRACE_COUNT]\n   --node-resource-usage-threshold value  node resources usage threshold (default: 0.85)\n   --exclude-ns value, -e value           namespaces to skip [$EXCLUDE_NS]\n   --include-ns value, -n value           namespaces to include (will skip any not listed if this option is used) [$INCLUDE_NS]\n   --dedup-minutes value, -d value        time in minutes to silence duplicate or already observed alerts, or 0 to disable deduplication (default: 60) [$DEDUP_MINUTES]\n   --store-filepath value, -s value       path to store file where state will be persisted or empty string to disable persistency (default: \"kube-scout.store.json\") [$STORE_FILEPATH]\n   --output value, -o value               output mode, one of pretty/json/yaml/discard (default: \"pretty\") [$OUTPUT_MODE]\n   --context value, -c value              context name to use from kubeconfig, defaults to current context\n   --not-in-cluster                       hint to scan out of cluster even if technically kubescout is running in a pod (default: false) [$NOT_IN_CLUSTER]\n   --all-contexts, -a                     iterate all kubeconfig contexts, 'context' flag will be ignored if this flag is set (default: false)\n   --exclude-contexts value               a comma separated list of kubeconfig context names to skip, only relevant if 'all-contexts' flag is set\n   --help, -h                             show help (default: false)\n   --version, -v                          print the version (default: false)\n```\n\nFor example:\n\n```bash\nkubescout --kubeconfig /root/.kube/config --name staging-cluster\nkubescout --exclude-ns kube-system\nkubescout --include-ns default,test,prod\nkubescout -n default -c aws-cluster\n```\n\n### Install\n\n```bash\ncurl -s https://raw.githubusercontent.com/reallyliri/kubescout/main/install.sh | sudo bash\n# or for a specific version:\ncurl -s https://raw.githubusercontent.com/reallyliri/kubescout/main/install.sh | sudo bash -s 0.1.0\n```\n\nIf that doesn't work, try:\n\n```bash\ncurl -s https://raw.githubusercontent.com/reallyliri/kubescout/main/install.sh -o install.sh\nsudo bash install.sh\n```\n\nthen run: `kubescout -h`\n\n## Monitoring Setup\n\nScout your cluster(s) on a schedule or on demand with the following setup options:\n\n### Install using Helm\n\n```bash\nhelm upgrade -i -n default kubescout ./chart\n```\n\nValues configuration examples:\n\n```bash\nhelm upgrade -i -f custom-values.yaml kubescout ./chart\nhelm upgrade -i \\\n  --set image.tag=\"$(go run . --version | cut -d\" \" -f 3)\" \\\n  --set run.mode=\"CronJob\" \\\n  --set run.cronJob.schedule=\"0 0 * * *\" \\\n  --set config.excludeNamespaces={kube-node-lease\\,kube-public\\,kube-system} \\\n  kubescout ./chart\n```\n\n### Run as a Kubernetes Job\n\nTo get the plain job manifests, you can render the Helm chart:\n\n```bash\nNAMESPACE=default\n\nhelm template \\\n  -n $NAMESPACE \\\n  --set image.tag=\"$(go run . --version | cut -d\" \" -f 3)\" \\\n  --set run.mode=\"Job\" \\\n  --set persistency.enable=false \\\n  kubescout ./chart \u003e kubescout-job.yaml\n\nkubectl apply -n $NAMESPACE -f kubescout-job.yaml\n```\n\n### Run as a Kubernetes CronJob\n\nTo get the plain cron-job manifests, you can render the Helm chart:\n\n```bash\nNAMESPACE=default\n\nhelm template \\\n  -n $NAMESPACE \\\n  --set image.tag=\"$(go run . --version | cut -d\" \" -f 3)\" \\\n  --set run.mode=\"CronJob\" \\\n  --set run.cronjob.schedule=\"* * * * *\" \\\n  kubescout ./chart \u003e kubescout-cronjob.yaml\n\nkubectl apply -n $NAMESPACE -f kubescout-cronjob.yaml\n```\n\n### Run as Docker\n\nAlpine based slim image that wraps the [CLI](#cli) and used by the Kubernetes solutions.\n\n```bash\ndocker run --rm -it reallyliri/kubescout:latest --help\n# or with actual kubeconfig\ndocker run --rm -it \\\n -v ${HOME}/.kube/config:/root/.kube/config \\\n reallyliri/kubescout:latest -a -o json\n```\n\nBuild yourself:\n\n```bash\ndocker build -t kubescout .\n# then run\ndocker run --rm -it kubescout --help\n```\n\n### Native\n\nSimply fetch/compile the binary and use the [CLI](#cli) with your required config options.\n\n### Native Cronjob\n\nQuick setup of the native binary in a cronjob should be simple enough.\n\nFor example, to scout [every 3 minutes](https://crontab.guru/every-3-minutes):\n\n```bash\nif ! crontab -l | grep kubescout \u003e/dev/null 2\u003e\u00261 ; then\n    (crontab -l ; echo \"*/3 * * * * kubescout --all-contexts --kubeconfig /root/.kube/config --dedup-minutes 180\") | crontab -\nfi\n```\n\n### Go Package\n\nYou can also use the tool as a package from your own code setup.\n\n```\ngo get github.com/reallyliri/kubescout\n```\n\n```go\npackage example\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\tkubescout \"github.com/reallyliri/kubescout/pkg\"\n\tkubescoutconfig \"github.com/reallyliri/kubescout/config\"\n\tkubescoutsink \"github.com/reallyliri/kubescout/sink\"\n\t\"net/http\"\n)\n\nfunc main() {\n\n\t// simple default execution:\n\t_ = kubescout.Scout(nil, nil)\n\n\t// example using Slack webhook as sink:\n\tcfg, _ := kubescoutconfig.DefaultConfig()\n\tcfg.KubeconfigFilePath = \"/root/configs/staging-kubeconfig\"\n\tsink, _ := kubescoutsink.CreateWebSink(\n\t\t\"https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX\",\n\t\tfunc() (http.RoundTripper, error) {\n\t\t\tskipVerifyTransport := http.DefaultTransport.(*http.Transport).Clone()\n\t\t\tskipVerifyTransport.TLSClientConfig = \u0026tls.Config{InsecureSkipVerify: true}\n\t\t\treturn skipVerifyTransport, nil\n\t\t},\n\t\tfunc(request *http.Request) error {\n\t\t\trequest.Header.Add(\"Content-Type\", \"application/json\")\n\t\t\treturn nil\n\t\t},\n\t\tfunc(response *http.Response, responseBody string) error {\n\t\t\tif responseBody != \"ok\" {\n\t\t\t\treturn fmt.Errorf(\"non-ok response from Slack: '%v'\", responseBody)\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t\tfalse,\n\t)\n\t_ = kubescout.Scout(cfg, sink)\n}\n```\n\n## Test and Build\n\n```bash\n# vet and lint\ngo vet\ndocker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:latest-alpine golangci-lint run --deadline=180s\n# tests\ngo test -v ./...\n# integration tests (requires minikube)\ngo test -v --tags=integration ./integration_test.go\n# build\nCGO_ENABLED=0 go build -o bin/kubescout-$(go run . --version | cut -d\" \" -f 3) .\n```\n\n![meme](https://i.imgur.com/9nRSxD0.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freallyliri%2Fkubescout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freallyliri%2Fkubescout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freallyliri%2Fkubescout/lists"}