Spot (preemptible) elastic container instances let you run batch jobs and stateless workloads on unused Alibaba Cloud capacity at a discounted price. This guide shows how to create a spot ECI-based pod in a Kubernetes cluster by adding annotations to a pod manifest.
Limitations
Before proceeding, note the following constraints:
Annotations take effect only at pod creation time. Adding or modifying annotations on an existing pod has no effect.
For Kubernetes Jobs, add annotations in
spec.template.metadata, not in the top-levelmetadata.Spot instances require 2 or more vCPUs when you specify resources by vCPU count and memory size.
When to use spot instances
Spot instances are suited for stateless, fault-tolerant workloads that can tolerate interruption:
Batch and big data jobs (Spark, ETL pipelines)
Image rendering and video transcoding
Large-scale parallel computing
Horizontally scalable web services
Use pay-as-you-go instances for workloads that cannot tolerate interruption: cluster management tools, monitoring agents, StatefulSets, and databases.
How spot instances work
Billing
When you create a spot instance, the market price fluctuates based on supply and demand for the instance type. If your bid exceeds the current market price and inventory is sufficient, the instance is created and enters a protection period (default: 1 hour). During the protection period, billing uses the market price at time of purchase. After the protection period, billing switches to the real-time market price.
Spot instances are billed at a lower price than pay-as-you-go instances. For details, see the "Billing methods" section of Preemptible instances.
Reclaim mechanism
After the protection period expires, the system checks the market price and resource inventory every 5 minutes. If the market price exceeds your bid or inventory is insufficient, the instance is released.
A SpotToBeReleased event is generated approximately 3 minutes before release.
After release, billing stops, the ECI instance status changes to Expired, and the pod status changes to Failed with reason BidFailed.
Creation methods
| Method | How it works | Minimum size |
|---|---|---|
| Specify an ECS instance type | Billed at the real-time discounted pay-as-you-go price of the specified type | — |
| Specify vCPU count and memory size | System auto-selects a matching ECS instance type; billed at the discounted market price of that type | 2 vCPUs |
When you specify vCPU count and memory size, the supported combinations are:
| vCPUs | Memory (GiB) |
|---|---|
| 2 | 2, 4, 8, 16 |
| 4 | 4, 8, 16, 32 |
| 8 | 8, 16, 32, 64 |
| 12 | 12, 24, 48, 96 |
| 16 | 16, 32, 64, 128 |
| 24 | 24, 48, 96, 192 |
| 32 | 32, 64, 128, 256 |
| 52 | 96, 192, 384 |
| 64 | 128, 256, 512 |
If the combination you specify is not supported, the system automatically uses the next supported higher specification.
Prerequisites
Before you begin, ensure that you have:
An ACK cluster with a virtual node
The
alibabacloud.com/eci: "true"label configured for ECI scheduling
To choose a bid price, query historical spot pricing using these ECS API operations:
DescribeSpotPriceHistory — historical prices over the last 30 days
DescribeSpotAdvice — average release rate and average discount rate
Set your bid above the average market price but within a range your business can accept. This increases the chance of successful creation and reduces the risk of premature release.
Annotations
Add the following annotations to spec.template.metadata.annotations in your pod manifest.
| Annotation | Required | Default | Description |
|---|---|---|---|
k8s.aliyun.com/eci-spot-strategy | Yes | — | Bid policy. SpotWithPriceLimit: set a maximum hourly price. SpotAsPriceGo: automatically use the market price at creation time. |
k8s.aliyun.com/eci-spot-price-limit | No | — | Maximum hourly price, accurate to 3 decimal places. Valid only when eci-spot-strategy is SpotWithPriceLimit. |
k8s.aliyun.com/eci-spot-duration | No | 1 (hour) | Protection period in hours. Set to 0 to disable the protection period. |
k8s.aliyun.com/eci-spot-fallback | No | false | When true, creates a pay-as-you-go instance if spot inventory is insufficient. |
When SpotAsPriceGo is set and the specified instance type has insufficient inventory in the target zone, set your maximum hourly price close to the pay-as-you-go price of that instance type to improve the creation success rate.
Create a spot instance
All examples use Kubernetes Job manifests. The alibabacloud.com/eci: "true" label schedules the pod onto a virtual node.
Example 1: Specify an ECS instance type with a price limit
This example creates a spot instance based on ecs.c6.large with a maximum hourly price of $0.25.
apiVersion: batch/v1
kind: Job
metadata:
name: test
spec:
template:
metadata:
labels:
app: perl
alibabacloud.com/eci: "true"
annotations:
k8s.aliyun.com/eci-use-specs: "ecs.c6.large" # Specify an ECS instance type.
k8s.aliyun.com/eci-spot-strategy: "SpotWithPriceLimit" # Use a price cap.
k8s.aliyun.com/eci-spot-price-limit: "0.25" # Maximum hourly price.
spec:
containers:
- name: pi
image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: NeverBehavior:
If inventory or the price condition is not met, the instance is not created.
After creation, the 1-hour protection period begins. After the period expires, the instance is released if the market price exceeds $0.25 or inventory is insufficient.
Example 2: Specify vCPU count and memory size with market-price bidding
Use SpotAsPriceGo to automatically bid at the current market price. Specify the instance size either through pod resource limits or through an annotation.
Option A: Use pod resource limits
apiVersion: batch/v1
kind: Job
metadata:
name: test
spec:
template:
metadata:
labels:
app: perl
alibabacloud.com/eci: "true"
annotations:
k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo" # Bid at market price.
spec:
containers:
- name: pi
image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
resources:
limits:
cpu: 2000m # 2 vCPUs
memory: 4096Mi # 4 GiB
restartPolicy: NeverOption B: Use the spec annotation
apiVersion: batch/v1
kind: Job
metadata:
name: test
spec:
template:
metadata:
labels:
app: perl
alibabacloud.com/eci: "true"
annotations:
k8s.aliyun.com/eci-use-specs: "2-4Gi" # 2 vCPUs, 4 GiB (minimum 2 vCPUs).
k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo" # Bid at market price.
spec:
containers:
- name: pi
image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: NeverBoth options create a 2 vCPU, 4 GiB instance with a 1-hour protection period.
Example 3: Disable the protection period
Example 4: Fall back to pay-as-you-go if spot inventory is insufficient
Set eci-spot-fallback to true to automatically create a pay-as-you-go instance when spot inventory is unavailable.
apiVersion: batch/v1
kind: Job
metadata:
name: test
spec:
template:
metadata:
labels:
app: perl
alibabacloud.com/eci: "true"
annotations:
k8s.aliyun.com/eci-use-specs: "ecs.c6.large"
k8s.aliyun.com/eci-spot-strategy: "SpotWithPriceLimit"
k8s.aliyun.com/eci-spot-price-limit: "0.05"
k8s.aliyun.com/eci-spot-fallback: "true" # Fall back to pay-as-you-go.
spec:
containers:
- name: pi
image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: NeverBehavior:
If spot inventory is sufficient: a spot instance is created with a 1-hour protection period.
If spot inventory is insufficient: a pay-as-you-go instance is created. The system does not auto-release it.
To verify which type was created, run kubectl describe pod and check the Events section. A SpotDegraded event indicates the instance is pay-as-you-go.

Monitor and handle instance release
Detect an upcoming release
A SpotToBeReleased event is generated approximately 3 minutes before a spot instance is released. Use kubectl describe or kubectl get events to monitor for this event.
# kubectl describe output
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning SpotToBeReleased 3m32s kubelet, eci Spot ECI will be released in 3 minutes# kubectl get events output
LAST SEEN TYPE REASON OBJECT MESSAGE
3m39s Warning SpotToBeReleased pod/pi-frmr8 Spot ECI will be released in 3 minutesCheck the status after release
After release, billing stops, the ECI instance status changes to Expired, and the pod status changes to Failed with reason BidFailed.
# kubectl get pod output
NAME READY STATUS RESTARTS AGE
pi-frmr8 1/1 BidFailed 0 3h5m# kubectl describe output
Status: Failed
Reason: BidFailed
Message: The pod is spot instance, and have been released at 2020-04-08T12:36ZGraceful termination
To enable graceful termination when a spot instance is reclaimed, add the k8s.aliyun.com/eci-spot-release-strategy: api-evict annotation to your pod. When a virtual node receives a SpotToBeReleased event, it calls the Kubernetes Eviction API to evict the pod gracefully instead of terminating it immediately.
Graceful termination via the Eviction API requires ack-virtual-node 2.11.0 or later. For more information, see ACK Virtual Node.
When the virtual node receives the SpotToBeReleased event, the ContainerInstanceExpired condition is set to true on the pod, and the eviction sequence begins:
The virtual node calls the Eviction API.
The API server checks the PodDisruptionBudget (PDB) for the pod.
The pod's deletion timestamp is updated with the configured grace period. The API server marks the pod for termination.
The kubelet on the virtual node initiates graceful termination.
The control plane disassociates the pod from Endpoints and EndpointSlices. After the grace period (
terminationGracePeriodSeconds) expires, the kubelet forcefully terminates the pod.The kubelet notifies the API server, which deletes the pod.
If the pod is managed by a ReplicaSet, StatefulSet, Job, SparkApplication, or a workflow configured with fault tolerance settings, the controller automatically creates a replacement pod after eviction.
If the PDB is misconfigured or a large number of pods are not in the Ready state, eviction may stall. If eviction is not complete when the instance expires, the instance is released immediately regardless.What's next
Store critical data on independent disks or external storage such as Apsara File Storage NAS to protect it from instance release.
Configure a PodDisruptionBudget (PDB) to control how many pods can be evicted simultaneously.
For graceful termination, update ack-virtual-node to 2.11.0 or later.