Node.js Agent with Kubernetes

  • Updated
Note: Contrast has released an Agent Operator for kubernetes which can simplify the addition of Contrast agents into your environment. More information can be found here in our documentation.

 

 This guide provides a working example of setting up and configuring the Contrast Node.js agent within a kubernetes environment.   This guide assumes you have basic working knowledge of git, docker and kubernetes.

Prerequisites

  1. Setup a local kubernetes environment if you do not already have one available to you.  Below are a few of the available options:
  2. Clone the following repo that will be used for this tutorial:
git clone https://github.com/Contrast-Security-OSS/contrastsecurity-node-docker-onboarding-guide-sample-project.git

 

Building and setting up the Node.js application's image w/Contrast


Inspect the Dockerfile, and note these two lines:

Line 7 utilizes npm to install the latest Contrast Node.js agent onto the image.

RUN npm install --production @contrast/agent

Line 10 has updated startup CMD to preload the Contrast agent.

CMD ["node", "-r", "@contrast/agent", "build/app"]

For more details on adding the Contrast agent to your application/image. See our docker guide on the subject.

  1. In your terminal, navigate to the cloned repo's folder and run the following command to build the docker image:
docker build --rm -t juiceshop:contrast -f Dockerfile.from-app-image .
  1. Tag and push your image to a local or public repo:
docker tag juiceshop:contrast example/juiceshop-k8s:contrast

docker push example/juiceshop-k8s:contrast

Now this image can be used in the kubernetes deployment.

 

Setting up the Kubernetes environment


  1. Download the contrast_security.yaml

YAML file should look like the following for our Node.js agent:

api: 
  url: http(s)://<dns>/Contrast
  api_key: <apiKey>
  service_key: <serviceKey>
  user_name: agent_<hashcode>@<domain>
agent: 
  service: 
    grpc: true
  1. Create a secret using kubectl:
kubectl create secret generic contrast-security --from-file=./contrast_security.yaml
This secret can be used by all Node agents. So it is preferable to keep this generic and make all app level configuration changes with environment variables.
  1. Create the applications deployment file and add the contrast_security secret. This will mount the file under /etc/contrast/:
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: juiceshop
spec: 
  replicas: 1
  selector: 
    matchLabels: 
      component: juiceshop
  template:
    metadata:
      labels:
        component: juiceshop
    spec:
      containers:
      - name: juiceshop
        image: example/juiceshop-k8s:contrast
        ports: 
          - containerPort: 3000
        # Volume Mount for contrast_security.yaml  
        volumeMounts:
        - name: contrast-security
          readOnly: true
          mountPath: "/etc/contrast"
        resources:
          requests:
            cpu: 1.0
            memory: 2Gi
          limits:
            cpu: 2.0
            memory: 4Gi
      # Volume from contrast-security secret     
      volumes:
      - name: contrast-security
        secret:
          secretName: contrast-security
  1. Add application level configurations to setup logging, pointer to the contrast_security.yaml and any desired name/environment updates. A full list of configurations options are provided in our documentation here
spec:
containers:
- name: juiceshop
image: example/juiceshop-k8s:contrast
ports:
- containerPort: 3000
env:
- name: CONTRAST__APPLICATION__NAME value: "juiceshop-k8s" - name: CONTRAST__SERVER__NAME value: "EKS-Node-Pod" - name: CONTRAST__SERVER__ENVIRONMENT value: "QA" - name: CONTRAST_CONFIG_PATH value: "/etc/contrast/contrast_security.yaml" - name: CONTRAST__AGENT__LOGGER__STDOUT value: "true" - name: CONTRAST__AGENT__LOGGER__LEVEL value: "INFO" - name: CONTRAST__AGENT__SERVICE__LOGGER__STDOUT value: "true" - name: CONTRAST__AGENT__SERVICE__LOGGER__LEVEL value: "INFO"

Optionally: these could also be defined via configmaps

  1. Create a file called contrast.properties with the same environment variables defined:
CONTRAST__APPLICATION__NAME=juiceshop-k8s
CONTRAST__SERVER__NAME=Juiceshop-Pod
CONTRAST__SERVER__ENVIRONMENT=QA
CONTRAST_CONFIG_PATH=/etc/contrast/contrast_security.yaml
CONTRAST__AGENT__LOGGER__STDOUT=true
CONTRAST__AGENT__LOGGER__LEVEL=INFO
CONTRAST__AGENT__SERVICE__LOGGER__STDOUT=true
CONTRAST__AGENT__SERVICE__LOGGER__LEVEL=INFO
  1. Create the configmap:
kubectl create configmap contrast-config --from-env-file=contrast.properties
  1. Update the deployment file to reference the configmap:
spec:
      containers:
      - name: testbench
        image: example/juiceshop-k8s:contrast
        ports: 
          - containerPort: 3000
        envFrom:
          - configMapRef:
              name: contrast-config
  1. Apply the deployment file:
kubectl apply -f juiceshop_deployment.yaml
  1. Finally configure a load balancer to expose the application:
kubectl expose deployment juiceshop --type=LoadBalancer --name=juiceshop-lb
  1. Check on the deployed application in kubernetes and access the site at External-IP/port 3000
kubectl get all

Note: External-IP will show "pending" if using Minikube. Run minikube tunnel to connect to LoadBalancer services

 

Sources for this example can be found on our github repo: contrastsecurity-node-docker-onboarding-guide-sample-project

 

Known Issues

 

Was this article helpful?

0 out of 0 found this helpful

Have more questions? Submit a request