{"id":13645548,"url":"https://github.com/digitalocean/clusterlint","last_synced_at":"2025-06-11T01:09:06.099Z","repository":{"id":39542475,"uuid":"191230466","full_name":"digitalocean/clusterlint","owner":"digitalocean","description":"A best practices checker for Kubernetes clusters. 🤠","archived":false,"fork":false,"pushed_at":"2025-05-21T16:29:53.000Z","size":16011,"stargazers_count":564,"open_issues_count":11,"forks_count":45,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-05-21T17:25:34.819Z","etag":null,"topics":["best-practices","hacktoberfest","kubernetes","linter"],"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/digitalocean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2019-06-10T19:12:29.000Z","updated_at":"2025-05-21T16:29:56.000Z","dependencies_parsed_at":"2023-02-18T11:04:10.981Z","dependency_job_id":"65a79215-5e15-4b94-b6ec-eda63a1898f7","html_url":"https://github.com/digitalocean/clusterlint","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fclusterlint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fclusterlint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fclusterlint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fclusterlint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalocean","download_url":"https://codeload.github.com/digitalocean/clusterlint/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fclusterlint/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259178519,"owners_count":22817388,"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":["best-practices","hacktoberfest","kubernetes","linter"],"created_at":"2024-08-02T01:02:37.023Z","updated_at":"2025-06-11T01:09:06.045Z","avatar_url":"https://github.com/digitalocean.png","language":"Go","funding_links":[],"categories":["Go","Other","Configuration Management"],"sub_categories":[],"readme":"# Clusterlint\n\n[![CircleCI](https://circleci.com/gh/digitalocean/clusterlint.svg?style=svg)](https://circleci.com/gh/digitalocean/clusterlint)\n\nAs clusters scale and become increasingly difficult to maintain, clusterlint helps operators conform to Kubernetes best practices around resources, security and reliability to avoid common problems while operating or upgrading the clusters.\n\nClusterlint queries live Kubernetes clusters for resources, executes common and platform specific checks against these resources and provides actionable feedback to cluster operators.  It is a non invasive tool that is run externally. Clusterlint does not alter the resource configurations.\n\n### Background\n\nKubernetes resources can be configured and applied in many ways. This flexibility often makes it difficult to identify problems across the cluster at the time of configuration. Clusterlint looks at live clusters to analyze all its resources and report problems, if any.\n\nThere are some common best practices to follow while applying configurations to a cluster like:\n\n- Namespace is used to limit the scope of the Kubernetes resources created by multiple sets of users within a team. Even though there is a default namespace, dumping all the created resources into one namespace is not recommended. It can lead to privilege escalation, resource name collisions, latency in operations as resources scale up and mismanagement of kubernetes objects. Having namespaces ensures that resource quotas can be enabled to keep track node, cpu and memory usage for individual teams.\n\n- Always specify resource requests and limits on pods: When containers have resource requests specified, the scheduler can make better decisions about which nodes to place pods on. And when containers have their limits specified, contention for resources on a node can be handled in a specified manner.\n\nWhile there are problems that are common to clusters irrespective of the environment they are running in, the fact that different Kubernetes configurations (VMs, managed solutions, etc.) have different subtleties affect how workloads run. Clusterlint provides platform specific checks to identify issues with resources that cluster operators can fix to run in a specific environment.\n\nSome examples of such checks are:\n\n- On upgrade of a cluster on [DOKS](https://www.digitalocean.com/products/kubernetes/), the worker nodes' hostname changes. So, if a user's pod spec relies on the hostname to schedule pods on specific nodes, pod scheduling will fail after upgrade.\n\n*Please refer to [checks.md](https://github.com/digitalocean/clusterlint/blob/master/checks.md) to get some background on every check that clusterlint performs.*\n\n### Install\n\n```bash\ngo get github.com/digitalocean/clusterlint/cmd/clusterlint\n```\n\nThe above command creates the `clusterlint` binary in `$GOPATH/bin`\n\n### Usage\n\n```bash\nclusterlint list [options]  // list all checks available\nclusterlint run [options]  // run all or specific checks\n```\n\n### Running in-cluster\n\nBuild the docker image to run clusterlint from within a cluster by doing:\n\n```shell\ndocker build -t \u003chub_username\u003e/clusterlint:\u003ctag\u003e .\ndocker push \u003chub_username\u003e/clusterlint:\u003ctag\u003e\n```\n\nIf you're running clusterlint from within a Pod, you can use the `--in-cluster` flag to access the Kubernetes API from the Pod.\n\n```\nclusterlint --in-cluster run\n```\n\nHere's a simple example of CronJob definition to run clusterlint in the default namespace without RBAC : \n\n```yaml\napiVersion: batch/v1\nkind: CronJob\nmetadata:\n  name: clusterlint-cron\nspec:\n  schedule: \"0 */1 * * *\"\n  concurrencyPolicy: Replace\n  failedJobsHistoryLimit: 3\n  successfulJobsHistoryLimit: 1\n  jobTemplate:\n    spec:\n      template:\n        spec:\n          containers:\n            - name: clusterlint\n              image: docker.io/\u003chub_username\u003e/clusterlint:\u003ctag\u003e\n              command: ['/clusterlint', '--in-cluster', 'run']\n              imagePullPolicy: IfNotPresent\n          restartPolicy: Never\n```\n\nIf you're using RBAC, see [docs/RBAC.md](docs/RBAC.md).\n\n### Specific checks and groups\n\nAll checks that clusterlint performs are categorized into groups. A check can belong to multiple groups. This framework allows one to only run specific checks on a cluster. For instance, if a cluster is running on DOKS, then, running checks specific to AWS does not make sense. Clusterlint can blacklist aws related checks, if any while running against a DOKS cluster.\n\n```bash\nclusterlint run -g basic                // runs only checks that are part of the basic group\nclusterlint run -G security            // runs all checks that are not part of the security group\nclusterlint run -c default-namespace  // runs only the default-namespace check\nclusterlint run -C default-namespace // exclude default-namespace check\n```\n\n### Disabling checks via Annotations\n\nClusterlint provides a way to ignore some special objects in the cluster from being checked. For example, resources in the kube-system namespace often use privileged containers. This can create a lot of noise in the output when a cluster operator is looking for feedback to improve the cluster configurations. In order to avoid such a situation where objects that are exempt from being checked, the annotation `clusterlint.digitalocean.com/disabled-checks` can be added in the resource configuration. The annotation takes in a comma separated list of check names that should be excluded while running clusterlint.\n\n```json\n\"metadata\": {\n  \"annotations\": {\n    \"clusterlint.digitalocean.com/disabled-checks\" : \"noop,bare-pods\"\n  }\n}\n```\n\n### Building local checks\n\nSome individuals and organizations have Kubernetes best practices that are not\napplicable to the general community, but which they would like to check with\nclusterlint. If your check may be useful for *anyone* else, we encourage you to\nsubmit it to clusterlint rather than keeping it local. However, if you have a\ntruly specific check that is not appropriate for sharing with the broader\ncommunity, you can implement it using Go plugins.\n\nSee the [example plugin](example-plugin) for documentation on how to build a\nplugin. Please be sure to read the [caveats](example-plugin/README.md#caveats)\nand consider whether you really want to maintain a plugin.\n\nTo use your plugin with clusterlint, pass its path on the commandline:\n\n```console\n$ clusterlint --plugins=/path/to/plugin.so list\n$ clusterlint --plugins=/path/to/plugin.so run -c my-plugin-check\n```\n\n## Update Go and dependencies\n1. Update Go version in\n   1. [go.mod](./go.mod)\n   2. [.circleci/config.yml](./.circleci/config.yml)\n   3. [.github/workflows/release.yml](./.github/workflows/release.yml)\n   4. [Dockerfile](./Dockerfile)\n2. Update Go dependencies\n   ```shell\n   go get -u ./...\n   go mod tidy\n   go mod vendor\n   ```\n3. Create and merge PR\n\n## Release\n\nTo release a new version of clusterlint, go to the actions page on GitHub, click on `Run workflow`.\nSpecify the new tag to create. Make sure the tag is prefixed with `v`.\n\nThe workflow does the following:\n\n- Checks out the source code from the default branch\n- Login with dockerhub credentials specified as secrets\n- Builds the docker image digitalocean/clusterlint:\u003ctag\u003e\n- Pushes digitalocean/clusterlint:\u003ctag\u003e to dockerhub\n- Builds binaries for all archs and computes sha256 sums for each binary\n- Creates release and tags the latest commit on the default branch with the input tag specified when workflow is triggered\n\n## Contributing\n\nContributions are welcome, in the form of either issues or pull requests. Please\nsee the [contribution guidelines](CONTRIBUTING.md) for details.\n\n## License\n\nCopyright 2022 DigitalOcean\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fclusterlint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalocean%2Fclusterlint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fclusterlint/lists"}