{"id":13846255,"url":"https://github.com/hootsuite/sens8","last_synced_at":"2025-04-11T08:31:00.377Z","repository":{"id":57583008,"uuid":"87895828","full_name":"hootsuite/sens8","owner":"hootsuite","description":"Kubernetes controller for Sensu checks","archived":false,"fork":false,"pushed_at":"2019-10-09T20:11:01.000Z","size":9990,"stargazers_count":42,"open_issues_count":9,"forks_count":9,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-08-04T18:01:12.108Z","etag":null,"topics":["golang","k8s","kubernetes","kubernetes-controller","kubernetes-operator","sensu"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hootsuite.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":"2017-04-11T06:05:23.000Z","updated_at":"2024-07-15T06:04:04.000Z","dependencies_parsed_at":"2022-08-30T04:31:24.421Z","dependency_job_id":null,"html_url":"https://github.com/hootsuite/sens8","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hootsuite%2Fsens8","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hootsuite%2Fsens8/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hootsuite%2Fsens8/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hootsuite%2Fsens8/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hootsuite","download_url":"https://codeload.github.com/hootsuite/sens8/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223463215,"owners_count":17149321,"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":["golang","k8s","kubernetes","kubernetes-controller","kubernetes-operator","sensu"],"created_at":"2024-08-04T18:00:21.213Z","updated_at":"2024-11-07T05:27:05.924Z","avatar_url":"https://github.com/hootsuite.png","language":"Go","funding_links":[],"categories":["Operators vs Controllers"],"sub_categories":["Ingress"],"readme":"\u003cimg src=\"sens8.png\" alt=\"sens8\" width=\"262\" height=\"221\"\u003e\n\n**Sensu + K8s**\n\n[![CircleCI](https://circleci.com/gh/hootsuite/sens8.svg?style=svg)](https://circleci.com/gh/hootsuite/sens8)\n\nA Kubernetes controller that watches cluster resources (`Deployment`, `Pod` etc.) and runs Sensu checks which are declared in the resource's annotations. For each of the check definitions it will run them at the specified interval, updating the checks with the latest resource info provided by Kubernetes. It communicates directly to Sensu's RabbitMQ endpoint, dynamically adding Sensu [proxy clients](https://sensuapp.org/docs/latest/reference/clients.html#proxy-clients) and optionally removing them on resource deletion or annotation update.   \n\nSens8 effectively acts a Sensu super client. It allows for checks to be run on ephemeral resources such as a pod under a replicaset without having to sidecar the heavy Sensu ruby client, or restart it. By having checks defined in the resources themselves it gives teams greater autonomy and lets checks be pushed out via CD. It also prevents having to manage resource-level checks out of band via configuration management. \n\nUnlike a traditional setup where Sensu's client is installed with check scripts, only a predefined number of checks are supported (i.e., only check definitions are allowed in the annotations). Refer to the [check command documentation](check-docs.md) for what is valid for each resource. Most checks are intended to be run over the network - like making an http request to a pod. For resources such as deployments, only checks based on the status provided by Kubernetes are possible.\n       \nA keepalive is run for Sens8 itself, and only itself, since all other checks register under proxy clients. Given its super client nature it's advised to set up alerting/paging appropriately.   \n\n### Build\n\n```bash\nmake all\n```\n\n### Deployment\n\nRefer to `kubernetes.yml` for an example deployment + config\n\n### Limitations\n\n* Only RabbitMQ transport is supported (no Redis)\n* If Sens8 crashes, all checks that have a ttl will alert\n* Subscriptions are ignored\n* Only checks are run. No metrics \n* Certain resources types such `Deployment` have a limited feature set and only alert of the status provided by Kubernetes. \n\n### Roadmap\n\nSee [projects](https://github.com/hootsuite/sens8/projects) for status \n\nCheck Schema\n============\n\nChecks are defined in the annotation `hootsuite.com/sensu-checks` of a given resource as a json array check objects. The check format is same as [Sensu's check configuration](https://sensuapp.org/docs/0.29/reference/checks.html#check-attributes) minus some fields being ignored. Refer to Sensu's [check definition specification](https://sensuapp.org/docs/0.29/reference/checks.html#check-definition-specification) as a guide.\n\n| field       | type    | required | example                                   |description |\n|-------------|---------|----------|-------------------------------------------|------------|\n| name        | string  | *        | `my_check`                                | Name of the check. Must be unique to the resource it's running on. See [Sensu's check naming](https://sensuapp.org/docs/0.29/reference/checks.html#check-names) |\n| command     | string  | *        | `deployment_status --warn 0.9 --crit 0.8` | Check to run. The first chunk of the string is the check id. All other parameters get parsed by the check itself. Environment variables and backticks (sub-shells) are interpolated. Refer to the [check command documentation](check-docs.md) for valid checks that can be run on the given resource |\n| interval    | int     | *        | `30`                                      | Interval in seconds between checks |\n| deregister  | bool    |          | `true`                                    | Deregister the proxy client sensu on resource deletion or annotation removal. Default value is dependant on resource type. Pod: true, Deployment: false |\n\nAll other (arbitrary) fields get passed along with the check result in the same way Sensu client proper does.\n\nCheck results will be registered/de-registered with the following template:  \n\n| Resource   | Source (client name)                     | Deregister default |\n|------------|------------------------------------------|---------|\n| Deployment | `deployment-name.deployment.namespace`   | `false` | \n| Pod        | `pod-name.pod.namespace`                 | `true` | \n| Service    | `sevice-name.service.namespace`          | `false` | \n| ReplicaSet | `replicatset-name.replicatset.namespace` | `false` |\n| Node       | `node-name.node.namespace`               | `false` |\n| DaemonSet  | `daemonSet-name.daemonSet.namespace`     | `false` |\n\n**Example check annotation**\n```json\n[\n  {\n    \"name\": \"deployment_status\",\n    \"command\": \"deployment_status --warn 0.9 --crit 0.8\",\n    \"interval\": 60,\n    \"deregister\": true,\n    \"foo\": \"bar\"\n  }\n]\n```\n\n**Example check result**\n\nFor the given check example above, the check result to Sensu might look like:\n```json\n[\n  {\n    \"name\": \"deployment_status\",\n    \"command\": \"deployment_status --warn 0.9 --crit 0.8\",\n    \"interval\": 60,\n    \"deregister\": true,\n    \"foo\": \"bar\",\n    \"source\": \"test-app.deployment.default\",\n    \"status\": 0,\n    \"output\": \"replicas: 5, updatedReplicas: 5, unavailableReplicas: 0\"\n  }\n]\n```\n\n## Defaults\n\nIt is possible to set defaults for all checks in Sens8's `-config-file` config. Arbitrary fields are respected, but any field defined in the check will override it. It is also possible to set a default for the required `interval`. Example:\n\n```json\n{\n  \"defaults\": {\n    \"interval\": 60,\n    \"occurrences\": 3,\n    \"refresh\": 900,\n    \"handlers\": [\"default\"],\n    \"pager_team\": \"production_engineering\"\n  }\n}\n```\n\n## Example service deployment\n\n```yaml\nkind: Deployment\napiVersion: extensions/v1beta1\nmetadata:\n  labels:\n    app: test-app\n  name: test-app\n  namespace: default\n  annotations:\n    hootsuite.com/sensu-checks: |-\n      [\n        {\n          \"name\": \"deployment_status\",\n          \"command\": \"deployment_status --warn 0.9 --crit 0.8\",\n          \"interval\": 60,\n          \"occurrences\": 3,\n          \"refresh\": 900,\n          \"handlers\": [\"default\"],\n          \"pager_team\": \"production_engineering\",\n          \"documentation\": \"http://example.com/runbook.html\",\n          \"deregister\": true\n        }\n      ]\nspec:\n  replicas: 1\n  revisionHistoryLimit: 1\n  selector:\n    matchLabels:\n      app: test-app\n  template:\n    metadata:\n      labels:\n        app: test-app\n      annotations:\n        hootsuite.com/sensu-checks: |-\n          [\n            {\n              \"name\": \"check_pod_dependencies\",\n              \"command\": \"hs_healthcheck --url http://:::POD_IP::::80/status/dependencies\",\n              \"interval\": 60,\n            }\n          ]\n    spec:\n      containers:\n      - name: test-app\n        image: markeijsermans/debug\n        command: [\"python3\"]\n        args: [\"-u\", \"-m\", \"http.server\", \"80\"]\n        imagePullPolicy: Always\n        ports:\n        - containerPort: 80\n          protocol: TCP\n```\n\n\nChecks Commands\n===============\n\nEach resource is limited to a subset of commands that can be run against it.\n\n[Check Command Documentation](check-docs.md)\n\n_or_\n\nGet latest docs via: `./sens8 -check-docs`\n\n### Release Process\n\nIf master branch contains a git tag, circle-ci will tag the docker image as well. Make sure to push the tag, before the commit. This will likely change when circle-ci 2.0 supports git tags. \n\n### Maintainers\n\n* :octocat: [Mark Eijsermans](https://github.com/markeijsermans)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhootsuite%2Fsens8","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhootsuite%2Fsens8","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhootsuite%2Fsens8/lists"}