Table of Contents

EVE-OS Images

EVE-OS Images are the operating system firmware for edge nodes. They are distinct from application images – they are the OS itself, not a workload. ZEDEDA Cloud manages metadata, version tracking, and distribution; EVE-OS handles the update process on the node using an A/B partition scheme.

Like application images, ZEDEDA Cloud does not store the EVE-OS binary. You upload the rootfs image to a datastore, then register a metadata record in ZEDEDA Cloud pointing to it.

EVE-OS Variants

The variant you choose determines what workloads the node can run and whether clustering is supported. You cannot switch between variants on a running node – a variant change requires reinstallation.

Variant Suffix Workloads Clustering Notes
EVE-KVM kvm VMs (KVM/QEMU) and OCI containers No Standard variant. Most common for industrial edge. Covered in this workshop.
EVE-k k VMs and OCI containers Yes (ZEDEDA managed) Bare-metal Kubernetes support. Replaced EVE-Kubevirt in 16.0 LTS. Requires 12-core CPU, 16 GB RAM, NVMe.
EVE-Kubevirt kubevirt VMs and OCI containers Yes (ZEDEDA managed) Legacy clustering variant from 14.5.0. Superseded by EVE-k in 16.0.

You cannot update from EVE-KVM to EVE-k (or vice versa). The rootfs partition layout differs. A variant change requires reflashing the node.

EVE-k is a Managed Kubernetes Infrastructure Layer

EVE-k embeds a k3s control plane inside EVE-OS to enable edge node clustering and the ZEDEDA Edge Kubernetes Service. It is important to understand what this means for operators:

In short: EVE-k gives you clustered infrastructure managed by ZEDEDA. Your workflow as an operator does not change – you still define App Bundles and App Instances through ZEDEDA Cloud.

Image Naming Convention

EVE-OS image names follow the pattern:

VERSION-lts-VARIANT-ARCH

Examples: * 16.0.0-lts-kvm-amd64 – version 16.0.0 LTS, KVM variant, x86-64 * 16.8.0-k-amd64 – version 16.8.0, EVE-k variant, x86-64 (RC/custom, no lts tag) * 14.5.2-lts-kvm-arm64 – version 14.5.2 LTS, KVM variant, ARM64 * 16.0.0-rc6-kvm-amd64 – release candidate 6 of 16.0.0, KVM, x86-64

The -lts tag denotes an officially supported Long Term Support version. RC and custom builds omit it. The ZEDEDA GUI only shows LTS images for upgrade. Custom, RC, and non-LTS images must be registered via Terraform or ZCLI.

Terraform Examples

EVE-KVM Release Candidate (custom datastore)

A pre-release or custom EVE-KVM image served from a local HTTP datastore. This is the pattern for testing RC builds before promoting to production nodes.

resource "zedcloud_image" "demo_sjc_eve_OS_image_16" {
  name                = "16.0.0-rc6-kvm-amd64"
  title               = "16.0.0-rc6-kvm-amd64"
  datastore_id        = zedcloud_datastore.demo_sjc_ds.id
  image_type          = "IMAGE_TYPE_EVE"
  image_arch          = "AMD64"
  image_format        = "RAW"
  image_sha256        = "6fdefb5dee42429765403a3dfa40b5471ffd5a626944679da728de8a6d2ddbfc"
  image_size_bytes    = 302092288
  project_access_list = []
  image_rel_url       = "eve-16.0.0-rc6-kvm-amd64.img"
}

Notes: * image_type = “IMAGE_TYPE_EVE” – this is what distinguishes an EVE-OS image from an app image * image_format = “RAW” – EVE-OS rootfs images are always RAW format * image_size_bytes and image_sha256 are required – EVE-OS verifies the download before writing to the inactive partition * The name should match the version string exactly for clarity when managing multiple versions

EVE-k Image

The EVE-k variant (Kubernetes-enabled) uses the same structure. The only difference is the variant suffix in the name and image_rel_url:

resource "zedcloud_image" "demo_sjc_eve_OS_image_16_k" {
  name                = "16.8.0-k-amd64"
  title               = "16.8.0-k-amd64"
  datastore_id        = zedcloud_datastore.demo_atl_ds.id
  image_type          = "IMAGE_TYPE_EVE"
  image_arch          = "AMD64"
  image_format        = "RAW"
  image_sha256        = "1d8170e4187e9c9342e59ff2db91c71b9d19fae1360eef3dc9c618b5ed9ed290"
  image_size_bytes    = 394297344
  project_access_list = []
  image_rel_url       = "16.8.0-k-amd64.rootfs"
}

Note the file extension: .rootfs vs .img – both are valid RAW format rootfs images. The extension depends on how the image was generated and named when placed in the datastore.

Assigning an EVE-OS Image to an Edge Node (base_image)

Registering the image record is only step one. To actually upgrade a node, you assign the image via the base_image block on the edge node resource.

Terraform: base_image block

resource "zedcloud_edgenode" "demo_node" {
  name       = "demo-edge-node-01"
  title      = "Demo Edge Node 01"
  model_id   = var.device_model_id
  project_id = zedcloud_project.demo_project.id
  base_image {
    image_name = "16.0.0-rc6-kvm-amd64"
    version    = "16.0.0-rc6-kvm-amd64"
    activate   = true
  }
}

Key fields in base_image:

Field Description
image_name Must exactly match the name field of a registered EVE-OS image record in your enterprise.
version The version string – typically the same as image_name for EVE-OS images.
activate When true, ZEDEDA Cloud schedules the upgrade on the node at next heartbeat. Set to false to stage without activating.

The base_image block is commented out by default in many Terraform configs because it triggers an OS upgrade immediately when activate = true. Uncomment and apply deliberately.

ZEDUI: Upgrade via GUI (LTS only)

The ZEDEDA GUI can upgrade nodes to LTS versions that are already registered in your enterprise or available in the ZEDEDA-managed catalog:

  1. Navigate to Edge Nodes and select the target node
  2. Click the Software tab
  3. Under EVE-OS Version, click Edit
  4. Select the target LTS version from the dropdown
  5. Click Save – the upgrade is scheduled for next heartbeat

Important: the GUI dropdown only shows LTS images. RC builds, custom images, and non-LTS versions do not appear in the GUI. To upgrade to those, use Terraform or ZCLI.

ZCLI: Upgrade

# Assign an EVE-OS image to a specific edge node
zcli edge-node update MY-EDGE-NODE \
  --eve-image=16.0.0-rc6-kvm-amd64
# Or mark an image as the enterprise default for an architecture
# (all nodes without an explicit assignment pick this up)
zcli image mark-latest 16.0.0-lts-kvm-amd64 --image-arch=AMD64

Upgrading an EVE-k Cluster

Upgrading a cluster is a single command that rolls the upgrade across all nodes sequentially. ZEDEDA handles the ordering – it upgrades one node at a time, waits for it to check back in successfully, then moves to the next. This prevents the entire cluster from going offline simultaneously.

ZCLI: Upgrade

zcli edge-node-cluster upgrade ss-cluster1-pci --image=16.8.0-k-amd64

This targets the cluster by name and assigns the specified EVE-k image to all member nodes. The image must already be registered in ZEDEDA Cloud (see Terraform/ZCLI image registration above).

Monitor Progress

zcli edge-node-cluster show ss-cluster1-pci --upgrade

Example output:

NodeID                               UpgradeableEveOS  Status             UpdatedAt
------------------------------------ ----------------  -----------------  ---------------------------
60df8932-13de-4474-9853-25c9ef867a49 16.8.0-k-amd64   STATUS_COMPLETED   2026-02-27T12:11:04.077771Z
6c38a8ae-54e7-4f58-9e2c-23bc7b1f9e14 16.8.0-k-amd64   STATUS_COMPLETED   2026-02-27T12:26:22.208999Z
5e196606-bc80-4ea7-a01c-b16ea7136430 16.8.0-k-amd64   STATUS_COMPLETED   2026-02-27T12:41:43.899942Z

The UpdatedAt timestamps show each node completing roughly 15 minutes apart – that is the sequential per-node upgrade cadence. Each node downloads the new image, writes it to the standby partition, reboots, checks in, and only then does ZEDEDA trigger the next node in the cluster.

Possible status values:

Status Meaning
STATUS_COMPLETED Node has rebooted into the new version and checked in successfully
STATUS_IN_PROGRESS Download, write, or reboot in progress on this node
STATUS_FAILED Upgrade failed; node has auto-rolled back to the previous partition

Terraform: Cluster Upgrade

Terraform cluster upgrade support via zedcloud_edge_node_cluster is not fully documented at the time of writing. The recommended approach for cluster upgrades is ZCLI (shown above) or the ZEDEDA API. The image registration itself (the zedcloud_image resource for the EVE-k image) is done in Terraform as shown in the examples above – the upgrade trigger is then done via ZCLI referencing that image name.

If you want to drive it from code, the API call is:

POST /v1/edge-node-clusters/{cluster_id}/upgrade
{
  "eveImageName": "16.8.0-k-amd64"
}

Important Notes for Cluster Upgrades

How to Get and Register a Custom EVE-OS Image

This is the full workflow for a custom or RC image – required because the GUI upload is not supported for EVE-OS images.

Step 1: Pull the rootfs image from Docker Hub

# KVM variant, AMD64
docker run --rm lfedge/eve:16.0.0-rc6-kvm-amd64 rootfs > eve-16.0.0-rc6-kvm-amd64.img
# EVE-k variant, AMD64
docker run --rm lfedge/eve:16.8.0-k-amd64 rootfs > 16.8.0-k-amd64.rootfs

Step 2: Get the SHA256 and size

sha256sum eve-16.0.0-rc6-kvm-amd64.img
stat -c %s eve-16.0.0-rc6-kvm-amd64.img

Step 3: Upload to your datastore (copy to your HTTP server, S3 bucket, or Azure container)

Step 4: Register the image in ZEDEDA Cloud via ZCLI

# Create the image record
zcli image create 16.0.0-rc6-kvm-amd64 \
  --arch=AMD64 \
  --datastore-name=TF-ATL-ZED-DEMO-DS \
  --type=Eve \
  --image-format=RAW \
  --title=16.0.0-rc6-kvm-amd64
# Uplink (associate SHA256 and size)
zcli image uplink 16.0.0-rc6-kvm-amd64 \
  --datastore-name=TF-ATL-ZED-DEMO-DS \
  --image-sha=6fdefb5dee42429765403a3dfa40b5471ffd5a626944679da728de8a6d2ddbfc \
  --image-size=302092288

Or do both steps in one Terraform apply using the resource block shown above.

How Upgrades Work on the Node

EVE-OS uses an A/B partition scheme – two OS partitions, one active and one standby:

  1. The controller delivers the desired EVE-OS version to the node at next heartbeat
  2. EVE-OS compares the desired version to the currently running version
  3. If different, EVE-OS downloads the new rootfs image from the datastore directly
  4. The downloaded image is verified against the registered SHA256 hash
  5. The verified image is written to the inactive (standby) partition
  6. EVE-OS sets the standby partition as the next boot target and reboots
  7. After reboot, the new version runs and checks in with the controller
  8. If the node fails to check in within the timeout window, EVE-OS automatically rolls back to the previous partition and reports an error
  9. The controller updates the node's recorded version after successful check-in

This means upgrades are atomic and self-healing: a failed upgrade reverts automatically without manual intervention.

LTS vs Custom Images: Method Matrix

Method LTS Images Custom / RC Images Cluster Upgrade
ZEDUI Yes – dropdown shows available LTS No – custom images do not appear No
ZCLI Yes Yes – requires image create + uplink first Yes – zcli edge-node-cluster upgrade
Terraform Yes Yes – requires image resource + base_image block Partial – use ZCLI or API to trigger
API Yes Yes – requires POST /v1/images then PATCH /v1/devices Yes – POST /v1/edge-node-clusters/{id}/upgrade

API

# Register a custom EVE-OS image
POST /v1/images
{
  "name": "16.0.0-rc6-kvm-amd64",
  "imageType": "IMAGE_TYPE_EVE",
  "imageArch": "AMD64",
  "imageFormat": "RAW",
  "datastoreId": "<datastore_id>",
  "imageRelUrl": "eve-16.0.0-rc6-kvm-amd64.img",
  "imageSha256": "6fdefb5dee42429765403a3dfa40b5471ffd5a626944679da728de8a6d2ddbfc",
  "imageSizeBytes": 302092288
}
# Assign to an edge node
PATCH /v1/devices/{device_id}
{
  "eveImageName": "16.0.0-rc6-kvm-amd64",
  "eveImageVersion": "16.0.0-rc6-kvm-amd64"
}