Article
· 22 hr ago 4m read

IKO Plus: Launching Airgapped IrisClusters with Hauler

"Haul" a Portable Registry for Airgapped IrisClusters

Rancher Government Hauler streamlines deploying and maintaining InterSystems container workloads in air-gapped environments by simplifying how you package and move required assets. It treats container images, Helm charts, and other files as content and collections, letting you fetch, store, and distribute them declaratively or via CLI — without changing your existing workflows.   Meaning your charts and what have yous, can have conditionals on your pull locations in Helm values, etc. 

If you have been tracking how HealthShare is being deployed via IPM Packages, you can certainly appreciate the adoption of OCI compliance storage for the packages themselves using ORAS... which is core to the Hauler solution.

Goal

I booked a flight to Grand Rapids, MI (GRR) to Boston Logan (BOS) on Allegiant and will not have access to the internet in the friendly skies.  The dog ate my homework and I am on deck for a proof of concept upon arrival that requires a simple IrisCluster and the InterSystems Kubernetes Operator doing amazing things, but I am essentially airgapped the majority of the time on my way to Boston.  Let's create a haul so we can pull images from it while airgapped on the flight on a scramble to crush the demo.

Kind Cluster

Provision a quick kind cluster, but with an asterisk for understanding

cat <<EOF | kind create cluster --name ikohauler --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
containerdConfigPatches:
  - |-
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."172.17.0.1:31337"]
      endpoint = ["http://172.17.0.1:31337"]
networking:
  disableDefaultCNI: false
EOF

Kind’s containerd defaults to HTTPS-only. If your Hauler registry is HTTP on 31337, you need to tell containerd inside the Kind nodes that this host:port is an insecure (plain-HTTP) mirror. The containerConfigPatches is relevant later, but we need to allow it to talk to our Docker ip address on a specified port.

 

Create the Haul (GRR)

Go grab hauler for your system while you are sitting at the gate, remember to switch to airplane mode once boarded.

curl -sfL https://get.hauler.dev | bash

Now, from experience I know the Operator needs a pair of containers and the IrisCluster I am creating is dead simple so Ill just need one of those, for the inventory of three images, lets create the Haul.

hauler store add image containers.intersystems.com/intersystems/irishealth-community:2025.1
hauler store add image containers.intersystems.com/intersystems/iris-operator-amd:3.8.42.100
hauler store add image appscode/kubectl:v1.14
hauler store info

You will see a folder created on the directory you are building your haul be created, `store`.



Lets load up the Haul (which is a collection of our images) so we can take the part of the internet with us.

 hauler store save --filename ikoplus-haul.tar.zst
 rf -rf store

Lets whack the store directory too for dramatics and get ready for takeoff.


In Flight

We are now at cruising altitude and the constant safety announcements are being tuned out by my airpods, lets provision an IrisCluster and IKO.

Airgap the Haul

We have the haul, represented as `ikoplus-haul.tar.zst` on your machine... Lets extract it for use and boot a registry.

sween @ fhirwatch-pop-os ~/Desktop/IKOPLUS/hauler
└─ $ ▶ hauler store load --filename ikoplus-haul.tar.zst
2025-10-21 13:56:43 INF loading haul [ikoplus-haul.tar.zst] to [/home/sween/Desktop/IKOPLUS/hauler/store]
2025-10-21 13:56:47 INF unarchiving completed successfully

Looks like we got our `store` folder back, so we should be in business.

Now, boot the registry:

hauler store serve registry --port 31337

Use of port 31337 in celebration of the great Back Orifice and Netbus from the 90's.

Lets peak now at the local registry with a quick curl:
 

curl http://172.17.0.1:31337/v2/_catalog
{"repositories":["appscode/kubectl","intersystems/iris-operator-amd","intersystems/irishealth-community"]}

Airgapped IKO and IrisCluster

So now we need to adjust our Chart for IKO, and our IrisCluster accordingly to point to our Hauler endpoint.

values.yaml

replicaCount: 1
operator:
  registry: 172.17.0.1:31337 ################# Hauler
  repository: intersystems/iris-operator-amd
  tag: 3.8.42.100
  # Operator Environment Variables
  useFQDN: true
  webserverPort: 52773
  useIrisFsGroup: false
  numThreads: 2
  resyncPeriod: "10m"
  webGatewayStartupTimeout: 0
# https://github.com/appscodelabs/Dockerfiles/tree/master/kubectl
cleaner:
  registry: 172.17.0.1:31337 ################# Hauler
  repository: kubectl
  tag: v1.14

IrisCluster.yaml

# full IKO documentation:
# https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_deployment_iko
apiVersion: intersystems.com/v1alpha1
kind: IrisCluster
metadata:
  name: airgapped-iris
  namespace: default
spec:
  topology:
    data:
      image: 172.17.0.1:31337/intersystems/irishealth-community:2025.1 #################### hauler
  serviceTemplate:
    spec:
      type: LoadBalancer
      externalTrafficPolicy: Local

How we install IKO and the IrisCluster!

helm install iko . -f values.yaml
kubectl apply -f iriscluster.yaml

💥 We pulled from 10,000 feet people.

 

Demo

Here we prove we have a running IrisCluster and Operator that were provisioned from a local Hauler registry, airgapped!

kubectl get pods -n default -o jsonpath='{range .items[*]}{.metadata.name}{" => "}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}'

airgapped-iris-data-0 => 172.17.0.1:31337/intersystems/irishealth-community:2025.1 
iko-iris-operator-amd-5d679956db-pkbmg => 172.17.0.1:31337/intersystems/iris-operator-amd:3.8.42.100 

🙌

Discussion (0)1
Log in or sign up to continue