Pesquisar

Artigo
· Set. 10 6min de leitura

IKO Plus: Stretched Cross Regional IrisCluster with Tailscale on Google Cloud Platform

A step by step implementation path to a cross regional stretched IrisCluster with Mirroring using the Intersystems Kubernetes Operator (IKO), Google Cloud Platform, and Tailscale.

I am giving this distraction the code name "Compliment Sandwich" for a reason yet to be realized, but I'd rather the community go right for the jugular shooting holes in a solution that implements wireguard based connectivity for our workloads in general, as I would like to refine it as a fall project leading up to KubeCon in Atlanta and if I miss the mark, Ill get it done before Amsterdam. 


The journey to wireguard started with Cilium for us, with ClusterMesh and Node to Node stuff becoming apparent for a two configuration flag to encryption and compliance checkboxes for the workloads.  After going down the Wireguard rabbit hole, it lent to aiding the overall divorce from Cloud vendors for $ite to $ite VPN's and development compute and watching the Super Bowl in Puerto Rico unabated as they say.

In a paragraph, explain Tailscale

Tailscale leverages WireGuard as its secure, encrypted tunnel layer, but wraps it in a powerful overlay that handles the hard parts for you. Under the hood, each device runs the WireGuard protocol (specifically a fork of the wireguard-go implementation) to establish encrypted point-to-point tunnels.  Tailscale’s coordination (control) plane—not part of the tunnel—handles identity-based authentication, key discovery, and automated configuration, allowing devices to connect directly in a peer-to-peer mesh even when behind NATs or firewalls.

My Version

Tailscale is a clown suit for wireguard-go like Github is for git, that flattens a network of participating devices.

Let's Go

gcloud config set project ikoplus


Create Compute

In a GCP project "ikoplus" enable, Compute Engine.
🇺🇸

gcloud compute instances create cks-master --zone=us-east4-a  \
--machine-type=c2-standard-4  \
--image=ubuntu-2404-noble-amd64-v20250530 \
--image-project=ubuntu-os-cloud \
--boot-disk-size=200GB

🇬🇧

gcloud compute instances create cks-master --zone=europe-west3-c \
--machine-type=c2-standard-4  \
--image=ubuntu-2404-noble-amd64-v20250530 \
--image-project=ubuntu-os-cloud \
--boot-disk-size=200GB

Should be looking a little like this in the cloud console.


 

Add the nodes to your Tailnet

Now for `region` in [ 🇺🇸 , 🇬🇧 ]; do

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt-get update
sudo apt-get install tailscale
sudo tailscale up
tailscale ip -4

You should get a prompt to authenticate your Tailnet:

And now our tailnet should look like so:


Install Kubernetes

Using Canonical k8s (formerly Microk8s),  the cluster setup is quite literally a "snap".

🇺🇸

sudo snap install k8s --classic
sudo k8s bootstrap --address 100.127.21.93 # use your tailnet address here for kube api
sudo k8s get-join-token --worker

👣 🔫
Foot gun: before we go to the next step you may or may not hit this but...  I was tailing the logs after hitting some TLS issues joining on the next step and found a time drift of over 5 seconds between the two boxes, despite using chrony and Google time synchroniztion.  To mitigate this a bit, I made the ntp setup on both nodes a bit more agressive by tweaking the /etc/chrony/chrony.conf with these two directives.

maxslewrate 2000
makestep 0.25 0.5

🇬🇧

sudo snap install k8s --classic
sudo k8s join-cluster eyJ0b2tl-tokenfromcommandaboveonmaster

Joining the cluster. This may take a few seconds, please wait.

We should now be able to bask in the glory of a kubernetes cluster with two nodes, over the pond.




Tailscale: Create OAUTH Client and Install Operator


This is a bonus for now, but the operator allows us to expose any service we decorate in the cluster with a tag to the tailscale operator.

Oauth Client

  
Install the Operator

helm repo add tailscale https://pkgs.tailscale.com/helmcharts
helm repo update
helm upgrade \
    --install \
    tailscale-operator \
    tailscale/tailscale-operator \
    --namespace=tailscale \
    --create-namespace \
    --set-string oauth.clientId=${OAUTH_CLIENT_ID} \
    --set-string oauth.clientSecret=${OAUTH_CLIENT_SECRET} \
    --set-string apiServerProxyConfig.mode="true" \
    --wait



Our Tailnet now looks like so, as you can see my laptop is also included in it.



Install the InterSystems Kubernetes Operator

sween @ fhirwatch-pop-os ~/Desktop/ISC/IKO/iris_operator_amd-3.10.1.100-unix/iris_operator_amd-3.10.1.100/chart/iris-operator
└─ $ ▶ helm install iko . --kubeconfig kube.config 
NAME: iko
LAST DEPLOYED: Tue Sep  9 14:41:51 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
To verify that InterSystems Kubernetes Operator has started, run:

  kubectl --namespace=default get deployments -l "release=iko, app=iris-operator-amd"

Establish Zones

Important concept, but powerful one is the establishment of zones.  At the end of the day, for IKO to do its magic, this simply means that you label the nodes with a zone, and IKO will do its magic to create the mirror set across the zones for the desired state across the pond.

For this, we created zones "us,uk" and labelled each node accordingly.

apiVersion: v1
kind: Node

🇺🇸

topology.kubernetes.io/zone: us

🇬🇧

topology.kubernetes.io/zone: uk


The Stretched IrisCluster

The abbreviated IrisCluster resource definition/topology is in the teaser below, but lets call out the cool spots.

Create an IRIS for Health Mirror, across zones and save me a flight.
 

      mirrorMap: primary,backup
      mirrored: true
      preferredZones:
        - us
        - uk


Please secure the web gateways, ecp, superserver, and mirror agents with TLS:

  tls:
    common:
      secret:
        secretName: cert-secret
 
IrisCluster.yaml

Deploy it!

Wooo!

Checking our Work

Now lets prove it utilizing curl to indicate our geo location, by flying to the US, shelling into the pod, and running `curl ipinfo.io`...
🇺🇸


Then flying back to the UK, shelling into the pod, and running `curl ipinfo.io`
🇬🇧

🎤 ⬇

So that is it for now, stay tuned for more elaboration on the subject.

💪 Special thanks to Mark Hayden from ISC for helping me wrap my head around "zones" in an understandable fashion in the IKO topology!

 

1 Comment
Discussão (1)2
Entre ou crie uma conta para continuar
Artigo
· Set. 10 4min de leitura

Learning ObjectScript as a New Developer: What I Wish I Knew

I joined InterSystems less than a year ago. Diving into ObjectScript and IRIS was exciting, but also full of small surprises that tripped me up at the beginning. In this article I collect the most common mistakes I, and many new colleagues, make, explain why they happen, and show concrete examples and practical fixes. My goal is to help other new developers save time and avoid the same bumps in the road.

 

1. Getting lost among system classes and where to start

The issue: ObjectScript/IRIS ships with many system classes and packages (%Library, %SYS, %Persistent, %SQL, etc.). As a new dev, it’s hard to know which class or pattern fits a task. I remember trying to find an appropriate persistent class and being unsure whether to extend %Persistent or use a registry-type class.

Why it matters: Picking the wrong approach early makes code harder to maintain and integrates poorly with IRIS features (indexes, security, SQL).

Tip: Start from the concrete need (store records? expose SQL? share objects across processes?) and then search the Class Reference for the relevant capability (persistence, indexes, collections). Use Studio or the InterSystems VS Code extension to browse classes interactively and inspect examples.

 

2. Documentation overwhelm: not knowing the right keywords

The issue: The docs are comprehensive, but if you don’t know the correct class name or term, searches return many unrelated pages. Early on I often spent a lot of time because I didn’t yet know the canonical terms.

Why it matters: You waste time and might implement suboptimal patterns.

Tip:

  • Search the Developer Community for practical examples (search by “persistent class example”, “ObjectScript transaction TSTART example”, etc.).
  • Use the VS Code InterSystems extension, it can jump directly to class definitions.
  • When searching docs, combine class names and actions: e.g. "%Persistent property index example".

 

3. Forgetting .. for local method call

The issue: Calling a method of the same class without .. results in a call not being recognized at runtime.

Wrong:

Class MyClass Extends %Persistent { 
   Method DoWork() 
   { 
       Do Hello()  // wrong: this is not a local method invocation
   } 
   Method Hello()
   { 
       Write "Hello", ! 
   } 
}

Right:

Method DoWork() {
   Do ..Hello()  // correct: local method call 
}

Tip: When you get “Unknown routine” errors for methods you see in the class, check whether you used .. for self-calls.

 

4. Confusing globals and local variables

The issue: ObjectScript distinguishes globals (persistent across sessions, e.g. ^MyGlobal) and local variables (in-memory, scope-limited). New developers frequently use one when the other is intended.

SET localVar = 10    // exists only during the current process/session
SET ^globalVar = 20  // persists in the database across processes and sessions

Tip: Use persistent classes for data that should be stored long-term. Limit use of globals to very specific low-level needs or when you understand consequences.

 

5. Hardcoding globals instead of using persistent classes

The issue: My instinct at first was “quick and dirty”: write to ^MyGlobal directly. That works, but it bypasses class-based benefits: schema, indices, SQL access, and safety.

Better approach:

Class Person Extends %Persistent 
{ 
    Property Name As %String; 
    Property DOB As %Date; 
}

Tip: Prefer %Persistent classes for application data. They give you a cleaner model and integrate with SQL and indexes.

 

6. Ignoring transactions (TSTART / TCOMMIT)

The issue: Developers sometimes perform several writes thinking they are atomic. Without explicit transaction control, partial failures can leave inconsistent data.

TSTART 
// multiple updates 
TCOMMIT

Tip: Identify logical units of work and wrap them in transactions. If something can fail halfway, use TSTART / TROLLBACK / TCOMMIT. Keep in mind that IRIS supports nested transactions: multiple TSTART calls increase the transaction level, and all levels must be committed (or rolled back) before changes are final.

 

7. Misunderstanding SQL options: Embedded SQL vs %SQL.Statement

The issue: Embedded SQL (UPDATE, SELECT blocks inside ObjectScript) and the %SQL.Statement API are both available; choosing without knowing pros/cons can cause awkward code.

Guideline: Use Embedded SQL for fixed/static queries inside routines; use %SQL.Statement when you need to build and execute SQL dynamically.

 

8. Skipping proper error handling

The issue: Not using TRY/CATCH or signaling errors properly makes debugging and reliability harder.

TRY 
{ 
   // code that may fail 
} CATCH ex 
{  
   Write "Error: ", ex.DisplayString(),! 
}

Tip: Wrap risky operations (I/O, external calls, dynamic SQL) with error handlers and log informative messages.

 

Final notes

Early on I wrote globals for convenience and later spent time refactoring to persistent classes. That refactor taught me the value of designing data models up front and using the tools IRIS provides. My best habits now: small experiments, frequent searches on Developer Community, and keeping transactions and error handling in mind from the start.

If you’re new: treat your first few tasks as experiments, create small persistent classes, try simple Embedded SQL, and use the Management Portal and VS Code browser to inspect system classes. Ask questions on the Developer Community; many others had the same “gotchas.”

For more: check the official ObjectScript documentation and the Developer Community for examples and patterns.

 

This article was reviewed and edited with the assistance of AI tools to improve clarity and grammar. The experiences and suggestions described are my own.

11 Comments
Discussão (11)6
Entre ou crie uma conta para continuar
Anúncio
· Set. 10

Concurso de .Net, Java, Python, y JavaScript de InterSystems.

Hola Desarrolladores,

Nos encanta poder anunciar el nuevo concurso de programación online de InterSystems:

🏆 InterSystems External Languages Contest 🏆

Duración: del 22 de septiembre al 12 de octubre de 2025

Bolsa de premios: $12.000

 

De qué va

Desarrollar una aplicación que muestre el uso de .Net, Java, Python, y JavaScript con InterSystems IRIS.

Requisitos generales:

  1. La aplicación o biblioteca debe ser completamente funcional. No debe ser una importación ni una interfaz directa de una biblioteca ya existente en otro lenguaje (excepto en C++, donde realmente se necesita mucho trabajo para crear una interfaz para IRIS). No debe ser un copia-pega de una aplicación o biblioteca existente.
  2. Aplicaciones aceptadas: apps nuevas para Open Exchange o existentes, pero con una mejora significativa. Nuestro equipo revisará todas las aplicaciones antes de aprobarlas para el concurso.
  3. La aplicación debe funcionar en IRIS Community Edition o IRIS for Health Community Edition. Ambas pueden descargarse como versiones para host (Mac, Windows) desde el sitio de evaluación, o utilizarse en forma de contenedores extraídos de InterSystems Container Registry o Community Containers: intersystemsdc/iris-community:latest o intersystemsdc/irishealth-community:latest.
  4. La aplicación debe ser de código abierto y publicarse en GitHub o GitLab.
  5. El archivo README de la aplicación debe estar en inglés, contener los pasos de instalación y contener el video de demostración y/o una descripción de cómo funciona la aplicación.
  6. Solo se permiten 3 envíos por desarrollador.

Nota: Nuestros expertos tendrán la última palabra sobre si la aplicación se aprueba para el concurso o no, basándose en los criterios de complejidad y utilidad. Su decisión es final y no está sujeta a apelación.

Premios

1. Nominación de Expertos: un jurado especialmente seleccionado determinará a los ganadores.

🥇 1er lugar - $5,000 

🥈 2do lugar - $2,500 

🥉 3er lugar - $1,000

🏅 4to lugar - $500

🏅 5to lugar - $300

🌟 6-10to lugar - $100

2. Premios de la Comunidad: aplicaciones que reciban la mayor cantidad de votos en total.

🥇 1er lugar - $1,000 

🥈 2do lugar - $600 

🥉 3er lugar - $300

🏅 4to lugar - $200

🏅 5to lugar - $100

❗ Si varios participantes obtienen el mismo número de votos, todos se consideran ganadores y el premio en efectivo se reparte entre ellos.
❗ Los premios en efectivo se otorgan solo a quienes puedan verificar su identidad. Si hay dudas, los organizadores se pondrán en contacto y solicitarán información adicional sobre los participantes.

¿Quién puede participar?

Cualquier miembro de la Comunidad de Desarrolladores, excepto los empleados de InterSystems (se permiten contratistas de ISC). ¡Cread una cuenta!

Los desarrolladores pueden formar equipo para crear una aplicación colaborativa, con un límite de 5 desarrolladores por equipo.

No olvides destacar a los miembros de tu equipo en el README de tu aplicación – perfiles de usuario de la Comunidad de Desarrolladores.

Fechas importantes

🛠 Fase de desarrollo y registro de aplicaciones:

  • 22 de septiembre de 2025 (00:00 EST): comienza el concurso.
  • 5 de octubre de 2025 (23:59 EST): fecha límite para envíos.

 Período de votación

  • 6 de octubre de 2025 (00:00 EST): Empieza la votación
  • 12 de octubre de 2025 (23:59 EST): Termina la votación

Nota: los desarrolladores pueden mejorar sus aplicaciones durante todo el período de registro y de votación.

    Recursos útiles

    ✓ Documentación:

    ✓ Aplicaciones de ejemplo:

    ✓ Para principiantes con IRIS:

    ✓ Para principiantes con ObjectScript Package Manager (IPM):

    ✓ Cómo enviar vuestra aplicación al concurso:

    ¿Necesitáis ayuda?

    Uníos al canal del concurso en el servidor de Discord de InterSystems o hablad con nosotros en los comentarios de esta publicación.

    Estamos esperando VUESTRO proyecto: uníos a nuestro maratón de código para ganar.


    Al participar en este concurso, aceptáis los términos de la competición aquí establecidos. Por favor, leedlos atentamente antes de continuar.

    Discussão (0)1
    Entre ou crie uma conta para continuar
    Discussão
    · Set. 10

    Introduction to New Memebers

    Hello Everyone,

    I’m excited to join the InterSystems Developer Community, a place where IRIS, Caché, Ensemble, HealthShare, and all things InterSystems come alive through shared knowledge and collaboration.

    A little about me,

    • I’m passionate about building efficient, integration-driven solutions, exploring ObjectScript, working with REST APIs, and diving into analytics tools like DeepSee and IntegratedML.
    • I’m here to learn from your real-world experiences, whether it’s tips on interoperability, performance tuning, or best practices across IRIS and HealthShare ecosystems.
    • I also look forward to contributing back through questions, articles, and discussions.

    I didn’t find any dedicated introduction thread, so I thought of starting this one. Hopefully this doesn’t go against any guidelines. 😊

    Looking forward to connecting, solving problems together, and growing within this amazing global developer community!

    - Rajesh

    3 Comments
    Discussão (3)4
    Entre ou crie uma conta para continuar
    Discussão (0)0
    Entre ou crie uma conta para continuar