Kubernetes - Goof Node.js
Running an application in a Kubernetes environment allows you to demonstrate the Snyk Kubernetes integrations.
Step 1 - Build a Kubernetes Cluster
You can build this on an x86 based laptop or other systems you may have laying around. Deploying k8s on an M1 Mac and Raspberry Pi’s has been largely ineffective and a waste of time.
Alternatively you can use this guide to deploy in our Google Cloud environment, GKE Kubernetes Cluster.
Step 2 - Build a Container
This guide outlines how to build a container that will run on x86 hardware, Containers - Snyk Goof Node.js.
Step 3 - Create a Namespace
Creating a dedicated namespace in k8s allows you to easily create and destroy deployments without worrying about wrecking other working apps. You are able to skip this step, and everything created will be deployed to the default namespace.
Use a naming convention that works for you. Because we often will use the same code in multiple SCM’s, Container Registries, and CI/CD tools that is the convention below. I.e. the app is the Node.js version of goof, the code is hosted in GitHub repos, the container is stored in DockerHub, and the container will be run in Google Kubernetes Engine:
kubectl create namespace node-goof-github-dockerhub-gke
Step 4 - Develop a Kubernetes Deployment for MondoDB
This application requires a functional mongoDB instance. Create a file called goof-mongo-deployment.yml and copy/paste the script below into it. Some notes on the configuration file:
-
Keeping the same namespace is important to ensure connectivity.
-
In the
specsection there is an environment variable,DOCKER = 1. This is critical in getting the pods to communicate. -
The image is specifically using
mongo:3. Other versions don’t seem to work.
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.31.2 (HEAD)
creationTimestamp: null
labels:
app: node-goof-mongo-github-dockerhub-gke
io.kompose.service: goof-mongo
name: node-goof-mongo-github-dockerhub-gke
namespace: node-goof-github-dockerhub-gke
spec:
replicas: 1
selector:
matchLabels:
app: node-goof-mongo-github-dockerhub-gke
strategy: {}
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.31.2 (HEAD)
creationTimestamp: null
labels:
app: node-goof-mongo-github-dockerhub-gke
io.kompose.network/node-goof-github-dockerhub-gke-default: "true"
io.kompose.service: node-goof-mongo-github-dockerhub-gke
spec:
containers:
- env:
- name: DOCKER
value: "1"
image: mongo:3
name: node-goof-mongo-github-dockerhub-gke
ports:
- containerPort: 27017
hostPort: 27017
protocol: TCP
resources: {}
restartPolicy: Always
status: {}
Step 4 - Apply the MongoDB Configuration
Deploy the MongoDB configuration above with the following:
kubectl apply -f ./goof-mongo-deployment.yml
Later when you want to remove the configuration:
kubectl delete -f ./goof-mongo-deployment.yml
Step 4 - Get the MongoDB IP
We’ll need to tell the app server where the DB is. Running the following command will provide the IP address of the MongoDB pod. Be sure to replace the namespace (-n) with whatever you’ve used.
kubectl get pods -n node-goof-github-dockerhub-gke -o wide
We’ll be using this data in the next steps.
Step 5 - Develop a Kubernetes Deployment for Goof
Create a deployment and service for the app server.
Create a file called goof-deployment.yml with the following contents. Some notes on the configuration file:
-
The namespace must be the same in all of these files.
-
In the
specsection there is an environment variable,DOCKER = 1. This is critical in getting the pods to communicate. -
Ensure the
imagebeing used is the correct one for x86/amd systems and not a container that runs on your laptop. -
The
ipunderhostAliasesis the IP address of the MongoDB server identified in the previous step.
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.31.2 (HEAD)
creationTimestamp: null
labels:
app: node-goof-github-dockerhub-gke
io.kompose.service: node-goof-github-dockerhub-gke
name: node-goof-github-dockerhub-gke
namespace: node-goof-github-dockerhub-gke
spec:
replicas: 1
selector:
matchLabels:
app: node-goof-github-dockerhub-gke
strategy: {}
template:
metadata:
labels:
app: node-goof-github-dockerhub-gke
io.kompose.service: node-goof-github-dockerhub-gke
spec:
containers:
- env:
- name: DOCKER
value: "1"
image: freshdemo/node-goof-github-dockerhub-gke:gha@sha256:8941c76ce8908b6e1ed04ef58ac5f7981875d7ed7b45730bbbfdbc73f5208410
name: node-goof-github-dockerhub-gke
resources: {}
restartPolicy: Always
hostAliases:
- ip: "10.124.2.54"
hostnames:
- "goof-mongo"
status: {}
Step 6 - Develop a Kubernetes Service for Goof
Create a file called goof-service.yml with the following contents. You could also include this configuration in the deployment file to consolidate, however it’s sometimes handy to leave the service intact while you delete and reapply the deployment. Some notes on the configuration file:
-
The namespace must match across all of these files.
-
The
port3001 can be modified, however leave thetargetPortas 3001.portis what you’ll use to access the service.
apiVersion: v1
kind: Service
metadata:
labels:
app: node-goof-github-dockerhub-gke
name: node-goof-github-dockerhub-gke
namespace: node-goof-github-dockerhub-gke
spec:
type: LoadBalancer
ports:
- name: "3001"
port: 3001
targetPort: 3001
- name: "9229"
port: 9229
targetPort: 9229
selector:
app: node-goof-github-dockerhub-gke
Step 7 - Apply the Kubernetes Deployment & Service for Goof
You can apply both configurations at the same time with the following:
kubectl apply -f ./goof-deployment.yml,goof-service.yml
Make sure the pods have been created successfully with:
kubectl get pods -n node-goof-github-dockerhub-gke -o wide
Step 8 - Access the Application
To get to the application we need to determine the public IP address of the service.
kubectl get services -n node-goof-github-dockerhub-gke
From here you can access the application by visiting http://<service IP>:3001
Step 9 - Destroy the Configurations
These are vulnerable applications and should not be left running. You can either delete the various parts by specifying individual configuration files, or use the following to remove everything;
kubectl delete -f ./goof-deployment.yml,goof-service.yml,goof-mongo-deployment.yml
Troubleshooting
Troubleshooting
-
Check to see what’s running in your namespace
kubectl get pods -n node-goof-github-dockerhub-gke -o wide
-
Check the logs of the pod identified in step 1 above. This can be helpful to identify issues with your container or the app not starting.
kubectl logs -n node-goof-github-dockerhub-gke node-goof-github-dockerhub-gke-648cc55d8d-s6qcp
-
Check the services to get the public IP address
kubectl get services -n node-goof-github-dockerhub-gke -o wide
-
Delete the pod identified in step 1. This can be helpful if you want to re-pull the container image.
kubectl delete pod -n node-goof-github-dockerhub-gke node-goof-github-dockerhub-gke-648cc55d8d-s6qcp
-
Make sure the environment variable DOCKER = 1 is set correctly in the MongoDB and Goof deployment, otherwise they will not be able to communicate and the app will not start.