This guide provides a working example of setting up and configuring the Contrast .NET Core 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/demo-netflicks.git
Building and setting up the .NET Core application's image with Contrast
Inspect the Dockerfile.contrast
, you should note a few sections where the Contrast agent is added:
Lines 12-17 utilizes a build stage to fetch in the latest Contrast .NET Core agent. as a Nuget package and unzips it to a temporary directory in the build image:
# Add contrast sensor package
ADD https://www.nuget.org/api/v2/package/Contrast.SensorsNetCore /tmp/contrast.sensorsnetcore.nupkg
RUN apt-get update \
&& apt-get install -y unzip \
&& unzip /tmp/contrast.sensorsnetcore.nupkg -d /tmp/contrast \
&& rm /tmp/contrast.sensorsnetcore.nupkg
Line 26 copies in the resulting directory from the build image to the final image.
COPY --from=publish /tmp/contrast /opt/contrast
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 -f Dockerfile.contrast . -t netflicks:1.0
- Tag and push your image to a local or public repo.
docker tag netflicks:contrast example/netflicks:contrast docker push example/netflicks:contrast
Now this image can be used in the kubernetes deployment.
Setting up the Kubernetes environment
- Download the
contrast_security.yaml
and create a secret
YAML file should look like the following for our .NET Core agent:
api:
url: http(s)://<dns>/Contrast
api_key: <apiKey>
service_key: <serviceKey>
user_name: agent_<hashcode>@<domain>
Create a secret using kubectl
kubectl create secret generic contrast-security --from-file=./contrast_security.yaml
This secret can be used by all .Net Core agents. So it is preferable to keep this generic and make all app level configuration changes with environment variables.
- Create the applications deployment file and add the contrast_security secret. This will mount the file under
/etc/contrast/
---
apiVersion: v1
kind: Service
metadata:
name: netflicks-db-service
spec:
selector:
app: netflicks-db
ports:
- protocol: TCP
port: 1433
targetPort: 1433
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: netflicks-controller-svc
spec:
type: LoadBalancer
selector:
app: netflicks
ports:
- name: "netflicks"
port: 8080
targetPort: 80
---
apiVersion: v1
kind: ReplicationController
metadata:
name: netflicks-controller
spec:
replicas: 1
template:
metadata:
labels:
app: netflicks
spec:
containers:
- name: netflicks-db
image: mcr.microsoft.com/mssql/server:2019-latest
ports:
- containerPort: 1433
env:
- name: ACCEPT_EULA
value: "Y"
- name: SA_PASSWORD
value: "reallyStrongPwd123"
- name: netflicks
image: example/netflicks:contrast
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: contrast-config
volumeMounts:
- name: contrast-security
readOnly: false
mountPath: "/etc/contrast/"
env:
- name: ConnectionStrings__DotNetFlicksConnection
value: "Server=tcp:localhost,1433;Initial Catalog=DotNetFlicksDb;Persist Security Info=False;User ID=sa;Password=reallyStrongPwd123;MultipleActiveResultSets=False;"
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
env:
- name: CONTRAST__APPLICATION__NAME
value: "netflicks-k8s"
- name: CONTRAST__SERVER__NAME
value: "EKS-Core-Pod"
- name: CONTRAST__SERVER__ENVIRONMENT
value: "QA"
- name: CONTRAST_CONFIG_PATH
value: "/etc/contrast/contrast_security.yaml"
- name: AGENT__LOGGER__STDOUT
value: "true"
- name: AGENT__LOGGER__LEVEL
value: "INFO"
- name: CORECLR_PROFILER_PATH_64
value: "/opt/contrast/contentFiles/any/netstandard2.0/contrast/runtimes/linux-x64/native/ContrastProfiler.so"
- name: CORECLR_PROFILER
value: "{8B2CE134-0948-48CA-A4B2-80DDAD9F5791}"
- name: CORECLR_ENABLE_PROFILING
value: "1"
- name: CONTRAST_CORECLR_LOGS_DIRECTORY
value: "/opt/contrast"
Optionally: these can also be defined via configmaps as follows:
Create a file called contrast.properties
with the same environment variables defined.
CONTRAST__APPLICATION__NAME=netflicks-k8s CONTRAST__SERVER__NAME=EKS-Core-Pod CONTRAST__SERVER__ENVIRONMENT=qa CONTRAST_CONFIG_PATH=/etc/contrast/contrast_security.yaml AGENT__LOGGER__STDOUT=true AGENT__LOGGER__LEVEL=INFO CORECLR_PROFILER_PATH_64=/opt/contrast/contentFiles/any/netstandard2.0/contrast/runtimes/linux-x64/native/ContrastProfiler.so CORECLR_PROFILER={8B2CE134-0948-48CA-A4B2-80DDAD9F5791} CORECLR_ENABLE_PROFILING=1 CONTRAST_CORECLR_LOGS_DIRECTORY=/opt/contrast
Create the configmap:
kubectl create configmap contrast-config --from-env-file=contrast.properties
Update the deployment file to reference the configmap:
spec:
containers:
- name: netflicks
image: example/netflicks-k8s:contrast
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: contrast-config
- Apply the deployment file:
kubectl apply -f netflicks_deployment.yaml
- Check on the deployed application in kubernetes and access the site at External-IP/port 8080:
kubectl get all
The sources for this example can be found on our github repo: demo-netflicks