Skip to main content
Version: v3.9.0

Airgap deployment

Use this guide when remote Control Plane hosts or Edgelet node hosts cannot reach the public internet or container registries. potctl runs on a connected operator machine. It pulls or caches artifacts locally, then transfers them over SSH.

This page covers SSH deploy paths only (remote ControlPlane and fleet Agent). Kubernetes and Helm installs are out of scope here.

End-to-end workflow​

  1. Prepare remote hosts (SSH and sudo).
  2. Deploy a remote ControlPlane with spec.airgap: true and pinned image tags.
  3. Deploy fleet Agent documents with spec.airgap: true (recommended: native + package.version).
  4. Apply OfflineImage manifests so microservice images load on nodes before application deploy.
  5. Deploy applications that reference offline catalog entries (Offline images in Learn).

Set spec.airgap: true on the YAML kind, or controllers[].airgap per host when only some Controller hosts are disconnected. Field rules: Remote ControlPlane schema and Multi-controller HA.

Native vs container on edge hosts​

Native + package.version (recommended)Container + package.container.image
Edge host engineEmbedded edgelet engine (default)docker or podman must exist on the host
What potctl stagesEdgelet binary from operator cache (~/.iofog/v3/airgap-binaries/)Container images loaded on the host
Typical useProduction air-gapped edgesStandardize on containerized Edgelet
Container airgap only

For deploymentType: container, remote hosts need a working docker or podman before deploy. Native airgap does not require a separate container engine on the edge host.

Remote ControlPlane​

---
apiVersion: datasance.com/v3
kind: ControlPlane
metadata:
name: remote
spec:
airgap: true
iofogUser:
name: Foo
surname: Bar
controller:
publicUrl: https://controller.example.com:51121
consoleUrl: https://console.example.com:8008
package:
image: ghcr.io/datasance/controller:v3.9.0
auth:
mode: embedded
bootstrap:
username: admin
password: "LocalTest12!"
systemMicroservices:
router:
amd64: ghcr.io/datasance/router:3.9.0
arm64: ghcr.io/datasance/router:3.9.0
riscv64: ghcr.io/datasance/router:3.9.0
arm: ghcr.io/datasance/router:3.9.0
nats:
amd64: ghcr.io/datasance/nats:2.14.3
arm64: ghcr.io/datasance/nats:2.14.3
riscv64: ghcr.io/datasance/nats:2.14.3
arm: ghcr.io/datasance/nats:2.14.3
nats:
enabled: true
controllers:
- name: remote-1
host: 10.0.23.66
ssh:
user: admin
keyFile: ~/.ssh/id_rsa
systemAgent:
package:
version: "1.1.0"
config:
deploymentType: native
containerEngine: edgelet
arch: amd64
host: 192.168.139.148
potctl deploy -f controlplane.yaml

With spec.airgap: true, potctl downloads Controller, Router, NATS, debugger, and system Edgelet artifacts on the operator machine and transfers them over SSH.

Requirements:

  • Set controllers[].systemAgent.config.arch on every controller when airgap is enabled (global or per-host).
  • List all four architecture keys under systemMicroservices when the fleet mixes CPU types.
  • Pin controller.package.image and router tags to your v3.9.0 train.

Custom bootstrap scripts: controllers[].systemAgent.scripts (same merge rules as fleet Agent). Embedded layers live in the CLI repo: assets/edgelet.

Full ControlPlane field reference: Remote deploy guide.

---
apiVersion: datasance.com/v3
kind: Agent
metadata:
name: edge-airgap-1
spec:
host: 10.0.0.51
ssh:
user: ubuntu
keyFile: ~/.ssh/id_rsa
airgap: true
package:
version: "1.1.0"
config:
arch: amd64
deploymentType: native
containerEngine: edgelet
upstreamRouters:
- default-router
routerConfig:
routerMode: edge
messagingPort: 5671
upstreamNatsServers:
- default-nats-hub
natsConfig:
natsMode: leaf
natsServerPort: 4222

Set spec.airgap: true, pin spec.package.version, and set spec.config.arch. potctl stages the Edgelet binary and runs the default bootstrap on the host.

First-time remote install steps: Setup Edgelet nodes.

Container airgap (alternative)​

When Edgelet runs as a container on the edge host, pre-install docker or podman, then use:

---
apiVersion: datasance.com/v3
kind: Agent
metadata:
name: edge-container-airgap
spec:
host: 192.168.139.148
ssh:
user: foo
keyFile: ~/.ssh/id_rsa
port: 22
airgap: true
package:
container:
image: ghcr.io/datasance/edgelet:1.1.0
config:
deploymentType: container
containerEngine: docker
arch: arm64

potctl pulls Edgelet, Router, NATS, and debugger images on the operator machine, transfers them over SSH, and loads them into the host engine.

OfflineImage for microservices​

Edgelet nodes still cannot pull application images at runtime in an air-gapped site. Use kind: OfflineImage after agents exist in the namespace.

Offline images in Learn is the reference for multi-arch keys (amd64, arm64, riscv64, arm), spec.auth, and CLI flags (--no-cache, --transfer-pool).

Steps:

  1. Define OfflineImage YAML with image tags per architecture and spec.agent names (remote Agent only).
  2. Run potctl deploy -f offline-image.yaml. potctl pulls on the operator machine, transfers over SSH, and loads images on each node. Catalog items use registry from_cache (ID 2).
  3. Deploy microservices that reference the offline catalog name.

Example:

---
apiVersion: datasance.com/v3
kind: OfflineImage
metadata:
name: my-app-offline
spec:
amd64: ghcr.io/datasance/my-app:1.0
arm64: ghcr.io/datasance/my-app:1.0
agent:
- edge-airgap-1
- edge-airgap-2

Deploy order: Control Plane → fleet Agents → OfflineImage → applications.

For the full platform path, see Platform deployment introduction.

Group 3See anything wrong with the document? Help us improve it!