Search code examples
bashkuberneteskubectlk6

how do I pipe in file content as args to kubectl?


I wish to run k6 in a container with some simple javascript load from local file system, It seems the below had some syntax error

$ cat simple.js
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
  vus: 10,
  duration: '30s',
};
export default function () {
  http.get('http://100.96.1.79:8080');
  sleep(1);
}

$kubectl run k6 --image=grafana/k6 -- run - <simple.js 
//OR
$kubectl run k6 --image=grafana/k6 run - <simple.js

in the k6 pod log, I got

│ time="2023-02-16T12:12:05Z" level=error msg="could not initialize '-': could not load JS test 'file:///-': no exported functions in s │

I guess this means the simple.js is not really passed to k6 this way?

thank you!


Solution

  • I think you can't pipe (host) files into Kubernetes containers this way.

    One way that it should work is to:

    1. Create a ConfigMap to represent your file
    2. Apply a Pod config that mounts the ConfigMap file
    NAMESPACE="..." # Or default
    
    kubectl create configmap simple \
    --from-file=${PWD}/simple.js \
    --namespace=${NAMESPACE}
    
    kubectl get configmap/simple \
    --output=yaml \
    --namespace=${NAMESPACE}
    

    Yields:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: simple
    data:
      simple.js: |
        import http from 'k6/http';
        import { sleep } from 'k6';
    
        export default function () {
          http.get('http://test.k6.io');
          sleep(1);
        }
    

    NOTE You could just create e.g. configmap.yaml with the above YAML content and apply it.

    Then with pod.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: simple
    spec:
      containers:
        - name: simple
          image: docker.io/grafana/k6
          args:
          - run
          - /m/simple.js
          volumeMounts:
          - name: simple
            mountPath: /m
      volumes:
        - name: simple
          configMap:
            name: simple
    

    Apply it:

    kubectl apply \
    --filename=${PWD}/pod.yaml \
    --namespace=${NAMESPACE}
    

    Then, finally:

    kubectl logs pod/simple \
    --namespace=${NAMESPACE}
    

    Yields:

    
              /\      |‾‾| /‾‾/   /‾‾/   
         /\  /  \     |  |/  /   /  /    
        /  \/    \    |     (   /   ‾‾\  
       /          \   |  |\  \ |  (‾)  | 
      / __________ \  |__| \__\ \_____/ .io
    
      execution: local
         script: /m/simple.js
         output: -
    
      scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
               * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)
    
    
    running (00m01.0s), 1/1 VUs, 0 complete and 0 interrupted iterations
    default   [   0% ] 1 VUs  00m01.0s/10m0s  0/1 iters, 1 per VU
    
    running (00m01.4s), 0/1 VUs, 1 complete and 0 interrupted iterations
    default ✓ [ 100% ] 1 VUs  00m01.4s/10m0s  1/1 iters, 1 per VU
    
         data_received..................: 17 kB 12 kB/s
         data_sent......................: 542 B 378 B/s
         http_req_blocked...............: avg=128.38ms min=81.34ms med=128.38ms max=175.42ms p(90)=166.01ms p(95)=170.72ms
         http_req_connecting............: avg=83.12ms  min=79.98ms med=83.12ms  max=86.27ms  p(90)=85.64ms  p(95)=85.95ms 
         http_req_duration..............: avg=88.61ms  min=81.28ms med=88.61ms  max=95.94ms  p(90)=94.47ms  p(95)=95.2ms  
           { expected_response:true }...: avg=88.61ms  min=81.28ms med=88.61ms  max=95.94ms  p(90)=94.47ms  p(95)=95.2ms  
         http_req_failed................: 0.00% ✓ 0        ✗ 2  
         http_req_receiving.............: avg=102.59µs min=67.99µs med=102.59µs max=137.19µs p(90)=130.27µs p(95)=133.73µs
         http_req_sending...............: avg=67.76µs  min=40.46µs med=67.76µs  max=95.05µs  p(90)=89.6µs   p(95)=92.32µs 
         http_req_tls_handshaking.......: avg=44.54ms  min=0s      med=44.54ms  max=89.08ms  p(90)=80.17ms  p(95)=84.62ms 
         http_req_waiting...............: avg=88.44ms  min=81.05ms med=88.44ms  max=95.83ms  p(90)=94.35ms  p(95)=95.09ms 
         http_reqs......................: 2     1.394078/s
         iteration_duration.............: avg=1.43s    min=1.43s   med=1.43s    max=1.43s    p(90)=1.43s    p(95)=1.43s   
         iterations.....................: 1     0.697039/s
         vus............................: 1     min=1      max=1
         vus_max........................: 1     min=1      max=1
    

    Tidy:

    kubectl delete \
    --filename=${PWD}/pod.yaml \
    --namespace=${NAMESPACE}
    
    kubectl delete configmap/simple \
    --namespace=${NAMESPACE}
    
    kubectl delete namespace/${NAMESPACE}