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
- Setup a local kubernetes environment if you do not already have one available to you. Below are a few of the available options:
- Install Docker & kubernetes, follow instructions on https://docs.docker.com/docker-for-mac/install/
- Install and start Minikube, follow instructions on https://kubernetes.io/docs/tasks/tools/install-minikube/
- 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.
- 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 .
- 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
- 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
- Create a secret using
kubectl
:
kubectl create secret generic contrast-security --from-file=./contrast_security.yaml
- 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
- 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
- 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
- Create the configmap:
kubectl create configmap contrast-config --from-env-file=contrast.properties
- 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
- Apply the deployment file:
kubectl apply -f juiceshop_deployment.yaml
- Finally configure a load balancer to expose the application:
kubectl expose deployment juiceshop --type=LoadBalancer --name=juiceshop-lb
- 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