OpenKruise V1.9 Release, API v1beta1, Cron Imagepulling, and More
OpenKruise (https://github.com/openkruise/kruise) is an open-source cloud-native application automation management suite. It is also a current incubating project hosted by the Cloud Native Computing Foundation (CNCF). It is a standard extension component based on Kubernetes that is widely used in production of internet scale company. It also closely follows upstream community standards and adapts to the technical improvement and best practices for internet-scale scenarios.
OpenKruise has released the latest version v1.9.0 on June 21, 2026 (ChangeLog). This release brings API upgrades to v1beta1, Windows node support, and several new features. This article introduces the key features in detail and briefly covers other notable changes.
Upgrade Noticeโ
- Kubernetes dependency has been updated to v1.32.6 and Golang to v1.23. Make sure your cluster is compatible.
- API v1alpha1 โ v1beta1: BroadcastJob, AdvancedCronJob, ImagePullJob, ImageListPullJob, NodeImage, Advanced DaemonSet, and SidecarSet APIs have been upgraded from v1alpha1 to v1beta1. The v1alpha1 APIs are still supported but deprecated, and conversion webhooks handle automatic migration transparently. Users are strongly encouraged to update their manifests to v1beta1 before upgrading to OpenKruise v2.0.
In addition to the apiVersion change, several fields were updated during the promotion:
SidecarSet field changes:
spec.namespaceis deprecated โ usespec.namespaceSelectorwith thekubernetes.io/metadata.namelabel instead.- The
"apps.kruise.io/sidecarset-custom-version"annotation is replaced by thespec.customVersionfield.
# Before (v1alpha1)
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
annotations:
apps.kruise.io/sidecarset-custom-version: "v1"
spec:
namespace: default
# After (v1beta1)
apiVersion: apps.kruise.io/v1beta1
kind: SidecarSet
metadata:
name: my-sidecarset
spec:
customVersion: v1
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
Advanced DaemonSet field changes:
- The
"daemonset.kruise.io/progressive-create-pod"annotation is replaced byspec.scaleStrategy. status.DaemonSetHashis replaced bystatus.UpdateRevision.spec.partitiontype changed from*int32to*intstr.IntOrStringโ now supports percentage values like50%.spec.updateStrategy.rollingUpdate.type: Surgingis deprecated โ useStandardinstead.
# After (v1beta1) โ partition now supports percentage
apiVersion: apps.kruise.io/v1beta1
kind: AdvancedDaemonSet
spec:
partition: "50%"
updateStrategy:
rollingUpdate:
type: Standard
For the full list of API promotions and field changes, see the API Upgrade Guide.
Note: The v1alpha1 API for Advanced StatefulSet will be removed in OpenKruise v2.0. Other v1alpha1 APIs have no removal plan yet, but migration is recommended to avoid conversion webhook overhead.
Key Featuresโ
UnitedDeployment ReserveUnschedulablePodsโ
In elastic scenarios, you often want to prioritize scheduling Pods on owned node pools (e.g., self-built IDC) and use elastic node pools (e.g., virtual-kubelet) as fallback. The existing Adaptive strategy permanently moves Pods to other subsets when the target subset is unschedulable. However, this means you lose the preferred topology โ even after the original subset recovers, the Pods stay where they were moved.
v1.9.0 introduces reserveUnschedulablePods under the Adaptive scheduling strategy. When enabled, unschedulable Pods are reserved in the target subset, and a temporary replica is created in the next available subset to maintain the expected replica count. Once the target subset becomes schedulable again, the temporary replica is deleted and the reserved Pod is scheduled back to the original subset.
apiVersion: apps.kruise.io/v1alpha1
kind: UnitedDeployment
metadata:
name: sample-ud
spec:
topology:
scheduleStrategy:
type: Adaptive
adaptive:
reserveUnschedulablePods: true
rescheduleCriticalSeconds: 30
subsets:
- name: ecs
nodeSelectorTerm:
matchExpressions:
- key: node-type
operator: In
values: [ecs]
- name: vk
nodeSelectorTerm:
matchExpressions:
- key: node-type
operator: In
values: [virtual-kubelet]
In this example, Pods are prioritized on ECS nodes. When ECS nodes are full, temporary replicas are created on virtual-kubelet nodes. Once ECS capacity is restored (e.g., after node scaling), the temporary replicas are removed and Pods migrate back to ECS.
Limitation: Only works with the Adaptive scheduling strategy. The temporary replica creation is recursive across subsets.
AdvancedCronJob Cron ImagePullJobโ
For AI/ML workloads that use large images (e.g., several GB), pre-pulling images before Pod scheduling significantly reduces startup time. In large model workload clusters, nodes frequently garbage-collect (GC) images due to disk space pressure, so pre-warming needs to be re-run before scheduled tasks to ensure effectiveness. Previously, you had to manually create ImagePullJob resources or use external cron tools. Now you can schedule image pre-pulling as a cron task directly within AdvancedCronJob using the new imageListPullJobTemplate field.
apiVersion: apps.kruise.io/v1beta1
kind: AdvancedCronJob
metadata:
name: acj-image-pull
spec:
schedule: "0 */2 * * *"
concurrencyPolicy: Replace
template:
imageListPullJobTemplate:
spec:
parallelism: 5
images:
- nginx:1.14.2
- busybox:latest
pullSecrets:
- default-secret
selector:
names:
- node1
- node2
pullPolicy:
timeoutSeconds: 60
imagePullPolicy: IfNotPresent
This example creates an ImageListPullJob every 2 hours, pulling the specified images on node1 and node2. The concurrencyPolicy: Replace ensures that if a new job is triggered while the previous one is still running, the old one is replaced.
Limitation: Uses the v1beta1 API. The imageListPullJobTemplate field is available since v1.9.0.
CloneSet progressDeadlineSecondsโ
In CI/CD pipelines, it is important to detect rollout failures early. Without a progress deadline, a stuck rollout (e.g., image pull errors, readiness probe failures) can hang indefinitely without any signal. v1.9.0 adds progressDeadlineSeconds to CloneSet, similar to the native Kubernetes Deployment field.
apiVersion: apps.kruise.io/v1beta1
kind: CloneSet
spec:
replicas: 10
progressDeadlineSeconds: 600
# ...
If the rollout does not progress within 600 seconds, the CloneSet controller adds the following condition to .status.conditions:
type: Progressing
status: "False"
reason: ProgressDeadlineExceeded
Higher-level orchestration systems (e.g., ArgoCD, Flux) can watch this condition to trigger automatic rollbacks.
Limitation: The value must be greater than spec.minReadySeconds. This condition does not stop the underlying rollout โ it only signals the failure. Pausing the rollout also pauses the deadline check.
SidecarSet Dynamic Resourcesโ
Sidecar containers (e.g., service mesh proxies, log agents) often need resources proportional to the main container. Previously, you had to set fixed resource requests/limits for sidecars, which led to either over-provisioning for small Pods or under-provisioning for large Pods.
v1.9.0 introduces resourcesPolicy, which lets you define sidecar resources as expressions based on the target Pod's container resources.
apiVersion: apps.kruise.io/v1beta1
kind: SidecarSet
spec:
containers:
- name: sidecar1
image: centos:6.7
resourcesPolicy:
targetContainersMode: sum
targetContainersNameRegex: ^large-engine-v4$
resourcesExpr:
limits:
cpu: max(cpu*50%, 50m)
memory: 200Mi
requests:
cpu: max(cpu*50%, 50m)
memory: 100Mi
In this example, the sidecar's CPU is set to 50% of the large-engine-v4 container's CPU, with a minimum of 50m. Supported expression operators include +, -, *, /, max(), min(), and Kubernetes resource quantities (e.g., 50m, 200Mi).
Limitation: The cpu and memory variables in the expression represent the aggregated resource values from target containers, calculated based on targetContainersMode (e.g., sum) and targetContainersNameRegex.
PodUnavailableBudget RESIZE Protectionโ
PodUnavailableBudget (PUB) protects application availability by limiting how many Pods can be unavailable simultaneously. Previously, PUB protected against DELETE, EVICT, and UPDATE operations. With the growing adoption of in-place vertical scaling (Kubernetes 1.27+ InPlacePodVerticalScaling), RESIZE operations can also make Pods temporarily unavailable.
v1.9.0 adds RESIZE as a protected operation. You can control which operations are protected via an annotation:
apiVersion: policy.kruise.io/v1alpha1
kind: PodUnavailableBudget
metadata:
name: web-server-pub
annotations:
# By default: DELETE, EVICT, UPDATE are protected
# Add RESIZE to also protect in-place resource resizing
kruise.io/pub-protect-operations: "DELETE, EVICT, UPDATE, RESIZE"
spec:
targetRef:
apiVersion: apps.kruise.io/v1beta1
kind: CloneSet
name: web-server
maxUnavailable: 20%
Limitation: If the InPlacePodVerticalScaling feature gate is disabled, in-place resizing is treated as an UPDATE operation instead.
Other Notable Changesโ
The following features were also introduced in v1.9.0 โ see the documentation for details:
- SidecarSet shareVolumeDevicePolicy: Sidecar containers can now share block devices (VolumeDevices) with other containers in the Pod, analogous to the existing
shareVolumePolicyfor volume mounts. - SidecarSet injection order: SidecarSet now sorts
containersandinitContainersby name in ascending order during injection, ensuring deterministic ordering for sidecars with dependencies. - PodProbeMarker HTTP probe: Supports
httpGetprobes in addition toexecandtcpSocket, enabling direct HTTP health checks without wrappingcurlin exec. - CloneSet OnDelete strategy: A new
podUpdatePolicytype where Pods are only updated when manually deleted โ useful for stateful workloads requiring manual update control. - JobSidecarTerminator exit code control: The
KRUISE_TERMINATE_SIDECAR_IGNORE_EXIT_CODEenv var lets you explicitly control whether a sidecar's non-zero exit code affects Pod Phase. - ImagePullJob node-side concurrency: The
--max-concurrencyflag on kruise-daemon limits concurrent image pulls per node, preventing resource exhaustion. - OpenKruise Daemon Windows support: kruise-daemon now runs on Windows nodes, enabling CRR, image pre-pulling, and PodProbeMarker for Windows workloads.
Other Improvementsโ
Various bug fixes and stability improvements are included in this release. For the full list, see the changelog.
What's Next in v2.0โ
Looking ahead, the next major release (v2.0) will bring two significant changes:
More API upgrades to v1beta1: CloneSet, WorkloadSpread, UnitedDeployment, PersistentPodState, PodUnavailableBudget, PodProbeMarker, and NodePodProbe will be promoted from v1alpha1 to v1beta1. Additionally, the v1alpha1 API for Advanced StatefulSet will be removed in v2.0.
ConfigMapSet โ a new configuration canary release feature: ConfigMapSet is a new CRD currently under active development on the master branch. It enables zero-downtime configuration updates decoupled from image releases โ you can update configuration data (e.g., YAML files, environment variables) and roll it out gradually without rebuilding images. Key capabilities include:
- Version management: Maintains a revision history of configuration versions, allowing rollback to previous versions.
- Configuration canary: Uses
partitioninupdateStrategyto control the rollout percentage, enabling gradual configuration updates. - Container selection: Supports both static container names and dynamic selection via field references (compatible with SidecarSet injection).
- Update strategies: Two modes โ injection-only (default) where the reload sidecar updates configs without restarting containers, and
restartInjectedContainersmode where containers using the configuration are also restarted.
apiVersion: apps.kruise.io/v1alpha1
kind: ConfigMapSet
metadata:
name: deploy-cms
spec:
selector:
matchLabels:
app: sample
data:
settings.yaml: |
value: aaa
containers:
- name: main
mountPath: /data/conf
revisionHistoryLimit: 5
updateStrategy:
partition: 10%
restartInjectedContainers: true
maxUnavailable: 1
Note: ConfigMapSet is still under active development. The API and feature set may change before the official release.
Get Involvedโ
Welcome to get involved with OpenKruise by joining us in Github/Slack/DingTalk/WeChat. Have something you'd like to broadcast to our community? Share your voice at our Bi-weekly community meeting (Chinese), or through the channels below:
- Join the community on Slack (English).
- Join the community on DingTalk: Search GroupID
23330762(Chinese). - Join the community on WeChat (new): Search User
openkruiseand let the robot invite you (Chinese).





