Article
· Apr 15 4m read

When to account for useIrisFsGroup in your IKO Deployments

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:

1) initContainers

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 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

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