Deploy Node.js Agent Using Init Containers

An example illustrating how to deploy on Kubernetes a sample application with the Node.js Agent using an init container (a.k.a. sidecar).

The init containers option, available in Kubernetes, is used to run additional containers at application startup. You can use this option to deploy your Seeker Agents without modifying your application images. This is achieved by downloading an Agent package using an init container, and loading it to the application container dynamically.

  1. Save the following code snippet in a file, for example, juiceshop.yml:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: juice-shop
      namespace: apps
    spec:
      selector:
        matchLabels:
          app: juice-shop
      template:
        metadata:
          labels:
            app: juice-shop
        spec:
          initContainers:
              # Download the Node.js Agent package and extract it to the shared folder /seeker.
            - name: download-agent
              image: busybox:stable
              command:
                - /bin/sh
                - -c
                - |              
                  echo "Download Seeker Node.js from: ${SEEKER_SERVER_URL}/rest/api/latest/installers/agents/binaries/NODEJS?flavor=TARGZ"
                  wget --no-check-certificate -O /tmp/seeker.tgz "${SEEKER_SERVER_URL}/rest/api/latest/installers/agents/binaries/NODEJS?flavor=TARGZ"
                  mkdir -p /seeker
                  tar zxvf /tmp/seeker.tgz -C /seeker
                  rm -f /tmp/seeker.tgz
    
              # Set the env variables below to point to your own server and project.
              env:
                - name: SEEKER_SERVER_URL
                  value: "https://seeker-server:8443"
                - name: SEEKER_PROJECT_KEY
                  value: "juice-shop-k8s"
              volumeMounts:
                - name: seeker-agent
                  mountPath: "/seeker"
          containers:
            - name: juice-shop
              image: bkimminich/juice-shop
              ports:
                - containerPort: 3000          
              env:
                - name: SEEKER_SERVER_URL
                  value: "https://seeker-server:8443"
                - name: SEEKER_PROJECT_KEY
                  value: "juice-shop-k8s"
                  # Instruct the Node.js runtime to load the Agent on its start
                - name: NODE_OPTIONS
                  value: "-r /seeker/package"
              volumeMounts:
                - name: seeker-agent
                  mountPath: "/seeker"
          volumes:
            - name: seeker-agent
              emptyDir: {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: juice-shop-service
      namespace: apps
    spec:
      type: NodePort
      selector:
        app: juice-shop
      ports:
        - name: "http"
          protocol: TCP
          port: 3000
          targetPort: 3000
          nodePort: 31082
  2. Deploy the application:
    kubectl apply -f juiceshop.yml
    The application starts with the NODE_OPTIONS variable that instructs the Node.js runtime to load the Agent on its start.