If you look at the values.yaml of the IKO's Helm chart you'll find:
useIrisFsGroup: false
Let's break down what it is and in what situations you may want to set it to true.
FsGroup refers to the file system group.
By default, Kubernetes volumes are owned by root, but we need IRIS to own its files (IRIS in containers is installed under irisowner user). To get around this we employ one of two methods:
The initContainers run before app containers (like IRIS) in a pod. They generally set up the environment for the application and then run to completion/terminate. The initContainer runs as root before IRIS and executes:
chown -R irisowner:irisowner /irissys/*
The SecurityContext is by default set to:
RunAsUser: 51773
RunAsGroup: 51773
RunAsNonRoot: true
for the pod. And we see that 51773 is is the user and group id for irisowner:
$ id
uid=51773(irisowner) gid=51773(irisowner) groups=51773(irisowner)
2) Mount volumes with a given group ownership
Some environments can restrict any containers from running as root, for example via Security Context Constraints in OpenShift. In this case we cannot even run an initContainer as root and will need to have the volumes given the correct file system ownership at mount time. To do so, deploy the InterSystems Kubernetes Operator with
useIrisFsGroup: true
in the /chart/iris-operator/values.yaml file.
Now your pods will deploy without initContainers.
A caveat, if you wish to set up sidecars then an extra step is required. You cannot use the regular Apache/NGINX sidecar. You will run into this problem:
>> kubectl get pods
NAME READY STATUS RESTARTS AGE
intersystems-iris-operator-amd-76b75f6b48-7lnw2 1/1 Running 0 43m
iris-data-0-0 1/2 Error 2 (22s ago) 2m
which will turn into a CrashLoopBackOff. A deeper look shows us that when the regular Apache/NGINX web gateway sidecar is present, the useIrisFsGroup is not taken into consideration. This is because these Apache/NGINX containers, in this case the sidecar, run as root. IRIS does not run as root and is unable to access its directories, causing our issue.
irisowner@iris-data-0-0:/irissys$ ls -l
total 16
drwxrwxrwx 3 root root 107 Mar 31 14:28 cpf
drwxr-xr-x 3 root root 4096 Mar 31 14:21 data
drwxr-xr-x 3 root root 4096 Mar 31 14:21 journal1
drwxr-xr-x 3 root root 4096 Mar 31 14:21 journal2
drwxrwxrwt 3 root root 100 Mar 31 14:28 key
drwxr-xr-x 3 root root 4096 Mar 31 14:21 wij
IRIS fails with the error:
[ERROR] Command "iris start IRIS quietly" exited with status 256
03/31/25-14:41:06:870 (795) 3 [Utility.Event] Error while moving data directories ERROR #5001: Cannot create target: /irissys/data/IRIS/
Instead, we should use the non-root web gateway image (since we want all our images to run as non-root supposedly). This would imply a locked-down web gateway. We need to also make sure to add the security context to enforce this condition. We need to explicitly state:
securityContext:
runAsUser: 51773
runAsGroup: 51773
runAsNonRoot: true
fsGroup: 51773
in your data/compute nodes.
An example YAML for our IrisCluster CRD putting this all together can be seen below.
apiVersion: intersystems.com/v1alpha1
kind: IrisCluster
metadata:
name: iris
spec:
licenseKeySecret:
name: iris-key-secret
configSource:
name: iris-cpf
imagePullSecrets:
- name: intersystems-pull-secret
topology:
data:
image: containers.intersystems.com/intersystems/irishealth:2025.1
compatibilityVersion: "2025.1.0"
mirrored: true
podTemplate:
spec:
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "4Gi"
cpu: "2"
securityContext:
runAsUser: 51773
runAsGroup: 51773
runAsNonRoot: true
fsGroup: 51773
webgateway:
image: containers.intersystems.com/intersystems/webgateway-lockeddown:2025.1
type: apache-lockeddown
applicationPaths:
- /csp/sys
- /csp/user
- /csp/broker
- /api
- /isc
- /oauth2
- /ui
- /csp/healthshare
loginSecret:
name: iris-webgateway-secret
webgateway:
replicas: 1
image: containers.intersystems.com/intersystems/webgateway-lockeddown:2025.1
type: apache-lockeddown
podTemplate:
spec:
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "2Gi"
cpu: "1"
applicationPaths:
- /csp/sys
- /csp/user
- /csp/broker
- /api
- /isc
- /oauth2
- /ui
- /csp/healthshare
alternativeServers: LoadBalancing
loginSecret:
name: iris-webgateway-secret
arbiter:
image: containers.intersystems.com/intersystems/arbiter:2025.1
serviceTemplate:
spec:
type: ClusterIP
Happy YAMLing