{"id":13562072,"url":"https://github.com/AliyunContainerService/kubernetes-cronhpa-controller","last_synced_at":"2025-04-03T18:32:26.035Z","repository":{"id":35644492,"uuid":"175586358","full_name":"AliyunContainerService/kubernetes-cronhpa-controller","owner":"AliyunContainerService","description":"⏰kubernetes-cronhpa-controller is a HPA controller that allows to scale your workload based on time schedule.","archived":false,"fork":false,"pushed_at":"2024-02-17T09:39:36.000Z","size":58309,"stargazers_count":444,"open_issues_count":19,"forks_count":123,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-11-04T14:42:49.016Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AliyunContainerService.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"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}},"created_at":"2019-03-14T09:09:13.000Z","updated_at":"2024-10-28T02:36:58.000Z","dependencies_parsed_at":"2023-02-19T15:45:23.116Z","dependency_job_id":"ea42ac70-8824-4e2a-b553-438da712d552","html_url":"https://github.com/AliyunContainerService/kubernetes-cronhpa-controller","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliyunContainerService%2Fkubernetes-cronhpa-controller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliyunContainerService%2Fkubernetes-cronhpa-controller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliyunContainerService%2Fkubernetes-cronhpa-controller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliyunContainerService%2Fkubernetes-cronhpa-controller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AliyunContainerService","download_url":"https://codeload.github.com/AliyunContainerService/kubernetes-cronhpa-controller/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247056796,"owners_count":20876462,"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":[],"created_at":"2024-08-01T13:01:04.254Z","updated_at":"2025-04-03T18:32:21.025Z","avatar_url":"https://github.com/AliyunContainerService.png","language":"Go","funding_links":[],"categories":["Autoscaler","Go"],"sub_categories":[],"readme":"# kubernetes-cronhpa-controller \n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)\n[![Build Status](https://travis-ci.org/AliyunContainerService/kubernetes-cronhpa-controller.svg?branch=master)](https://travis-ci.org/AliyunContainerService/kubernetes-cronhpa-controller)\n## Overview \n`kubernetes-cronhpa-controller` is a kubernetes cron horizontal pod autoscaler controller using `crontab` like scheme. You can use `CronHorizontalPodAutoscaler` with any kind object defined in kubernetes which support `scale` subresource(such as `Deployment` and `StatefulSet`). \n\n\n## Installation \n1. install CRD \n```$xslt\n# k8s \u003c v1.22\nkubectl apply -f config/crds/autoscaling.alibabacloud.com_cronhorizontalpodautoscalers.yaml\n# k8s \u003e=v1.22\nkubectl apply -f config/crds/autoscaling.alibabacloud.com_cronhorizontalpodautoscalers.v1.22.yaml\n```\n2. install RBAC settings \n```$xslt\n# create ClusterRole \nkubectl apply -f config/rbac/rbac_role.yaml\n\n# create ClusterRolebinding and ServiceAccount \nkubectl apply -f config/rbac/rbac_role_binding.yaml\n```\n3. deploy kubernetes-cronhpa-controller \n```$xslt\nkubectl apply -f config/deploy/deploy.yaml\n```\n4. verify installation\n```$xslt\nkubectl get deploy kubernetes-cronhpa-controller -n kube-system -o wide \n\n➜  kubernetes-cronhpa-controller git:(master) ✗ kubectl get deploy kubernetes-cronhpa-controller -n kube-system\nNAME                            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE\nkubernetes-cronhpa-controller   1         1         1            1           49s\n```\n## Example \nPlease try out the examples in the \u003ca href=\"https://github.com/AliyunContainerService/kubernetes-cronhpa-controller/blob/master/examples\"\u003eexamples folder\u003c/a\u003e.   \n\n1. Deploy sample workload and cronhpa  \n```$xslt\nkubectl apply -f examples/deployment_cronhpa.yaml \n```\n\n2. Check deployment replicas  \n```$xslt\nkubectl get deploy nginx-deployment-basic \n\n➜  kubernetes-cronhpa-controller git:(master) ✗ kubectl get deploy nginx-deployment-basic\nNAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE\nnginx-deployment-basic   2         2         2            2           9s\n```\n\n3. Describe cronhpa status \n```$xslt\nkubectl describe cronhpa cronhpa-sample \n\nName:         cronhpa-sample\nNamespace:    default\nLabels:       controller-tools.k8s.io=1.0\nAnnotations:  kubectl.kubernetes.io/last-applied-configuration:\n                {\"apiVersion\":\"autoscaling.alibabacloud.com/v1beta1\",\"kind\":\"CronHorizontalPodAutoscaler\",\"metadata\":{\"annotations\":{},\"labels\":{\"controll...\nAPI Version:  autoscaling.alibabacloud.com/v1beta1\nKind:         CronHorizontalPodAutoscaler\nMetadata:\n  Creation Timestamp:  2019-04-14T10:42:38Z\n  Generation:          1\n  Resource Version:    4017247\n  Self Link:           /apis/autoscaling.alibabacloud.com/v1beta1/namespaces/default/cronhorizontalpodautoscalers/cronhpa-sample\n  UID:                 05e41c95-5ea2-11e9-8ce6-00163e12e274\nSpec:\n  Exclude Dates:  \u003cnil\u003e\n  Jobs:\n    Name:         scale-down\n    Run Once:     false\n    Schedule:     30 */1 * * * *\n    Target Size:  1\n    Name:         scale-up\n    Run Once:     false\n    Schedule:     0 */1 * * * *\n    Target Size:  3\n  Scale Target Ref:\n    API Version:  apps/v1beta2\n    Kind:         Deployment\n    Name:         nginx-deployment-basic\nStatus:\n  Conditions:\n    Job Id:           38e79271-9a42-4131-9acd-1f5bfab38802\n    Last Probe Time:  2019-04-14T10:43:02Z\n    Message:\n    Name:             scale-down\n    Run Once:         false\n    Schedule:         30 */1 * * * *\n    State:            Submitted\n    Job Id:           a7db95b6-396a-4753-91d5-23c2e73819ac\n    Last Probe Time:  2019-04-14T10:43:02Z\n    Message:\n    Name:             scale-up\n    Run Once:         false\n    Schedule:         0 */1 * * * *\n    State:            Submitted\n  Exclude Dates:      \u003cnil\u003e\n  Scale Target Ref:\n    API Version:  apps/v1beta2\n    Kind:         Deployment\n    Name:         nginx-deployment-basic\nEvents:               \u003cnone\u003e\n```\n\nif the `State` of cronhpa job is `Succeed` that means the last execution is successful. `Submitted` means the cronhpa job is submitted to the cron engine but haven't be executed so far. Wait for 30s seconds and check the status.\n\n```\n➜  kubernetes-cronhpa-controller git:(master) kubectl describe cronhpa cronhpa-sample\nName:         cronhpa-sample\nNamespace:    default\nLabels:       controller-tools.k8s.io=1.0\nAnnotations:  \u003cnone\u003e\nAPI Version:  autoscaling.alibabacloud.com/v1beta1\nKind:         CronHorizontalPodAutoscaler\nMetadata:\n  Creation Timestamp:  2019-11-01T12:49:57Z\n  Generation:          1\n  Resource Version:    47812775\n  Self Link:           /apis/autoscaling.alibabacloud.com/v1beta1/namespaces/default/cronhorizontalpodautoscalers/cronhpa-sample\n  UID:                 1bbbab8a-fca6-11e9-bb47-00163e12ab74\nSpec:\n  Exclude Dates:  \u003cnil\u003e\n  Jobs:\n    Name:         scale-down\n    Run Once:     false\n    Schedule:     30 */1 * * * *\n    Target Size:  2\n    Name:         scale-up\n    Run Once:     false\n    Schedule:     0 */1 * * * *\n    Target Size:  3\n  Scale Target Ref:\n    API Version:  apps/v1beta2\n    Kind:         Deployment\n    Name:         nginx-deployment-basic2\nStatus:\n  Conditions:\n    Job Id:           157260b9-489c-4a12-ad5c-f544386f0243\n    Last Probe Time:  2019-11-05T03:47:30Z\n    Message:          cron hpa job scale-down executed successfully. current replicas:3, desired replicas:2\n    Name:             scale-down\n    Run Once:         false\n    Schedule:         30 */1 * * * *\n    State:            Succeed\n    Job Id:           5bab7b8c-158a-469c-a68c-a4657486e2a5\n    Last Probe Time:  2019-11-05T03:48:00Z\n    Message:          cron hpa job scale-up executed successfully. current replicas:2, desired replicas:3\n    Name:             scale-up\n    Run Once:         false\n    Schedule:         0 */1 * * * *\n    State:            Succeed\n  Exclude Dates:      \u003cnil\u003e\n  Scale Target Ref:\n    API Version:  apps/v1beta2\n    Kind:         Deployment\n    Name:         nginx-deployment-basic\nEvents:\n  Type    Reason   Age                     From                            Message\n  ----    ------   ----                    ----                            -------\n  Normal  Succeed  42m (x5165 over 3d14h)  cron-horizontal-pod-autoscaler  cron hpa job scale-down executed successfully. current replicas:3, desired replicas:1\n  Normal  Succeed  30m                     cron-horizontal-pod-autoscaler  cron hpa job scale-up executed successfully. current replicas:1, desired replicas:3\n  Normal  Succeed  17m (x13 over 29m)      cron-horizontal-pod-autoscaler  cron hpa job scale-up executed successfully. current replicas:2, desired replicas:3\n  Normal  Succeed  4m59s (x26 over 29m)    cron-horizontal-pod-autoscaler  cron hpa job scale-down executed successfully. current replicas:3, desired replicas:2\n```\n🍻Cheers! It works.\n\n## Implementation Details\nThe following is an example of a `CronHorizontalPodAutoscaler`. \n```$xslt\napiVersion: autoscaling.alibabacloud.com/v1beta1\nkind: CronHorizontalPodAutoscaler\nmetadata:\n  labels:\n    controller-tools.k8s.io: \"1.0\"\n  name: cronhpa-sample\n  namespace: default \nspec:\n   scaleTargetRef:\n      apiVersion: apps/v1beta2\n      kind: Deployment\n      name: nginx-deployment-basic\n   jobs:\n   - name: \"scale-down\"\n     schedule: \"30 */1 * * * *\"\n     targetSize: 1\n   - name: \"scale-up\"\n     schedule: \"0 */1 * * * *\"\n     targetSize: 3\n``` \nThe `scaleTargetRef` is the field to specify workload to scale. If the workload supports `scale` subresource(such as `Deployment` and `StatefulSet`), `CronHorizontalPodAutoscaler` should work well. `CronHorizontalPodAutoscaler` support multi cronhpa job in one spec. \n\nThe cronhpa job spec need three fields:\n* name    \n  `name` should be unique in one cronhpa spec. You can distinguish different job execution status by job name.\n* schedule     \n  The scheme of `schedule` is similar with `crontab`. `kubernetes-cronhpa-controller` use an enhanced cron golang lib （\u003ca target=\"_blank\" href=\"https://github.com/ringtail/go-cron\"\u003ego-cron\u003c/a\u003e） which support more expressive rules. \n  \n  The cron expression format is as described below: \n  ```$xslt\n\n    Field name   | Mandatory? | Allowed values  | Allowed special characters\n    ----------   | ---------- | --------------  | --------------------------\n    Seconds      | Yes        | 0-59            | * / , -\n    Minutes      | Yes        | 0-59            | * / , -\n    Hours        | Yes        | 0-23            | * / , -\n    Day of month | Yes        | 1-31            | * / , - ?\n    Month        | Yes        | 1-12 or JAN-DEC | * / , -\n    Day of week  | Yes        | 0-6 or SUN-SAT  | * / , - ?    \n  ```\n  #### Asterisk ( * )    \n  The asterisk indicates that the cron expression will match for all values of the field; e.g., using an asterisk in the 5th field (month) would indicate every month.\n  #### Slash ( / )    \n  Slashes are used to describe increments of ranges. For example 3-59/15 in the 1st field (minutes) would indicate the 3rd minute of the hour and every 15 minutes thereafter. The form \"*\\/...\" is equivalent to the form \"first-last/...\", that is, an increment over the largest possible range of the field. The form \"N/...\" is accepted as meaning \"N-MAX/...\", that is, starting at N, use the increment until the end of that specific range. It does not wrap around.    \n  #### Comma ( , )      \n  Commas are used to separate items of a list. For example, using \"MON,WED,FRI\" in the 5th field (day of week) would mean Mondays, Wednesdays and Fridays.  \n  #### Hyphen ( - )     \n  Hyphens are used to define ranges. For example, 9-17 would indicate every hour between 9am and 5pm inclusive.   \n  #### Question mark ( ? )      \n  Question mark may be used instead of '*' for leaving either day-of-month or day-of-week blank.\n  #### Predefined schedules\n  You may use one of several pre-defined schedules in place of a cron expression.\n  \n  Entry                  | Description                                | Equivalent To\n  -----                  | -----------                                | -------------\n  @yearly (or @annually) | Run once a year, midnight, Jan. 1st        | 0 0 1 1 *\n  @monthly               | Run once a month, midnight, first of month | 0 0 1 * *\n  @weekly                | Run once a week, midnight between Sat/Sun  | 0 0 * * 0\n  @daily (or @midnight)  | Run once a day, midnight                   | 0 0 * * *\n  @hourly                | Run once an hour, beginning of hour        | 0 * * * *\n  Intervals\n  You may also schedule a job to execute at fixed intervals, starting at the time it's added or cron is run. This is supported by formatting the cron spec like this:\n  \n  @every \u003cduration\u003e\n  where \"duration\" is a string accepted by time.ParseDuration (http://golang.org/pkg/time/#ParseDuration).\n  \n  For example, \"@every 1h30m10s\" would indicate a schedule that activates after 1 hour, 30 minutes, 10 seconds, and then every interval after that.\n  \n  Note: The interval does not take the job runtime into account. For example, if a job takes 3 minutes to run, and it is scheduled to run every 5 minutes, it will have only 2 minutes of idle time between each run.\n  \n  more schedule scheme please check this \u003ca target=\"_blank\" href=\"https://godoc.org/github.com/robfig/cron\"\u003edoc\u003c/a\u003e.\n  #### Specific Date (@date)\n  You may use the specific date to schedule a job for scaling the workloads. It is useful when you want to do a daily promotion.  \n   \n  Entry                       | Description                                | Equivalent To\n  -----                       | -----------                                | -------------\n  @date 2020-10-27 21:54:00   | Run once when the date reach               | 0 54 21 27 10 *\n                              \n* targetSize     \n  `TargetSize` is the size you desired to scale when the scheduled time arrive. \n  \n* runOnce    \n  if `runOnce` is true then the job will only run and exit after the first execution.\n  \n* excludeDates      \n  excludeDates is a dates array. The job will skip the execution when the dates is matched. The minimum unit is day. If you want to skip the date(November 15th), You can specific the excludeDates like below.\n  ```$xslt\n    excludeDates:\n    - \"* * * 15 11 *\"\n  ```\n## Metrics and Monitoring \n`kubernetes-cronhpa-controller` export metrics through prometheus metrics format. Here are core metrics list.\n```prom\n# HELP kube_expired_jobs_in_cron_engine_total Expired jobs in queue of Cron Engine\n# TYPE kube_expired_jobs_in_cron_engine_total gauge\nkube_expired_jobs_in_cron_engine_total 0\n\n# HELP kube_failed_jobs_in_cron_engine_total Failed jobs in queue of Cron Engine\n# TYPE kube_failed_jobs_in_cron_engine_total gauge\nkube_failed_jobs_in_cron_engine_total 0\n\nHELP kube_jobs_in_cron_engine_total Jobs in queue of Cron Engine\n# TYPE kube_jobs_in_cron_engine_total gauge\nkube_jobs_in_cron_engine_total 2\n\n# HELP kube_submitted_jobs_in_cron_engine_total Submitted jobs in queue of Cron Engine\n# TYPE kube_submitted_jobs_in_cron_engine_total gauge\nkube_submitted_jobs_in_cron_engine_total 0\n\n# HELP kube_successful_jobs_in_cron_engine_total Successful jobs in queue of Cron Engine\n# TYPE kube_successful_jobs_in_cron_engine_total gauge\nkube_successful_jobs_in_cron_engine_total 2\n```\n\nIn most of kubernetes cluster. \n```\nkube_jobs_in_cron_engine_total = kube_failed_jobs_in_cron_engine_total + kube_submitted_jobs_in_cron_engine_total + kube_successful_jobs_in_cron_engine_total.\n```\nExpired jobs are in unique state when cron engine have exceptions. So `kube_failed_jobs_in_cron_engine_total` and `kube_expired_jobs_in_cron_engine_total` are two key metrics to monitor.\n\n\n## Common Question  \n* Could `kubernetes-cronhpa-controller` and HPA work together?       \nYes and no is the answer. `kubernetes-cronhpa-controller` can work together with hpa. But if the desired replicas is independent. So when the HPA min replicas reached `kubernetes-cronhpa-controller` will ignore the replicas and scale down and later the HPA controller will scale it up.\n\n## Contributing\nPlease check \u003ca href=\"https://github.com/AliyunContainerService/kubernetes-cronhpa-controller/blob/master/CONTRIBUTING.md\"\u003eCONTRIBUTING.md\u003c/a\u003e\n\n## License\nThis software is released under the Apache 2.0 license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAliyunContainerService%2Fkubernetes-cronhpa-controller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAliyunContainerService%2Fkubernetes-cronhpa-controller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAliyunContainerService%2Fkubernetes-cronhpa-controller/lists"}