AliyunContainerService / kubernetes-cronhpa-controller

⏰kubernetes-cronhpa-controller is a HPA controller that allows to scale your workload based on time schedule.
443 stars 122 forks source link

kubernetes-cronhpa-controller

License Build Status

Overview

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).

Installation

  1. install CRD
    # k8s < v1.22
    kubectl apply -f config/crds/autoscaling.alibabacloud.com_cronhorizontalpodautoscalers.yaml
    # k8s >=v1.22
    kubectl apply -f config/crds/autoscaling.alibabacloud.com_cronhorizontalpodautoscalers.v1.22.yaml
  2. install RBAC settings
    
    # create ClusterRole 
    kubectl apply -f config/rbac/rbac_role.yaml

create ClusterRolebinding and ServiceAccount

kubectl apply -f config/rbac/rbac_role_binding.yaml

3. deploy kubernetes-cronhpa-controller 
```$xslt
kubectl apply -f config/deploy/deploy.yaml
  1. verify installation
    
    kubectl get deploy kubernetes-cronhpa-controller -n kube-system -o wide 

➜ kubernetes-cronhpa-controller git:(master) ✗ kubectl get deploy kubernetes-cronhpa-controller -n kube-system NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE kubernetes-cronhpa-controller 1 1 1 1 49s

## Example 
Please try out the examples in the <a href="https://github.com/AliyunContainerService/kubernetes-cronhpa-controller/blob/master/examples">examples folder</a>.   

1. Deploy sample workload and cronhpa  
```$xslt
kubectl apply -f examples/deployment_cronhpa.yaml 
  1. Check deployment replicas
    
    kubectl get deploy nginx-deployment-basic 

➜ kubernetes-cronhpa-controller git:(master) ✗ kubectl get deploy nginx-deployment-basic NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment-basic 2 2 2 2 9s


3. Describe cronhpa status 
```$xslt
kubectl describe cronhpa cronhpa-sample 

Name:         cronhpa-sample
Namespace:    default
Labels:       controller-tools.k8s.io=1.0
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"autoscaling.alibabacloud.com/v1beta1","kind":"CronHorizontalPodAutoscaler","metadata":{"annotations":{},"labels":{"controll...
API Version:  autoscaling.alibabacloud.com/v1beta1
Kind:         CronHorizontalPodAutoscaler
Metadata:
  Creation Timestamp:  2019-04-14T10:42:38Z
  Generation:          1
  Resource Version:    4017247
  Self Link:           /apis/autoscaling.alibabacloud.com/v1beta1/namespaces/default/cronhorizontalpodautoscalers/cronhpa-sample
  UID:                 05e41c95-5ea2-11e9-8ce6-00163e12e274
Spec:
  Exclude Dates:  <nil>
  Jobs:
    Name:         scale-down
    Run Once:     false
    Schedule:     30 */1 * * * *
    Target Size:  1
    Name:         scale-up
    Run Once:     false
    Schedule:     0 */1 * * * *
    Target Size:  3
  Scale Target Ref:
    API Version:  apps/v1beta2
    Kind:         Deployment
    Name:         nginx-deployment-basic
Status:
  Conditions:
    Job Id:           38e79271-9a42-4131-9acd-1f5bfab38802
    Last Probe Time:  2019-04-14T10:43:02Z
    Message:
    Name:             scale-down
    Run Once:         false
    Schedule:         30 */1 * * * *
    State:            Submitted
    Job Id:           a7db95b6-396a-4753-91d5-23c2e73819ac
    Last Probe Time:  2019-04-14T10:43:02Z
    Message:
    Name:             scale-up
    Run Once:         false
    Schedule:         0 */1 * * * *
    State:            Submitted
  Exclude Dates:      <nil>
  Scale Target Ref:
    API Version:  apps/v1beta2
    Kind:         Deployment
    Name:         nginx-deployment-basic
Events:               <none>

if 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.

➜  kubernetes-cronhpa-controller git:(master) kubectl describe cronhpa cronhpa-sample
Name:         cronhpa-sample
Namespace:    default
Labels:       controller-tools.k8s.io=1.0
Annotations:  <none>
API Version:  autoscaling.alibabacloud.com/v1beta1
Kind:         CronHorizontalPodAutoscaler
Metadata:
  Creation Timestamp:  2019-11-01T12:49:57Z
  Generation:          1
  Resource Version:    47812775
  Self Link:           /apis/autoscaling.alibabacloud.com/v1beta1/namespaces/default/cronhorizontalpodautoscalers/cronhpa-sample
  UID:                 1bbbab8a-fca6-11e9-bb47-00163e12ab74
Spec:
  Exclude Dates:  <nil>
  Jobs:
    Name:         scale-down
    Run Once:     false
    Schedule:     30 */1 * * * *
    Target Size:  2
    Name:         scale-up
    Run Once:     false
    Schedule:     0 */1 * * * *
    Target Size:  3
  Scale Target Ref:
    API Version:  apps/v1beta2
    Kind:         Deployment
    Name:         nginx-deployment-basic2
Status:
  Conditions:
    Job Id:           157260b9-489c-4a12-ad5c-f544386f0243
    Last Probe Time:  2019-11-05T03:47:30Z
    Message:          cron hpa job scale-down executed successfully. current replicas:3, desired replicas:2
    Name:             scale-down
    Run Once:         false
    Schedule:         30 */1 * * * *
    State:            Succeed
    Job Id:           5bab7b8c-158a-469c-a68c-a4657486e2a5
    Last Probe Time:  2019-11-05T03:48:00Z
    Message:          cron hpa job scale-up executed successfully. current replicas:2, desired replicas:3
    Name:             scale-up
    Run Once:         false
    Schedule:         0 */1 * * * *
    State:            Succeed
  Exclude Dates:      <nil>
  Scale Target Ref:
    API Version:  apps/v1beta2
    Kind:         Deployment
    Name:         nginx-deployment-basic
Events:
  Type    Reason   Age                     From                            Message
  ----    ------   ----                    ----                            -------
  Normal  Succeed  42m (x5165 over 3d14h)  cron-horizontal-pod-autoscaler  cron hpa job scale-down executed successfully. current replicas:3, desired replicas:1
  Normal  Succeed  30m                     cron-horizontal-pod-autoscaler  cron hpa job scale-up executed successfully. current replicas:1, desired replicas:3
  Normal  Succeed  17m (x13 over 29m)      cron-horizontal-pod-autoscaler  cron hpa job scale-up executed successfully. current replicas:2, desired replicas:3
  Normal  Succeed  4m59s (x26 over 29m)    cron-horizontal-pod-autoscaler  cron hpa job scale-down executed successfully. current replicas:3, desired replicas:2

🍻Cheers! It works.

Implementation Details

The following is an example of a CronHorizontalPodAutoscaler.

apiVersion: autoscaling.alibabacloud.com/v1beta1
kind: CronHorizontalPodAutoscaler
metadata:
  labels:
    controller-tools.k8s.io: "1.0"
  name: cronhpa-sample
  namespace: default 
spec:
   scaleTargetRef:
      apiVersion: apps/v1beta2
      kind: Deployment
      name: nginx-deployment-basic
   jobs:
   - name: "scale-down"
     schedule: "30 */1 * * * *"
     targetSize: 1
   - name: "scale-up"
     schedule: "0 */1 * * * *"
     targetSize: 3

The 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.

The cronhpa job spec need three fields:

HELP kube_failed_jobs_in_cron_engine_total Failed jobs in queue of Cron Engine

TYPE kube_failed_jobs_in_cron_engine_total gauge

kube_failed_jobs_in_cron_engine_total 0

HELP kube_jobs_in_cron_engine_total Jobs in queue of Cron Engine

TYPE kube_jobs_in_cron_engine_total gauge

kube_jobs_in_cron_engine_total 2

HELP kube_submitted_jobs_in_cron_engine_total Submitted jobs in queue of Cron Engine

TYPE kube_submitted_jobs_in_cron_engine_total gauge

kube_submitted_jobs_in_cron_engine_total 0

HELP kube_successful_jobs_in_cron_engine_total Successful jobs in queue of Cron Engine

TYPE kube_successful_jobs_in_cron_engine_total gauge

kube_successful_jobs_in_cron_engine_total 2


In most of kubernetes cluster. 

kube_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.


Expired 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.

## Common Question  
* Could `kubernetes-cronhpa-controller` and HPA work together?       
Yes 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.

## Contributing
Please check <a href="https://github.com/AliyunContainerService/kubernetes-cronhpa-controller/blob/master/CONTRIBUTING.md">CONTRIBUTING.md</a>

## License
This software is released under the Apache 2.0 license.