Version: v26.03

AI Inference Tidal Algorithm ​

Feature Introduction ​

Tidal is a scheduled scaling algorithm designed for workloads with clear tidal characteristics. Users can configure Tidal CRD to scale target workloads (such as Deployment, StatefulSet, ResourceScalingGroup, etc.) to a specified number of replicas at designated times. The current version mainly considers the time dimension factor, suitable for scenarios where business load patterns are clear and capacity can be planned in advance through time-based configuration. Tidal Controller is only responsible for calculating the desired replicas and writing them to the status field—the actual scaling is executed by the general decision framework ElasticScaler. The Tidal resource is bound to an ElasticScaler resource through metadata.labels (elasticscaler.io/name, elasticscaler.io/namespace) in the CRD, and the scaling decisions are uniformly consumed by ElasticScaler.

NOTE:
openFuyao defines a custom resource named ResourceScalingGroup (abbreviated as RSG) in Kubernetes. For detailed introduction and usage of this resource, please refer to the documentation: ResourceScalingGroup-Resource Group Scaling. RSG or ResourceScalingGroup mentioned in this document refers to this custom resource object.

Application Scenarios ​

  • Scenarios with clear business time patterns such as morning/evening peaks and event days, requiring proactive scaling before peaks and scaling down during low-traffic periods.
  • Multi-stage resource strategies for workdays/weekends, holidays, warm-up/peak/wrap-up periods, requiring different replica counts at different time points.
  • Clusters with existing ElasticScaler, seeking to add time-based scaling capabilities to coordinate with existing metric-based policies.

Capability Scope ​

  • Provides time-driven scaling decisions based on standard CRD (Tidal), independent of historical metric predictions, suitable for scenarios with clear business time patterns (such as morning/evening peaks, event days, etc.).
  • Supports scalable resources such as Deployment, StatefulSet, ResourceScalingGroup as targets, working with the ElasticScaler framework for unified elastic management.
  • Supports combining multiple time rules to construct multi-stage resource strategies for workdays/weekends, holidays, warm-up/peak/wrap-up periods, etc.
  • Supports 6-field CRON expressions with second-level precision and mandatory timezone configuration to ensure consistent behavior across environments.
  • Supports conflict resolution strategies (taking the maximum replica count) when multiple rules trigger simultaneously at the same time point, ensuring business capacity safety even under complex rules.
  • Provides observable scaling intentions through Status fields (such as desiredReplicas, activeRule, lastTriggerTime, nextTriggerTime) for troubleshooting and auditing.

Highlight Features ​

  • Focuses on "time dimension" tidal scheduling: Compared to traditional autoscaling based on real-time metrics, it is more suitable for scenarios with clear business calendars (workdays/weekends/event periods), enabling proactive scaling before peaks and timely scaling down during low-traffic periods.
  • Deep integration with ElasticScaler: Through the two standard labels elasticscaler.io/name and elasticscaler.io/namespace, Tidal resources are decoupled from ElasticScaler resources for binding. ElasticScaler is responsible for orchestrating time-based policies with other metric-based policies.
  • Strongly constrained timezone + 6-field CRON syntax: Built-in validation rules to avoid time deviation issues caused by missing timezones or 5-field CRON expressions.

Implementation Principle ​

This section explains the implementation principle of the tidal algorithm from both logical and runtime perspectives.

Logical View ​

The logical view shows the core components and their interaction relationships of the time-based tidal business scenario scheduling decision algorithm. The system adopts a layered architecture design, including the user layer, Kubernetes API layer, tidal algorithm layer (Tidal Controller and Timer Scheduler), and decision framework integration layer. Each layer interacts through standard Kubernetes API mechanisms (Watch, Reconcile). The Controller is responsible for watching CR changes and coordinating timing rules, the Timer Scheduler is responsible for parsing CRON expressions and triggering timed events, and finally integrates with the decision framework through label mechanisms to achieve automatic scaling of target Deployments.

Figure 1 Tidal Algorithm Logical View

time-based-tidal-algo-logic

Runtime View ​

The runtime view shows the complete runtime flow from user configuration to final scaling execution through a sequence diagram, which can be divided into four stages.

  1. Users configure Tidal CR through YAML and submit it to APIServer.
  2. Controller perceives CR changes through the Watch mechanism, triggers Reconcile processing, and synchronizes time rules to the internal TimerScheduler.
  3. TimerScheduler sets timers based on CRON expressions and notifies the Controller when trigger time arrives.
  4. Controller updates Tidal's Status and desired replica count. Decision frameworks like ElasticScaler watch status changes and execute actual Pod scaling operations.

Figure 2 Tidal Algorithm Runtime Sequence Diagram

time-based-tidal-algo-sequence

ElasticScaler: Tidal resources depend on ElasticScaler to complete actual scaling. Tidal resources are only responsible for calculating desired replicas based on time policies and writing them to status, without directly modifying target resources. After binding to a specified ElasticScaler resource through elasticscaler.io/name and elasticscaler.io/namespace in metadata.labels, ElasticScaler watches Tidal resource's status.desiredReplicas and other statuses through the Watch mechanism, and executes actual scaling on the target resource pointed to by spec.targetRef. ElasticScaler must be deployed and configured before using Tidal.

Installation ​

Prerequisites ​

  • An available Kubernetes cluster with kubectl and helm installed.
  • Network environment configured to access cr.openfuyao.cn.

Installation ​

Create the namespace scaling-system (if it doesn't exist):

bash
kubectl create namespace scaling-system

Two deployment methods are supported: deploying through the pd-orchestrator unified chart (with optional sub-components), or deploying the Tidal component separately from the source code repository.

Method 1: Deploy via pd-orchestrator chart ​

Install the pd-orchestrator chart from the OCI repository, which by default installs three Controllers: elastic-scaler, resourcescalinggroup, and tidal. Since Tidal depends on ElasticScaler to complete actual scaling, it is recommended to deploy Tidal with ElasticScaler together; ResourceScalingGroup (RSG) can be deployed optionally as needed.

For full capabilities (Tidal+ElasticScaler), use the default installation.

bash
helm install orchestrator oci://cr.openfuyao.cn/charts/pd-orchestrator --version 0.0.0-latest

If you only need to deploy Tidal Controller, you can enable sub-components on demand through --set switches, for example, to enable only Tidal Controller.

bash
helm install orchestrator oci://cr.openfuyao.cn/charts/pd-orchestrator --version 0.0.0-latest \
  --set elastic-scaler.enabled=true \
  --set resourcescalinggroup.enabled=false \
  --set tidal.enabled=true

NOTE:
ElasticScaler typically points to only one scaling target. When using tidal, the Tidal resource will be associated with a certain ElasticScaler through labels, and that ElasticScaler will scale the same target. If a default ElasticScaler example CR is also created during installation (for HPA to scale RSG groups), it will conflict or duplicate with the ElasticScaler used by tidal. It is recommended that one scaling target corresponds to only one ElasticScaler resource. Users should create the ElasticScaler CR themselves and bind it to the Tidal resource's labels, so the default ElasticScaler CR during installation should be disabled. When resourcescalinggroup.enabled=false, RSG is not deployed and resourcescalinggroup.instanceConfig.enabled naturally doesn't take effect. However, when elastic-scaler.enabled=true, you still need to separately set elastic-scaler.elasticScaler.enabled=false to avoid creating the default ElasticScaler example CR. Example:

bash
helm install orchestrator oci://cr.openfuyao.cn/charts/pd-orchestrator --version 0.0.0-latest \
  --set elastic-scaler.enabled=true \
  --set resourcescalinggroup.enabled=false \
  --set tidal.enabled=true \
  --set elastic-scaler.elasticScaler.enabled=false

Method 2: Deploy individual component (from source) ​

After cloning the code from the ElasticScaler repository, navigate to the charts/elastic-scaler/charts/tidal path and execute helm install in that directory to deploy only the Tidal Controller.

bash
git clone https://gitcode.com/openFuyao/elastic-scaler.git
cd elastic-scaler/charts/elastic-scaler/charts/tidal
helm install tidal . -n <namespace>

This method only installs the Tidal component. For actual scaling capabilities, ElasticScaler needs to be deployed separately and ensure that the Tidal CR's labels are correctly bound to the ElasticScaler resource.

Key Parameter Description ​

Table 1 Helm Key Parameters

Parameter KeyDescription
orchestratorHelm Release name, can be modified as needed.
--version 0.0.0-latestInstall the latest version of orchestrator (which includes the three Controllers mentioned above).
--set elastic-scaler.enabled / --set resourcescalinggroup.enabled / --set tidal.enabledSet to true or false as needed to control whether to deploy the corresponding Controller; all are enabled by default if not specified.
--set resourcescalinggroup.instanceConfig.enabledControls whether to install the ResourceScalingGroup default example CR. If mainly using Tidal/ElasticScaler for tidal scaling, it is recommended to keep the default value when --set resourcescalinggroup.enabled=false (at this time RSG is not deployed, instanceConfig no longer takes effect).
--set elastic-scaler.elasticScaler.enabledControls whether to install the ElasticScaler default example CR. Since ElasticScaler typically points to only one scaling resource, if using Tidal to bind a custom ElasticScaler for tidal scaling, it is recommended to explicitly set this value to false to avoid conflicts between the default ElasticScaler example CR and the ElasticScaler in tidal scenarios.

Verify Deployment ​

After completing the installation, you can verify whether the Tidal Controller is running normally through the following steps.

  • Check Pod status (using namespace scaling-system as an example).

    bash
    kubectl get pods -n scaling-system | grep tidal

    Expect to see Pods with tidal in the name and STATUS as Running.

  • Check Controller logs to confirm there are no persistent errors (replace <pod-name> or <deployment-name> according to the actual deployment name).

    bash
    # View Pod logs
    kubectl logs -n scaling-system <pod-name>
    
    # Or view Pod list through Deployment and then view logs
    kubectl get deploy -n scaling-system
    kubectl logs -n scaling-system deploy/<deployment-name>

If the Pod is in a non-Running state or there are numerous errors in the logs, you can prioritize checking:

  • Whether the namespace is correct during Helm installation.
  • Whether cluster access to cr.openfuyao.cn is normal (whether the image is pulled successfully).
  • Whether there are conflicts with existing ElasticScaler/ResourceScalingGroup deployments in the cluster.

Using AI Inference Tidal Algorithm ​

Prerequisites ​

  • The installation steps described earlier in this guide have been completed, and Tidal Controller and ElasticScaler are running normally.
  • During installation, the default ElasticScaler/ResourceScalingGroup example CRs that conflict with tidal scenarios have been disabled according to the recommendations in Key Parameter Description.
  • At least one target workload (such as Deployment, StatefulSet, etc.) to be scaled exists in the cluster.

Background Information ​

  • Tidal describes time-based policy rules through CR. ElasticScaler watches fields such as status.desiredReplicas of Tidal resources through the Watch mechanism and executes actual scaling on the target resource pointed to by spec.targetRef.

  • This capability is suitable for scenarios where business loads have clear time patterns (such as morning/evening peaks, event days, etc.). The current version only considers the time dimension without comprehensive real-time metric decision-making.

  • Time rules are configured through "timezone prefix + 6-field CRON expression" in the format:

    text
    CRON_TZ=<timezone> second minute hour day month weekday

    Example (trigger at 8:00 on workdays):

    text
    CRON_TZ=Asia/Shanghai 0 0 8 * * 1-5
    └──────────timezone────┘ │ │ │ │ │ └─ weekday (1-5 represents Monday to Friday)
                             │ │ │ │ └── month
                             │ │ │ └──── day
                             │ │ └────── hour
                             │ └──────── minute
                             └────────── second

Usage Restrictions ​

  • Currently only supports fixed replica count setting based on time policies, does not support dynamic curve adjustments within time periods.
  • A single ElasticScaler resource typically points to only one scaling target; the same target should not be controlled by multiple ElasticScaler/Tidal/HPA policies simultaneously to avoid policy conflicts.
  • CRON expression must be in timezone prefix + 6-field format and must include the second field; incorrect expressions will cause time policies to not take effect.
  • Tidal Controller is only responsible for calculating desired replicas and writing to Status, it does not directly modify target resources; if ElasticScaler is not correctly deployed or bound, time policies will not actually take effect.

Operation Steps ​

  1. Write Tidal CR.

    Below is a Tidal example more aligned with actual production scenarios, used to set different replica counts at different time periods.

    • Scale to 10 replicas before morning peak on workdays (8:00).
    • Scale to 20 replicas during evening peak on workdays (20:00).
    • Scale down to 2 replicas at 1:00 AM daily to save resources.
    yaml
    apiVersion: tidal.io/v1alpha1
    kind: Tidal
    metadata:
      name: ecommerce-traffic-tidal
      namespace: scaling-system
      labels:
        elasticscaler.io/name: ecommerce-traffic-elasticscaler
        elasticscaler.io/namespace: scaling-system
    spec:
      targetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: ecommerce-frontend
        namespace: production
    
      triggers:
        times:
          rules:
            - name: workday-morning-base
              cron: "CRON_TZ=Asia/Shanghai 0 0 8 * * 1-5"
              replicas: 10
              description: "Scale to 10 replicas before workday morning peak to ensure daytime traffic"
    
            - name: workday-evening-peak
              cron: "CRON_TZ=Asia/Shanghai 0 0 20 * * 1-5"
              replicas: 20
              description: "Scale to 20 replicas during workday evening peak to handle evening traffic surge"
    
            - name: nightly-offpeak
              cron: "CRON_TZ=Asia/Shanghai 0 0 1 * * *"
              replicas: 2
              description: "Scale down to 2 replicas at 1 AM daily to save resources"

    Table 2 Tidal CR Field Description

    Field PathRequiredDescription
    metadata.nameYesTidal resource name, unique within the namespace.
    metadata.namespaceYesTidal namespace. It is recommended to be consistent with the ElasticScaler namespace or planned according to operational specifications.
    metadata.labels.elasticscaler.io/nameYesName of the bound ElasticScaler resource. ElasticScaler will watch the status of this Tidal resource.
    metadata.labels.elasticscaler.io/namespaceYesNamespace of the bound ElasticScaler resource.
    spec.targetRef.apiVersionYesAPIVersion of the target workload.
    spec.targetRef.kindYesType of target workload, such as Deployment, StatefulSet, ResourceScalingGroup, etc.
    spec.targetRef.nameYesName of the target workload.
    spec.targetRef.namespaceYesNamespace of the target workload.
    spec.triggers.times.rules[].nameYesTime rule name, should be unique within the same Tidal resource, used for troubleshooting and identifying current rule in status.
    spec.triggers.times.rules[].cronYes6-field CRON expression with timezone prefix, controlling when the rule triggers.
    spec.triggers.times.rules[].replicasYesDesired target replica count when the rule triggers.
    spec.triggers.times.rules[].descriptionNoRule description to help the team understand the business meaning of the rule.
  2. Create resource.

    bash
    kubectl apply -f ecommerce-traffic-tidal.yaml
  3. View and verify Tidal resource status.

    bash
    kubectl get tidal ecommerce-traffic-tidal -n scaling-system -o yaml

    NOTE:
    status.desiredReplicas: Current desired replica count calculated by the time policy.
    status.activeRule: Name of the currently active time rule.
    status.lastTriggerTime: Time point of the most recent time rule trigger.
    status.nextTriggerTime: Expected next trigger time point.
    When a time rule trigger point is reached, desiredReplicas and activeRule will be updated. After ElasticScaler watches the status change, it will execute actual scaling on the Deployment/StatefulSet or other resources pointed to by spec.targetRef.

  4. Adjust rules according to business needs.

    • You can update the CRON expressions and replica counts in rules by editing the CR (kubectl edit tidal ...) or re-apply.
    • It is recommended to conduct small-scale drills during low-risk periods first, and confirm that the scaling time points match expectations before applying to production traffic.

Follow-up Operations ​

  • Regularly review and adjust time rules in Tidal resources according to business changes to avoid long-term retention of historical event rules.

  • When a time policy is no longer needed, you can delete the corresponding Tidal CR:

    bash
    kubectl delete tidal ecommerce-traffic-tidal -n scaling-system
  • Execute the following command to view all Tidal instances:

    bash
    kubectl get tidal -A
  • Execute the following command to view single instance details:

    bash
    kubectl describe tidal ecommerce-traffic-tidal -n scaling-system