Objectives
- Deploy the Contrast Agent Operator using a Helm chart.
- Configure a Kubernetes application deployment to be injected by the operator.
- Basic troubleshooting guidance.
Process
The steps below assume you have Helm installed and the system on which it is being run has internet access.
Add the Contrast Helm repository
Run the following command:
helm repo add contrast https://contrastsecurity.dev/helm-charts
To verify which repositories have been installed:
helm repo list
You should see output similar to this:
NAME URL
bitnami https://charts.bitnami.com/bitnami
contrast https://contrastsecurity.dev/helm-charts
Now update it to the latest:
helm repo update contrast
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "contrast" chart repository
Update Complete. ⎈Happy Helming!⎈
Basic configuration
By default, the configuration values shown at https://contrastsecurity.dev/helm-charts/# will take effect when you create a release of a chart. To override any of these (which you must do to, for example, provide the service key, API key etc.) you can first get a list of all current values and write them to a file like this:
helm show values contrast/contrast-agent-operator > values.yaml
Then edit values.yaml
to modify whatever you want/need to customize. For example here I am adding the credentials that a Contrast agent will need to communicate with the Contrast UI, setting all agents to log at the INFO level and overriding the Java agent operator version to always use agent version 6.10.0:
clusterDefaults:
enabled: true
url: https://app-agents.contrastsecurity.com/Contrast
existingSecret:
apiKeyValue: *****
serviceKeyValue: *****
userNameValue: *****
yaml: |-
enable: true
agent:
logger:
level: INFO
agentInjectors:
enabled: true
namespaces:
- default
injectors:
- language: java
name: contrast-java-injector
enabled: true
selector:
labels:
- name: contrast-agent
value: java
imageVersion: 6.10.0
- language: dotnet-core
name: contrast-dotnet-core-injector
selector:
labels:
- name: contrast-agent
value: dotnet-core
- language: nodejs
name: contrast-nodejs-injector
selector:
labels:
- name: contrast-agent
value: nodejs
- language: nodejs-esm
name: contrast-nodejs-esm-injector
selector:
labels:
- name: contrast-agent
value: nodejs-esm
- language: php
name: contrast-php-injector
selector:
labels:
- name: contrast-agent
value: php
- language: python
name: contrast-python-injector
selector:
labels:
- name: contrast-agent
value: python
Install the Helm Chart with the above configuration changes
Now you can install the chart - note that we are creating it as a named release (contrast-agent-operator
):
helm upgrade --install -f values.yaml contrast-agent-operator contrast/contrast-agent-operator
Release "contrast-agent-operator" has been upgraded. Happy Helming!
NAME: contrast-agent-operator
LAST DEPLOYED: Wed Nov 6 15:02:46 2024
NAMESPACE: contrast-agent-operator
STATUS: deployed
REVISION: 5
TEST SUITE: None
NOTES:
contrast-agent-operator chart version 1.5.2 deployed!
✅ 6 injectors have been deployed to namespace: default
To use with your workloads:
contrast-java-injector (java/v6.10.0):
⎈ kubectl label deployment/<your_deployment_name> contrast-agent=java
contrast-dotnet-core-injector (dotnet-core):
⎈ kubectl label deployment/<your_deployment_name> contrast-agent=dotnet-core
contrast-nodejs-injector (nodejs):
⎈ kubectl label deployment/<your_deployment_name> contrast-agent=nodejs
contrast-nodejs-esm-injector (nodejs-esm):
⎈ kubectl label deployment/<your_deployment_name> contrast-agent=nodejs-esm
contrast-php-injector (php):
⎈ kubectl label deployment/<your_deployment_name> contrast-agent=php
contrast-python-injector (python):
⎈ kubectl label deployment/<your_deployment_name> contrast-agent=python
✅ Cluster agent defaults deployed
👀 To watch the operator logs:
⎈ kubectl logs -f -l app.kubernetes.io/part-of=contrast-agent-operator --namespace contrast-agent-operator
📄 More documentation: https://docs.contrastsecurity.com/en/agent-operator.html
🙋 Get support: https://support.contrastsecurity.com / support@contrastsecurity.com
🙋 Get support: https://support.contrastsecurity.com / support@contrastsecurity.com
Create an app to be injected
The following example shows a Java application deployment that will be injected by the agent operator once correctly labeled.
Here's the deployment manifest of an application named Petclinic:
apiVersion: apps/v1
kind: Deployment
metadata:
name: petclinic
namespace: default
spec:
selector:
matchLabels:
app: petclinic
template:
metadata:
labels:
app: petclinic
spec:
containers:
- name: petclinic
image: arey/springboot-petclinic:latest
ports:
- containerPort: 8080
Deploy it to Kubernetes as you normally would:
kubectl apply -f petclinic_deploy_unlabeled.yaml
As you can see by running the following command, this (and the other app deployments in the namespace) are as yet unlabeled:
kubectl get deployments --show-labels --namespace default
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
netflicks 1/1 1 1 19s <none>
petclinic 1/1 1 1 3m44s <none>
vulnpy 1/1 1 1 8s <none>
Label the app deployment
Now we want to label the petclinic one so that it will get injected with a Java agent when a pod comes up:
kubectl label deployment petclinic contrast-agent=java
See the result here:
kubectl get deployments --show-labels --namespace default
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
netflicks 1/1 1 1 66m <none>
petclinic 1/1 1 1 70m contrast-agent=java
vulnpy 1/1 1 1 66m <none>
Nothing will happen yet until we Install the Helm chart telling it what the operator needs to do:
Optional Agent Configuration
The Contrast Agent Operator Helm Chart does not currently include the ability to add an AgentConfiguration directly in the Helm chart, but if you look at the values you will see in the injectors section that you can provide the name of an AgentConfiguration that applies to, for example, the Java injector here:
injectors:
- language: java
name: contrast-java-injector
# Optional, defaults to true (enabled)
enabled: true
# Optional, specify labels and/or image names to inject. If omitted, all workloads will be injected.
# Label selections are cumulative using the logical AND operation.
selector:
labels:
- name: contrast-agent
value: java
#images:
# - imagename
# Optional image configuration.
# image:
# registry: docker.io/contrast
# name: agent-java
# pullPolicy: Always
# Optional image version, defaults to latest
#imageVersion: 5
# Optional name of an AgentConfiguration to use with this injector
#configurationName: custom-config-name
# Optional name of an AgentConnection to use with this injector
#connectionName: custom-connection-name
If you take this approach you would have to separately deploy an AgentConfiguration manifest as shown here in the operator documentation (https://docs.contrastsecurity.com/en/agent-operator-configuration.html#agentconfiguration) and provide the configuration name in the injector definition above.
Alternatively (and probably preferably if you have other Java containers being injected with the same injector) you can instead add an environment variable to the application deployment manifest instead. The configuration item would be CONTRAST__APPLICATION__GROUP
(note the double underscores).
Troubleshooting
Install troubleshooting
In case of an error when installing, you can add the --debug
option to the install command.
List current releases
helm list --namespace contrast-agent-operator
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
contrast-agent-operator contrast-agent-operator 5 2024-11-06 15:02:46.846522 -0500 EST deployed contrast-agent-operator-1.5.2 1.5.2
Get values that were set by the user in this release
In this example you can see where all agents have been set to log at the INFO level and the Java agent operator version is set to to always use agent version 6.10.0:
helm get values contrast-agent-operator
USER-SUPPLIED VALUES:
agentInjectors:
enabled: true
injectors:
- enabled: true
imageVersion: 6.10.0
language: java
name: contrast-java-injector
selector:
labels:
- name: contrast-agent
value: java
- language: dotnet-core
name: contrast-dotnet-core-injector
selector:
labels:
- name: contrast-agent
value: dotnet-core
- language: nodejs
name: contrast-nodejs-injector
selector:
labels:
- name: contrast-agent
value: nodejs
- language: nodejs-esm
name: contrast-nodejs-esm-injector
selector:
labels:
- name: contrast-agent
value: nodejs-esm
- language: php
name: contrast-php-injector
selector:
labels:
- name: contrast-agent
value: php
- language: python
name: contrast-python-injector
selector:
labels:
- name: contrast-agent
value: python
namespaces:
- default
clusterDefaults:
apiKeyValue: *****
enabled: true
existingSecret: null
serviceKeyValue: *****
url: https://app-agents.contrastsecurity.com/Contrast
userNameValue: *****
yaml: |-
enable: true
agent:
logger:
level: INFO
helm show values contrast-agent-operator
will return all the values, not just the user supplied ones. There's also the additional option of helm get manifest contrast-agent-operator
which provides a comprehensive list of everything, including the user supplied values.Change user supplied values
To change user supplied values, simply modify the values file and run the install again:
helm upgrade --install -f values.yaml contrast-agent-operator contrast/contrast-agent-operator
Uninstall a named release
helm uninstall contrast-agent-operator
release "contrast-agent-operator" uninstalled