permissionscontainersk6argo-workflows

Unable to write to mounted volume while using K6 image in Argo-Workflows


I'm trying to execute a K6 test in an Argo-Workflows step and to write the results to a file that would be handled by a later step. To do so, I'm mounting a volume and attempting to write the results to a file on the mounted volume.

When I do so with --out json=/mnt/app/results.json as well as when using handleSummary functionality, I get a 'permission denied' error:

Could not save some summary information:\n\t- could not open '/mnt/app/summary.json': open /mnt/app/summary.json: permission denied

I guess this happens due to K6 executing in a non root user which doesn't have permissions to write to the file system. While I see there are ways to get around this using plain docker (Using --user $UID or --user root), I didn't find an appropriate method to achieve this with Argo-Workflows.

Here's a small Workflow that reproduces the problem:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: permission-denied-for-k6-image-
spec:
  volumeClaimTemplates:
  - metadata:
      name: workdir
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

  entrypoint: main
  templates:
  - name: main
    steps:
    - - name: run-load-test
        template: run-load-test
    - - name: print-results
        template: print-results

  - name: run-load-test
    script:
      volumeMounts:
      - name: workdir
        mountPath: /mnt/app
      image: grafana/k6:latest
      command: ["k6"]
      args: ["run"]
      source: |
        import http from "k6/http";
        import { sleep } from "k6";
        export const options = {
          vus: 10,
          duration: "3s",
        };
        export default function () {
          http.get("http://test.k6.io");
          sleep(1);
        }

        export function handleSummary(data) {
          return {
            "/mnt/app/summary.json": json.stringify(data.metrics.iteration_duration.values),
          };
        }
  - name: print-results
    script:
      volumeMounts:
      - name: workdir
        mountPath: /mnt/app
      image: busybox
      command: [sh]
      source: |
        ls -l /mnt/app/

  volumes:
    - name: shared-volume
      emptyDir: {}

Solution

  • Currently, the only way I found to achieve a solution is to add a patch to the pod spec which defines the user, group and FS group:

    apiVersion: argoproj.io/v1alpha1
    kind: Workflow
    metadata:
      generateName: reproduced-failure-to-write-from-k6-
    spec:
      volumeClaimTemplates:
      - metadata:
          name: workdir
        spec:
          accessModes: [ "ReadWriteOnce" ]
          resources:
            requests:
              storage: 1Gi
    
      entrypoint: main
      templates:
      - name: main
        steps:
        - - name: run-load-test
            template: run-load-test
        - - name: print-results
            template: print-results
    
    
    
      - name: run-load-test
        script:
          volumeMounts:
          - name: workdir
            mountPath: /mnt/app
          image: grafana/k6:latest
          command: ["k6"]
          args: ["run"]
          source: |
            import http from "k6/http";
            import { sleep } from "k6";
            export const options = {
              vus: 10,
              duration: "3s",
            };
            export default function () {
              http.get("http://test.k6.io");
              sleep(1);
            }
    
            export function handleSummary(data) {
              return {
                "/mnt/app/summary.json": JSON.stringify(data.metrics.iteration_duration.values),
              };
            }
      - name: print-results
        script:
          volumeMounts:
          - name: workdir
            mountPath: /mnt/app
          image: busybox
          command: [sh]
          source: |
            ls -l /mnt/app/
    
      podSpecPatch: |
        securityContext:
          runAsUser: 1000
          runAsGroup: 1000
          fsGroup: 1000
    
    
      volumes:
        - name: shared-volume
          emptyDir: {}
    

    Adding fsGroup to the security context of the workflow, step or container failed with the error:

    Failed to parse workflow: json: unknown field "fsGroup"