- CLI instead of Helm: Kubernetes with potctl (
KubernetesControlPlaneYAML). - Linux hosts over SSH: Remote control plane.
Deploy the control plane on Kubernetes with Helm
This guide installs Datasance PoT on Kubernetes using the iofog-operator Helm chart 3.9.3. The chart deploys the operator Deployment and a ControlPlane custom resource with apiVersion: datasance.com/v3. The operator reconciles Controller, Router, NATS, Services, Secrets, and an Ingress when the Controller Service is ClusterIP.
Chart 3.9.2 values are flat. auth, images, database, services, controller, nats, vault, and events sit at the top of values.yaml. The templates build the ControlPlane spec from those keys. The chart always installs the CRD, RBAC, and one ControlPlane.
The legacy repo Datasance/helm (chart pot, https://datasance.github.io/helm) is deprecated. Use the Helm repository index linked below.
| Reference | Where to read |
|---|---|
Every ControlPlane spec field | ControlPlane CRD |
| Controller, Router, NATS TLS on cluster | Securing Kubernetes cluster (operator) |
| CLI trust when the API uses HTTPS | Kubernetes TLS (CLI YAML) (spec.ca / connect --ca) |
| Auth bootstrap | Embedded OIDC |
Published chart defaults: Helm repository index. values.yaml is the install contract. marketplace-values.yaml on that index is the marketplace form. Do not pass it as a second -f file.
Prerequisites
- Helm 3
- Kubernetes 1.22+
- kubectl
- Pull access to ghcr.io/datasance (operator, controller, router, nats)
- For NATS JetStream with PVCs: a suitable StorageClass
Charts are stamped per mirror at package time (CRD group, default ControlPlane name, and image tags). Do not override the CRD group or image registry unless you run a custom build.
Add the Helm repository
helm repo add iofog-operator https://datasance.github.io/iofog-operator
helm repo update
Download defaults for editing:
helm show values iofog-operator/iofog-operator --version 3.9.3 > my-values.yaml
Or use the files on the index page: https://datasance.github.io/iofog-operator/values.yaml and values-3.9.3.yaml.
Quick install
Embedded OIDC is the default. Set a bootstrap password of at least 12 characters, with one uppercase letter and one special character. Prefer a Secret in production (auth.bootstrap.passwordSecretRef in values).
helm install pot iofog-operator/iofog-operator \
--namespace iofog-system --create-namespace \
--version 3.9.3 \
--set auth.bootstrap.password='ReplaceMe1!x'
name overrides the ControlPlane resource name. Leave it empty to use the flavor default (pot or iofog). The Helm release name does not set that name.
See Embedded OIDC for console URLs and bootstrap behavior.
Install with a values file
name: ""
images:
controller: ghcr.io/datasance/controller:3.9.2
router: ghcr.io/datasance/router:3.9.2
nats: ghcr.io/datasance/nats:2.15.1-1
auth:
mode: embedded
bootstrap:
username: admin
password: "ReplaceMe1!x"
database:
provider: sqlite
replicas:
controller: 1
nats: 2
services:
controller:
type: LoadBalancer
router:
type: LoadBalancer
nats:
type: LoadBalancer
natsServer:
type: ClusterIP
controller:
publicUrl: https://controller.example.com
consoleUrl: https://console.example.com
nats:
memoryStoreSize: 1
storageSize: 10
helm install pot iofog-operator/iofog-operator \
--namespace iofog-system --create-namespace \
--version 3.9.3 \
-f my-values.yaml
Database: chart default is SQLite (single Controller replica). For HA, set replicas.controller greater than 1 and configure Postgres under database. See Database installation.
NATS: the chart always installs NATS. replicas.nats must be at least 2. nats.memoryStoreSize and nats.storageSize are whole numbers of Gi (1 becomes 1Gi on the custom resource).
LoadBalancer and externalTrafficPolicy
Defaults use LoadBalancer for Controller, Router, and the NATS TLS Service (services.nats). services.natsServer defaults to ClusterIP, so the non-TLS client port is not published.
externalTrafficPolicy is auto, Local, or Cluster. auto omits the field. The operator then uses Local on LoadBalancer Services and Cluster on NodePort.
- Local preserves client source IP on many cloud load balancers.
- Cluster can help when Services stay pending or your LB controller does not support Local well.
services:
controller:
type: LoadBalancer
externalTrafficPolicy: Cluster
router:
type: LoadBalancer
externalTrafficPolicy: Cluster
Leave annotations null when you have none. Set a map, or one key: value line per annotation. Quote values that YAML would read as booleans or numbers, such as "on" or "443".
Use Ingress instead of LoadBalancer when you have an ingress controller. Set services.controller.type to ClusterIP, set controller.https to true, and set services.controller.ingress.host. Field list: ControlPlane CRD - ingresses.
Production TLS
When controller.https is true, set controller.tls.source to existing or create.
existingusescontroller.tls.secretName(for cert-manager, the Secret the issuer will create).createtakes PEMcontroller.tls.crt,controller.tls.key, and optional PEMcontroller.tls.ca. The chart stores them in Secretcontroller-tls.
Patterns (LoadBalancer + pod TLS, Ingress, Router/NATS Secrets, cert-manager) are documented in Securing Kubernetes cluster (operator).
External database TLS uses database.ssl and database.ca (ca is base64 PEM, written only when ssl is true). See CRD - database.
External auth
helm upgrade pot iofog-operator/iofog-operator \
--namespace iofog-system \
--version 3.9.3 \
--set auth.mode=external \
--set auth.issuerUrl=https://auth.example.com/realms/myrealm \
--set auth.client.id=controller \
--set auth.client.secret='YOUR_SECRET'
For an issuer signed by a private CA, also set auth.issuerCa to the base64 PEM CA or bundle. Leave it empty for a public CA. Certificate checks stay on. See External OIDC and External OIDC providers.
Verify
kubectl get pods -n iofog-system
kubectl get svc -n iofog-system
kubectl get controlplanes.datasance.com -n iofog-system
Wait until the ControlPlane status is Ready and Controller, Router, and NATS workloads are available.
Upgrade
Rewrite a values file from chart 3.9.1 before you upgrade. Those files used controlplane.spec, crds.install, and controlplane.create. Chart 3.9.2 ignores that shape.
If the previous release left the NATS TLS Service on ClusterIP and you want that to stay, set services.nats.type: ClusterIP in the new file. The chart default is LoadBalancer.
helm upgrade pot iofog-operator/iofog-operator \
--namespace iofog-system \
--version 3.9.3 \
-f my-values.yaml
Platform train v3.9.2 supports an in-place upgrade from v3.9.1, v3.9.0, or v3.8.0 on the same Controller database. See Upgrading to v3.9.2 and Operator.
v3.7.x and the legacy Helm chart require a greenfield move to v3.8+ (uninstall the old operator and CRDs first). See Migrating to v3.8.0.
Helm does not upgrade CRDs on helm upgrade. The CRD in this chart is installed with the release. Apply the chart CRDs when you need the new auth.issuerCa field on an existing cluster.
Uninstall
helm uninstall pot -n iofog-system
kubectl delete controlplanes.datasance.com --all -n iofog-system
CRDs remain unless you remove them cluster-wide (only when no ControlPlane instances exist):
kubectl delete crd controlplanes.datasance.com
Connect with potctl
After the stack is ready, connect potctl in the same namespace you used for Helm (iofog-system in the examples above):
potctl create namespace iofog-system
potctl connect --email [email protected] --kube ~/.kube/config --namespace iofog-system
Sign in with the embedded bootstrap user you configured in values. If the Controller API uses HTTPS with a private CA, use connect --ca as described in Kubernetes TLS (CLI YAML).
Values reference
| Area | Values keys |
|---|---|
| ControlPlane name | name. Empty uses the flavor default |
| Images | images.operator, images.controller, images.router, images.nats, images.pullSecret |
| Auth | auth.mode, auth.bootstrap, auth.issuerUrl, auth.issuerCa, auth.client |
| Database | database.provider, database.host, database.ca |
| Services | services.controller, services.router, services.nats, services.natsServer |
| NATS disk | nats.memoryStoreSize, nats.storageSize (whole Gi), nats.storageClassName |
| Events | events.cleanupIntervalHours (minimum 2). The chart writes seconds on the custom resource |
Full chart reference: iofog-operator chart README.
Go to Set up Edgelet nodes to provision Edgelet v1.1.2 on edge hosts.