In this tutorial, we will install the Eclipse ioFog Control Plane on Kubernetes using Helm.
The Helm Chart deploys the ioFog operator (iofog-operator) and creates a ControlPlane custom resource instance automatically. The Operator consumes this CRD and creates deployments for the Controller, Router, and (when enabled) NATs, as well as associated services. Image versions (e.g. operator 3.7.0, controller, router, NATs) are configurable in the chart values; see the Control Plane YAML Specification for NATs and Router options.
apiextensions.k8s.io/v1 CRDsAdd the Datasance Helm repotsitory to your local index:
helm repo add datasance https://datasance.github.io/helm
helm repo updateInstall the Chart while specifying the required authentication configuration. The chart requires Keycloak/OpenID Connect authentication settings. You can provide these values either via a values file or using --set flags.
helm install pot-operator datasance/pot -n pot --create-namespace \
--set controlplane.spec.auth.url=https://keycloak.example.com \
--set controlplane.spec.auth.realm=pot \
--set controlplane.spec.auth.realmKey=master \
--set controlplane.spec.auth.ssl=true \
--set controlplane.spec.auth.controllerClient=pot-controller \
--set controlplane.spec.auth.controllerSecret=supersecret \
--set controlplane.spec.auth.viewerClient=pot-viewerCreate a myvalues.yaml file with your configuration:
operator:
image: ghcr.io/eclipse-iofog/operator:3.7.2
controlplane:
spec:
replicas:
controller: 1
nats: 2
nats:
enabled: true
# Database is optional; if omitted, the controller uses internal SQLite.
# When using SQLite, keep controller replicas at 1.
database:
provider: postgres
host: db
port: 5432
user: pot
password: changeme
databaseName: pot
ssl: false
auth:
url: https://keycloak.example.com
realm: pot
realmKey: master
ssl: true
controllerClient: pot-controller
controllerSecret: supersecret
viewerClient: pot-viewerThen install using the values file:
helm install pot-operator datasance/pot -n pot --create-namespace \
-f pot-operator-values.yamlThe install creates:
controlplanes.datasance.comcontrolplane.create)To list all Helm releases, run:
helm list -n potThe result should look like this:
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
pot-operator 1 Tue Dec 8 21:34:42 2025 DEPLOYED pot-3.7.0 3.7.0 potEdit values.yaml or provide your own overrides (e.g. test-values.yaml). Key sections:
operator.*: image, replicaCount, resources, scheduling, extraEnv/extraArgs, serviceAccount, RBAC.controlplane.*: metadata and full ControlPlane .spec (auth, database, controller, events, images, services, nats, ingresses, vault, replicas).crds.install: whether to install the ControlPlane CRD.Must be set via values or --set:
controlplane.spec.auth.url, realm, realmKey, ssl, controllerClient, controllerSecret, viewerClientcontrolplane.spec.database with at least provider, host, port, user, password, databaseName. For SQLite use provider: sqlite with empty host/port/user/password/databaseName as needed.operator.image (default ghcr.io/eclipse-iofog/operator:3.7.2), operator.replicaCount, operator.resources, operator.nodeSelector, operator.tolerations, operator.affinity, operator.serviceAccount.create|name, operator.imagePullSecretscontrolplane.create, controlplane.name, controlplane.namespacecontrolplane.spec.replicas.controller, controlplane.spec.replicas.nats (min 2 when NATs enabled)controlplane.spec.images.controller, router, nats, pullSecretcontrolplane.spec.services.controller|router|nats|natsServer with type, address, annotations, externalTrafficPolicy (e.g. Local or Cluster)controlplane.spec.nats.enabled, controlplane.spec.nats.jetStream.memoryStoreSize, storageSize, storageClassNamecontrolplane.spec.controller.logLevel, https, secretName, pidBaseDir, ecn, ecnViewerPort, ecnViewerUrlcontrolplane.spec.ingresses.controller|router|nats (host, ingressClassName, address, ports)controlplane.spec.events.auditEnabled, retentionDays, cleanupInterval, captureIpAddresscontrolplane.spec.vault.enabled, provider, basePath, and provider-specific config (hashicorp, aws, azure, google)helm install pot datasance/pot -n pot --create-namespace \
--set controlplane.spec.auth.url=https://keycloak.example.com \
--set controlplane.spec.auth.realm=pot \
--set controlplane.spec.auth.realmKey=master \
--set controlplane.spec.auth.ssl=external \
--set controlplane.spec.auth.controllerClient=pot-controller \
--set controlplane.spec.auth.controllerSecret=supersecret \
--set controlplane.spec.auth.viewerClient=pot-viewer \
--set controlplane.spec.database.provider=sqlite \
--set controlplane.spec.database.host="" \
--set controlplane.spec.database.port=0 \
--set controlplane.spec.database.user="" \
--set controlplane.spec.database.password="" \
--set controlplane.spec.database.databaseName="" \
--set controlplane.spec.database.ssl=falseoperator:
image: ghcr.io/eclipse-iofog/operator:3.7.2
controlplane:
create: true
name: pot
spec:
# Database is required in CRD v3. Use sqlite for single-replica or postgres for HA.
database:
provider: postgres
host: db
port: 5432
user: pot
password: changeme
databaseName: pot
ssl: false
ca: ""
auth:
url: https://keycloak.example.com
realm: pot
realmKey: master
ssl: external
controllerClient: pot-controller
controllerSecret: supersecret
viewerClient: pot-viewer
replicas:
controller: 1
nats: 2
images:
controller: ghcr.io/eclipse-iofog/controller:3.7.3
router: ghcr.io/eclipse-iofog/router:3.7.0
nats: ghcr.io/eclipse-iofog/nats:2.12.4
services:
controller:
type: LoadBalancer
router:
type: LoadBalancer
nats:
type: LoadBalancer
natsServer:
type: LoadBalancer
nats:
enabled: trueFrom the repo root:
helm lint charts/pothelm upgrade pot datasance/pot -n pot -f myvalues.yamlFor a local chart:
helm upgrade pot ./charts/pot -n pot -f test-values.yamlhelm uninstall pot -n potNote: CRDs remain by default after uninstallation. Remove them manually if desired:
kubectl delete crd controlplanes.datasance.comOnce the installation is complete, you can connect to the Controller using iofogctl. Make sure the --namespace matches the one used during helm install:
iofogctl create namespace pot
iofogctl connect --email foo.bar@example.com --kube ~/.kube/config --namespace potiofogctl create namespace pot
iofogctl connect --email foo.bar@example.com --name pot --ecn-addr <http://controller-endpoint:51121> -n potYou will need to authenticate using your Keycloak credentials configured during installation.