Si echáis un vistazo al archivo values.yaml del Helm chart de IKO, encontraréis:
useIrisFsGroup: false
Vamos a desglosar qué es useIrisFsGroup y en qué situaciones puede ser útil activarlo.
FsGroup se refiere al file system group (grupo del sistema de archivos).
Por defecto, los volúmenes en Kubernetes son propiedad del usuario root, pero necesitamos que IRIS sea propietario de sus propios archivos (IRIS en contenedores se instala bajo el usuario irisowner). Para solucionar esto, utilizamos uno de estos dos métodos:
Los initContainers se ejecutan antes que los contenedores de la aplicación (como IRIS) en un pod. Generalmente preparan el entorno para la aplicación y luego terminan. El initContainer se ejecuta como root antes que IRIS y ejecuta:
chown irisowner:irisowner /irissys/*
El SecurityContext está, por defecto, configurado como:
RunAsUser: 51773
RunAsGroup: 51773
RunAsNonRoot: true
para el pod. Y vemos que 51773 es el ID de usuario y grupo para irisowner:
$ id
uid=51773(irisowner) gid=51773(irisowner) groups=51773(irisowner)
2) Montar volúmenes con una propiedad de grupo específica
Algunos entornos pueden restringir que los contenedores se ejecuten como root, por ejemplo, mediante las Security Context Constraints en OpenShift. En este caso, ni siquiera podemos ejecutar un initContainer como root y necesitaremos que los volúmenes tengan la propiedad del sistema de archivos correcta en el momento de su montaje. Para hacerlo, desplegad el InterSystems Kubernetes Operator con:
useIrisFsGroup: true
en el archivo /chart/iris-operator/values.yaml.
Ahora, vuestros pods se desplegarán sin initContainers.
Una advertencia: si deseáis configurar sidecars, se requiere un paso adicional. No podréis utilizar el sidecar habitual de Apache/NGINX. Encontraréis este problema:
>> 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
lo que resultará en un CrashLoopBackOff. Un análisis más profundo nos muestra que cuando el sidecar habitual de Apache/NGINX está presente, el parámetro useIrisFsGroup no se tiene en cuenta. Esto se debe a que estos contenedores de Apache/NGINX, en este caso el sidecar, se ejecutan como root. IRIS no se ejecuta como root y no puede acceder a sus directorios, lo que causa nuestro problema.
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 falla con el 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/
En su lugar, deberíamos utilizar la imagen non-root del web gateway (ya que suponemos que queremos que todas nuestras imágenes se ejecuten como no root). Esto implicaría un web gateway restringido o locked-down. También debemos asegurarnos de agregar el security context para hacer cumplir esta condición. Necesitamos declarar explícitamente:
securityContext:
runAsUser: 51773
runAsGroup: 51773
runAsNonRoot: true
fsGroup: 51773
en vuestros nodos de datos/cómputo.
Un ejemplo de YAML para nuestro IrisCluster CRD que integra todo esto se puede ver a continuación.
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
Feliz YAMLing