# services/hermes/chat-sandbox.yaml apiVersion: v1 kind: Service metadata: name: hermes-chat-sandbox namespace: hermes labels: app: hermes-chat-sandbox spec: clusterIP: None publishNotReadyAddresses: false selector: app: hermes-chat-sandbox ports: - {name: http, port: 9080, targetPort: http, protocol: TCP} --- apiVersion: apps/v1 kind: Deployment metadata: name: hermes-chat-sandbox-0 namespace: hermes labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "0" spec: replicas: 1 selector: matchLabels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "0" template: metadata: labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "0" annotations: ai.bstein.dev/role: isolated-user-computation ai.bstein.dev/isolation: credential-free and default-deny network spec: hostname: hermes-chat-sandbox-0 subdomain: hermes-chat-sandbox automountServiceAccountToken: false enableServiceLinks: false securityContext: fsGroup: 10000 fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault affinity: &sandbox-affinity nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: [arm64] - key: node-role.kubernetes.io/worker operator: In values: ["true"] - key: kubernetes.io/hostname operator: NotIn values: [titan-05, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - weight: 40 preference: matchExpressions: - key: hardware operator: In values: [rpi4] podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: hermes-chat-sandbox topologyKey: kubernetes.io/hostname containers: - &sandbox-container name: sandbox image: registry.bstein.dev/bstein/hermes-chat-sandbox@sha256:17ee62b8e61c08573a3a8cca903b38ec43800cb44ec29340e1bc095176544bca imagePullPolicy: IfNotPresent ports: - {name: http, containerPort: 9080, protocol: TCP} volumeMounts: - {name: workspace, mountPath: /workspace} - {name: workspace, mountPath: /opt/data/workspace} - {name: tmp, mountPath: /tmp} readinessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 20000 runAsGroup: 10000 seccompProfile: type: RuntimeDefault resources: requests: {cpu: 50m, memory: 128Mi} limits: {cpu: "1", memory: 1Gi} volumes: - name: workspace persistentVolumeClaim: claimName: workspace-hermes-chat-tenant-0 - &sandbox-tmp name: tmp emptyDir: sizeLimit: 256Mi --- apiVersion: apps/v1 kind: Deployment metadata: name: hermes-chat-sandbox-1 namespace: hermes labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "1" spec: replicas: 1 selector: matchLabels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "1" template: metadata: labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "1" annotations: ai.bstein.dev/role: isolated-user-computation ai.bstein.dev/isolation: credential-free and default-deny network spec: hostname: hermes-chat-sandbox-1 subdomain: hermes-chat-sandbox automountServiceAccountToken: false enableServiceLinks: false securityContext: fsGroup: 10000 fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: [arm64] - key: node-role.kubernetes.io/worker operator: In values: ["true"] - key: kubernetes.io/hostname operator: NotIn values: [titan-05, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - weight: 40 preference: matchExpressions: - key: hardware operator: In values: [rpi4] podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: hermes-chat-sandbox topologyKey: kubernetes.io/hostname containers: - name: sandbox image: registry.bstein.dev/bstein/hermes-chat-sandbox@sha256:17ee62b8e61c08573a3a8cca903b38ec43800cb44ec29340e1bc095176544bca imagePullPolicy: IfNotPresent ports: - {name: http, containerPort: 9080, protocol: TCP} volumeMounts: - {name: workspace, mountPath: /workspace} - {name: workspace, mountPath: /opt/data/workspace} - {name: tmp, mountPath: /tmp} readinessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 20000 runAsGroup: 10000 seccompProfile: type: RuntimeDefault resources: requests: {cpu: 50m, memory: 128Mi} limits: {cpu: "1", memory: 1Gi} volumes: - name: workspace persistentVolumeClaim: claimName: workspace-hermes-chat-tenant-1 - name: tmp emptyDir: sizeLimit: 256Mi --- apiVersion: apps/v1 kind: Deployment metadata: name: hermes-chat-sandbox-2 namespace: hermes labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "2" spec: replicas: 1 selector: matchLabels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "2" template: metadata: labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "2" annotations: ai.bstein.dev/role: isolated-user-computation ai.bstein.dev/isolation: credential-free and default-deny network spec: hostname: hermes-chat-sandbox-2 subdomain: hermes-chat-sandbox automountServiceAccountToken: false enableServiceLinks: false securityContext: fsGroup: 10000 fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: [arm64] - key: node-role.kubernetes.io/worker operator: In values: ["true"] - key: kubernetes.io/hostname operator: NotIn values: [titan-05, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - weight: 40 preference: matchExpressions: - key: hardware operator: In values: [rpi4] podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: hermes-chat-sandbox topologyKey: kubernetes.io/hostname containers: - name: sandbox image: registry.bstein.dev/bstein/hermes-chat-sandbox@sha256:17ee62b8e61c08573a3a8cca903b38ec43800cb44ec29340e1bc095176544bca imagePullPolicy: IfNotPresent ports: - {name: http, containerPort: 9080, protocol: TCP} volumeMounts: - {name: workspace, mountPath: /workspace} - {name: workspace, mountPath: /opt/data/workspace} - {name: tmp, mountPath: /tmp} readinessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 20000 runAsGroup: 10000 seccompProfile: type: RuntimeDefault resources: requests: {cpu: 50m, memory: 128Mi} limits: {cpu: "1", memory: 1Gi} volumes: - name: workspace persistentVolumeClaim: claimName: workspace-hermes-chat-tenant-2 - name: tmp emptyDir: sizeLimit: 256Mi --- apiVersion: apps/v1 kind: Deployment metadata: name: hermes-chat-sandbox-3 namespace: hermes labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "3" spec: replicas: 1 selector: matchLabels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "3" template: metadata: labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "3" annotations: ai.bstein.dev/role: isolated-user-computation ai.bstein.dev/isolation: credential-free and default-deny network spec: hostname: hermes-chat-sandbox-3 subdomain: hermes-chat-sandbox automountServiceAccountToken: false enableServiceLinks: false securityContext: fsGroup: 10000 fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: [arm64] - key: node-role.kubernetes.io/worker operator: In values: ["true"] - key: kubernetes.io/hostname operator: NotIn values: [titan-05, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - weight: 40 preference: matchExpressions: - key: hardware operator: In values: [rpi4] podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: hermes-chat-sandbox topologyKey: kubernetes.io/hostname containers: - name: sandbox image: registry.bstein.dev/bstein/hermes-chat-sandbox@sha256:17ee62b8e61c08573a3a8cca903b38ec43800cb44ec29340e1bc095176544bca imagePullPolicy: IfNotPresent ports: - {name: http, containerPort: 9080, protocol: TCP} volumeMounts: - {name: workspace, mountPath: /workspace} - {name: workspace, mountPath: /opt/data/workspace} - {name: tmp, mountPath: /tmp} readinessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 20000 runAsGroup: 10000 seccompProfile: type: RuntimeDefault resources: requests: {cpu: 50m, memory: 128Mi} limits: {cpu: "1", memory: 1Gi} volumes: - name: workspace persistentVolumeClaim: claimName: workspace-hermes-chat-tenant-3 - name: tmp emptyDir: sizeLimit: 256Mi --- apiVersion: apps/v1 kind: Deployment metadata: name: hermes-chat-sandbox-4 namespace: hermes labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "4" spec: replicas: 1 selector: matchLabels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "4" template: metadata: labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "4" annotations: ai.bstein.dev/role: isolated-user-computation ai.bstein.dev/isolation: credential-free and default-deny network spec: hostname: hermes-chat-sandbox-4 subdomain: hermes-chat-sandbox automountServiceAccountToken: false enableServiceLinks: false securityContext: fsGroup: 10000 fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: [arm64] - key: node-role.kubernetes.io/worker operator: In values: ["true"] - key: kubernetes.io/hostname operator: NotIn values: [titan-05, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - weight: 40 preference: matchExpressions: - key: hardware operator: In values: [rpi4] podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: hermes-chat-sandbox topologyKey: kubernetes.io/hostname containers: - name: sandbox image: registry.bstein.dev/bstein/hermes-chat-sandbox@sha256:17ee62b8e61c08573a3a8cca903b38ec43800cb44ec29340e1bc095176544bca imagePullPolicy: IfNotPresent ports: - {name: http, containerPort: 9080, protocol: TCP} volumeMounts: - {name: workspace, mountPath: /workspace} - {name: workspace, mountPath: /opt/data/workspace} - {name: tmp, mountPath: /tmp} readinessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 20000 runAsGroup: 10000 seccompProfile: type: RuntimeDefault resources: requests: {cpu: 50m, memory: 128Mi} limits: {cpu: "1", memory: 1Gi} volumes: - name: workspace persistentVolumeClaim: claimName: workspace-hermes-chat-tenant-4 - name: tmp emptyDir: sizeLimit: 256Mi --- apiVersion: apps/v1 kind: Deployment metadata: name: hermes-chat-sandbox-5 namespace: hermes labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "5" spec: replicas: 1 selector: matchLabels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "5" template: metadata: labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "5" annotations: ai.bstein.dev/role: isolated-user-computation ai.bstein.dev/isolation: credential-free and default-deny network spec: hostname: hermes-chat-sandbox-5 subdomain: hermes-chat-sandbox automountServiceAccountToken: false enableServiceLinks: false securityContext: fsGroup: 10000 fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: [arm64] - key: node-role.kubernetes.io/worker operator: In values: ["true"] - key: kubernetes.io/hostname operator: NotIn values: [titan-05, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - weight: 40 preference: matchExpressions: - key: hardware operator: In values: [rpi4] podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: hermes-chat-sandbox topologyKey: kubernetes.io/hostname containers: - name: sandbox image: registry.bstein.dev/bstein/hermes-chat-sandbox@sha256:17ee62b8e61c08573a3a8cca903b38ec43800cb44ec29340e1bc095176544bca imagePullPolicy: IfNotPresent ports: - {name: http, containerPort: 9080, protocol: TCP} volumeMounts: - {name: workspace, mountPath: /workspace} - {name: workspace, mountPath: /opt/data/workspace} - {name: tmp, mountPath: /tmp} readinessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 20000 runAsGroup: 10000 seccompProfile: type: RuntimeDefault resources: requests: {cpu: 50m, memory: 128Mi} limits: {cpu: "1", memory: 1Gi} volumes: - name: workspace persistentVolumeClaim: claimName: workspace-hermes-chat-tenant-5 - name: tmp emptyDir: sizeLimit: 256Mi --- apiVersion: apps/v1 kind: Deployment metadata: name: hermes-chat-sandbox-6 namespace: hermes labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "6" spec: replicas: 1 selector: matchLabels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "6" template: metadata: labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "6" annotations: ai.bstein.dev/role: isolated-user-computation ai.bstein.dev/isolation: credential-free and default-deny network spec: hostname: hermes-chat-sandbox-6 subdomain: hermes-chat-sandbox automountServiceAccountToken: false enableServiceLinks: false securityContext: fsGroup: 10000 fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: [arm64] - key: node-role.kubernetes.io/worker operator: In values: ["true"] - key: kubernetes.io/hostname operator: NotIn values: [titan-05, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - weight: 40 preference: matchExpressions: - key: hardware operator: In values: [rpi4] podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: hermes-chat-sandbox topologyKey: kubernetes.io/hostname containers: - name: sandbox image: registry.bstein.dev/bstein/hermes-chat-sandbox@sha256:17ee62b8e61c08573a3a8cca903b38ec43800cb44ec29340e1bc095176544bca imagePullPolicy: IfNotPresent ports: - {name: http, containerPort: 9080, protocol: TCP} volumeMounts: - {name: workspace, mountPath: /workspace} - {name: workspace, mountPath: /opt/data/workspace} - {name: tmp, mountPath: /tmp} readinessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 20000 runAsGroup: 10000 seccompProfile: type: RuntimeDefault resources: requests: {cpu: 50m, memory: 128Mi} limits: {cpu: "1", memory: 1Gi} volumes: - name: workspace persistentVolumeClaim: claimName: workspace-hermes-chat-tenant-6 - name: tmp emptyDir: sizeLimit: 256Mi --- apiVersion: apps/v1 kind: Deployment metadata: name: hermes-chat-sandbox-7 namespace: hermes labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "7" spec: replicas: 1 selector: matchLabels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "7" template: metadata: labels: app: hermes-chat-sandbox ai.bstein.dev/tenant-ordinal: "7" annotations: ai.bstein.dev/role: isolated-user-computation ai.bstein.dev/isolation: credential-free and default-deny network spec: hostname: hermes-chat-sandbox-7 subdomain: hermes-chat-sandbox automountServiceAccountToken: false enableServiceLinks: false securityContext: fsGroup: 10000 fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: [arm64] - key: node-role.kubernetes.io/worker operator: In values: ["true"] - key: kubernetes.io/hostname operator: NotIn values: [titan-05, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - weight: 40 preference: matchExpressions: - key: hardware operator: In values: [rpi4] podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: hermes-chat-sandbox topologyKey: kubernetes.io/hostname containers: - name: sandbox image: registry.bstein.dev/bstein/hermes-chat-sandbox@sha256:17ee62b8e61c08573a3a8cca903b38ec43800cb44ec29340e1bc095176544bca imagePullPolicy: IfNotPresent ports: - {name: http, containerPort: 9080, protocol: TCP} volumeMounts: - {name: workspace, mountPath: /workspace} - {name: workspace, mountPath: /opt/data/workspace} - {name: tmp, mountPath: /tmp} readinessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: {path: /health, port: http} initialDelaySeconds: 10 periodSeconds: 30 timeoutSeconds: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 20000 runAsGroup: 10000 seccompProfile: type: RuntimeDefault resources: requests: {cpu: 50m, memory: 128Mi} limits: {cpu: "1", memory: 1Gi} volumes: - name: workspace persistentVolumeClaim: claimName: workspace-hermes-chat-tenant-7 - name: tmp emptyDir: sizeLimit: 256Mi