Skip to content

Commit ddc8765

Browse files
authored
Merge pull request #31 from lightrun-platform/DEVOPS-2134-add-lightrun-java-agents-helm-chart
DEVOPS-2134-add-lightrun-java-agents-helm-chart
2 parents 544b149 + 15f1c0c commit ddc8765

File tree

9 files changed

+443
-0
lines changed

9 files changed

+443
-0
lines changed

.github/workflows/release.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
- lightrun-init-agent/*
1010
- .github/**
1111
- helm-chart/*
12+
- charts/*
1213
- grafana/*
1314
- config/*
1415
- examples/*
@@ -60,6 +61,11 @@ jobs:
6061
yq -i '.version = "${{steps.release_tag.outputs.new_tag}}"' helm-chart/Chart.yaml
6162
yq -i '.controllerManager.manager.image.tag = "${{steps.release_tag.outputs.new_tag}}"' helm-chart/values.yaml
6263
helm package ./helm-chart -u -d ./helm-repo/
64+
- name: Pack Lightrun Agents Helm chart
65+
shell: bash
66+
run: |
67+
yq -i '.version = "${{steps.release_tag.outputs.new_tag}}"' charts/lightrun-agents/Chart.yaml
68+
helm package ./charts/lightrun-agents -u -d ./helm-repo/
6369
6470
- name: Login to DockerHub
6571
if: ${{ success() }}

charts/lightrun-agents/.helmignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/

charts/lightrun-agents/Chart.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: v2
2+
name: lightrun-agents
3+
description: A Helm chart for Kubernetes that deploy lightrun agents CRDs
4+
5+
# A chart can be either an 'application' or a 'library' chart.
6+
#
7+
# Application charts are a collection of templates that can be packaged into versioned archives
8+
# to be deployed.
9+
#
10+
# Library charts provide useful utilities or functions for the chart developer. They're included as
11+
# a dependency of application charts to inject those utilities and functions into the rendering
12+
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
13+
type: application
14+
15+
# This is the chart version. This version number should be incremented each time you make changes
16+
# to the chart and its templates, including the app version.
17+
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18+
version: 0.0.1

charts/lightrun-agents/README.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# Helm Chart for Deploying Lightrun Agents
2+
3+
This Helm chart enables the deployment and management of Lightrun Agents as custom resources within your Kubernetes cluster. Currently, only Java-based agents are supported. The LightrunJavaAgent custom resource will be configured according to the settings specified in the values.yaml file.
4+
5+
## Prerequisites
6+
7+
- Kubernetes 1.19+
8+
- Ability to fetch images of the init containers from [Lightrun Repository Dockerhub](https://hub.docker.com/u/lightruncom). or alternatively have them available in private registry.
9+
10+
## Installation
11+
12+
### 1 - Add the repo to your Helm repository list
13+
14+
```shell
15+
helm repo add lightrun-k8s-operator https://lightrun-platform.github.io/lightrun-k8s-operator
16+
17+
```
18+
19+
### 2 - Prepare values.yaml
20+
21+
The values.yaml file includes the following configurable parameters for each Java agent object:
22+
23+
| Parameter | Description | Default |
24+
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
25+
| `javaAgents[].agentCliFlags` | [Command-line flags for the Lightrun Java Agent.](https://docs.lightrun.com/jvm/agent-configuration/#additional-command-line-flags). | Optional `""` (empty string) |
26+
| `javaAgents[].agentConfig` | [Additional configuration for the Lightrun Java Agent.](https://docs.lightrun.com/jvm/agent-configuration/#agent-flags). | Optional `{}` (empty map) |
27+
| `javaAgents[].agentEnvVarName` | Specifies the Java environment variable name used to add `--agentpath`. | Optional (if not provided, defaults to `"JAVA_TOOL_OPTIONS"`) |
28+
| `javaAgents[].agentName` | Custom name to assign to the Lightrun Java Agent. | Optional (if not provided, defaults to pod name) |
29+
| `javaAgents[].agentPoolCredentials.existingSecret` | Name of an existing Kubernetes secret that contains the API key and pinned certificate hash for the agent pool. [secret example](https://github.com/lightrun-platform/lightrun-k8s-operator/blob/main/examples/lightrunjavaagent.yaml#L64-L73). | Optional (if not provided, defaults to `name-secret`) |
30+
| `javaAgents[].agentPoolCredentials.apiKey` | Lightrun agent API key. | Required if `existingSecret` not set |
31+
| `javaAgents[].agentPoolCredentials.pinnedCertHash` | 64 character sha256 certificate public key hash for pinning. | Required if `existingSecret` not set |
32+
| `javaAgents[].agentTags` | [List of Lightrun Java Agent tags](https://docs.lightrun.com/jvm/tagging/#manage-lightrun-java-agent-tags). | Optional `[]` (empty list) |
33+
| `javaAgents[].containerSelector` | Selector for containers within the deployment to inject the Lightrun Java Agent. | Required |
34+
| `javaAgents[].deploymentName` | Name of the Kubernetes deployment to attach the Lightrun Java Agent. | Required |
35+
| `javaAgents[].initContainer.image` | Image for the Lightrun Java Agent init container. | Required |
36+
| `javaAgents[].initContainer.sharedVolumeMountPath` | Mount path for the shared volume in the init container. | Optional (if not provided, defaults to `"/lightrun"`" |
37+
| `javaAgents[].initContainer.sharedVolumeName` | Name of the shared volume for the init container. | Optional (if not provided, defaults to `"lightrun-agent-init"`" |
38+
| `javaAgents[].name` | Name of the Lightrun Java Agent custom resource. | Required |
39+
| `javaAgents[].namespace` | Namespace of the Lightrun Java Agent custom resource. Must be in the same namespace as the workload | Required |
40+
| `javaAgents[].serverHostname` | Hostname of the Lightrun server to connect the agent. | Required |
41+
42+
#### 2.1 - Set `initContainer.image`
43+
44+
Based on your workload's OS and architecture, you should select the appropriate DockerHub repository from the following options:
45+
46+
- [linux amd64](https://hub.docker.com/repository/docker/lightruncom/k8s-operator-init-java-agent-linux/general)
47+
- [linux arm64](https://hub.docker.com/repository/docker/lightruncom/k8s-operator-init-java-agent-linux-arm64/general)
48+
- [alpine amd64](https://hub.docker.com/repository/docker/lightruncom/k8s-operator-init-java-agent-alpine/general)
49+
- [alpine arm64](https://hub.docker.com/repository/docker/lightruncom/k8s-operator-init-java-agent-alpine-arm64/general)
50+
51+
After determining the appropriate image, you will need to choose a tag. The tag can either be "latest," which corresponds to the most up-to-date Lightrun version, or it can be a specific Lightrun version following the convention `<x.y.z>-init.<number>`. Typically, the `<number>` part is 0, but it is always good to verify on the DockerHub repository.
52+
53+
For your convenience, here are some possible combinations of how the final image might look:
54+
55+
```text
56+
Linux amd64 with the latest version -> lightruncom/k8s-operator-init-java-agent-linux:latest
57+
Linux amd64 with a specific version -> lightruncom/k8s-operator-init-java-agent-linux:1.39.1-init.0
58+
Linux arm64 with the latest version -> lightruncom/k8s-operator-init-java-agent-linux-arm64:latest
59+
Linux arm64 with a specific version -> lightruncom/k8s-operator-init-java-agent-linux-arm64:1.39.1-init.0
60+
Alpine amd64 with the latest version -> lightruncom/k8s-operator-init-java-agent-alpine:latest
61+
Alpine amd64 with a specific version -> lightruncom/k8s-operator-init-java-agent-alpine:1.39.1-init.0
62+
Alpine arm64 with the latest version -> lightruncom/k8s-operator-init-java-agent-alpine-arm64:latest
63+
Alpine arm64 with a specific version -> lightruncom/k8s-operator-init-java-agent-alpine-arm64:1.39.1-init.0
64+
```
65+
66+
#### 2.2 Install the chart
67+
68+
When installing the chart, it is important to understand that the -n flag provided in the helm install command does not determine where the actual resources will be deployed. Instead, deployment is controlled by the javaAgents[].namespace parameter for each object in the values.yaml file.
69+
70+
Use the -n flag to specify a namespace, either using the same namespace where your Lightrun Kubernetes Operator is installed or creating a new namespace specifically for this purpose, such as "lightrun-agents". This namespace will be referenced if you need to uninstall the chart later.
71+
72+
```bash
73+
helm install <release-name> lightrun-k8s-operator/lightrun-agents -n <namespace> -f values.yaml
74+
```
75+
76+
## Examples
77+
78+
### Basic
79+
80+
- The `my-service-1` does not use an `existingSecret` and instead the `agentPoolCredentials.apiKey` and `agentPoolCredentials.pinnedCertHash` are provided directly.
81+
82+
- The `my-service-2` uses an `existingSecret` named `my-existing-secret`
83+
84+
```yaml
85+
javaAgents:
86+
- name: 'my-service-1'
87+
namespace: 'my-namespace-1'
88+
deploymentName: "my-deployment-1"
89+
containerSelector:
90+
- my-container-1
91+
serverHostname: 'lightrun.example.com'
92+
initContainer:
93+
image: "lightruncom/k8s-operator-init-java-agent-linux:latest"
94+
agentPoolCredentials:
95+
existingSecret: ""
96+
apiKey: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
97+
pinnedCertHash: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
98+
agentTags:
99+
- env-production
100+
- service-my-server
101+
- region-us_east_1
102+
- provider-aws
103+
- name: 'my-service-2'
104+
namespace: 'my-namespace-2'
105+
initContainer:
106+
image: "lightruncom/k8s-operator-init-java-agent-linux:latest"
107+
deploymentName: "my-deployment-2"
108+
containerSelector:
109+
- my-container-2
110+
serverHostname: 'lightrun.example.com'
111+
agentPoolCredentials:
112+
existingSecret: "my-existing-secret"
113+
apiKey: ""
114+
pinnedCertHash: ""
115+
agentTags:
116+
- env-production
117+
- service-my-other-server
118+
- region-us_east_1
119+
- provider-aws
120+
```
121+
122+
### Full
123+
124+
- The `my-service-1` does not use an `existingSecret` and instead the `agentPoolCredentials.apiKey` and `agentPoolCredentials.pinnedCertHash` are provided directly.
125+
126+
- The `my-service-2` uses an `existingSecret` named `my-existing-secret`
127+
128+
```yaml
129+
javaAgents:
130+
- name: 'my-service-1'
131+
namespace: 'my-namespace-1'
132+
deploymentName: "my-deployment-1"
133+
containerSelector:
134+
- my-container-1
135+
serverHostname: 'lightrun.example.com'
136+
agentEnvVarName: '_JAVA_OPTIONS'
137+
agentConfig:
138+
max_log_cpu_cost: "2"
139+
agentCliFlags: "--lightrun_extra_class_path=<PATH_TO_JAR>:<PATH_TO_JAR>,lightrun_init_wait_time_ms"
140+
initContainer:
141+
image: "lightruncom/k8s-operator-init-java-agent-linux:latest"
142+
sharedVolumeName: 'my-shared-volume'
143+
sharedVolumeMountPath: '/mypath'
144+
agentPoolCredentials:
145+
existingSecret: ""
146+
apiKey: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
147+
pinnedCertHash: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
148+
agentTags:
149+
- env-production
150+
- service-my-server
151+
- region-us_east_1
152+
- provider-aws
153+
- name: 'my-service-2'
154+
namespace: 'my-namespace-2'
155+
initContainer:
156+
image: "lightruncom/k8s-operator-init-java-agent-linux:latest"
157+
sharedVolumeName: 'my-shared-volume'
158+
sharedVolumeMountPath: '/mypath'
159+
deploymentName: "my-deployment-2"
160+
containerSelector:
161+
- my-container-2
162+
serverHostname: 'lightrun.example.com'
163+
agentEnvVarName: 'JAVA_OPTS'
164+
agentConfig:
165+
max_log_cpu_cost: "2"
166+
agentCliFlags: "--lightrun_extra_class_path=<PATH_TO_JAR>:<PATH_TO_JAR>,lightrun_init_wait_time_ms"
167+
agentPoolCredentials:
168+
existingSecret: "my-existing-secret"
169+
apiKey: ""
170+
pinnedCertHash: ""
171+
agentTags:
172+
- env-production
173+
- service-my-other-server
174+
- region-us_east_1
175+
- provider-aws
176+
```
177+
178+
## Uninstallation
179+
180+
To uninstall the chart:
181+
182+
```bash
183+
helm uninstall <release-name> -n <namespace>
184+
```
185+
186+
This command removes all the Kubernetes components associated with the chart and deletes the release.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{{/*
2+
Compile all warnings into a single message, and call fail.
3+
*/}}
4+
5+
{{- define "javaAgents.checkConfig" -}}
6+
{{- $objectErrors := dict -}} {{/* Create a dictionary to store errors by agent name */}}
7+
8+
{{- range .Values.javaAgents }}
9+
{{- $objectName := .name }}
10+
{{- $objectErrorMsgs := list -}} {{/* Create a list to store errors for the current agent */}}
11+
12+
{{- /* Add error messages to the list if fields are missing */}}
13+
{{- if not .namespace }}
14+
{{- $objectErrorMsgs = append $objectErrorMsgs "Namespace Checker:\n Error: The 'namespace' field is missing. Please provide the 'namespace' parameter." -}}
15+
{{- end }}
16+
{{- if not .serverHostname }}
17+
{{- $objectErrorMsgs = append $objectErrorMsgs "Server Hostname Checker:\n Error: The 'serverHostname' field is missing. Please provide the 'serverHostname' parameter." -}}
18+
{{- end }}
19+
{{- if not .name }}
20+
{{- $objectErrorMsgs = append $objectErrorMsgs "Name Checker:\n Error: The 'name' field is missing. Please provide the 'name' parameter." -}}
21+
{{- end }}
22+
{{- if not .initContainer.image }}
23+
{{- $objectErrorMsgs = append $objectErrorMsgs "Init Container Image Checker:\n Error: The 'initContainer.image' field is missing. Please provide the 'initContainer.image' parameter." -}}
24+
{{- end }}
25+
{{- if not .deploymentName }}
26+
{{- $objectErrorMsgs = append $objectErrorMsgs "Deployment Name Checker:\n Error: The 'deploymentName' field is missing. Please provide the 'deploymentName' parameter." -}}
27+
{{- end }}
28+
{{- if not .containerSelector }}
29+
{{- $objectErrorMsgs = append $objectErrorMsgs "Container Selector Checker:\n Error: The 'containerSelector' field is missing. Please provide the 'containerSelector' parameter." -}}
30+
{{- end }}
31+
32+
{{- if .agentPoolCredentials.existingSecret }}
33+
{{- if and .agentPoolCredentials.apiKey .agentPoolCredentials.pinnedCertHash }}
34+
{{- $objectErrorMsgs = append $objectErrorMsgs "Secret Checker:\n Error: Both 'agentPoolCredentials.existingSecret' and 'agentPoolCredentials.apiKey' with 'agentPoolCredentials.pinnedCertHash' are defined. Please use only one of the following: 'existingSecret' or 'apiKey' with 'pinnedCertHash'." -}}
35+
{{- end }}
36+
{{- end }}
37+
38+
{{- if not .agentPoolCredentials.existingSecret }}
39+
{{- if not (and .agentPoolCredentials.apiKey .agentPoolCredentials.pinnedCertHash) }}
40+
{{- $objectErrorMsgs = append $objectErrorMsgs "Secret Checker:\n Error: neither 'agentPoolCredentials.existingSecret' nor 'agentPoolCredentials.apiKey' with 'agentPoolCredentials.pinnedCertHash' are defined. Please use one of the following: 'existingSecret' or 'apiKey' with 'pinnedCertHash'." -}}
41+
{{- end }}
42+
{{- end }}
43+
44+
{{- if $objectErrorMsgs }}
45+
{{- $objectErrors = merge $objectErrors (dict $objectName $objectErrorMsgs) -}}
46+
{{- end }}
47+
{{- end }}
48+
49+
{{- /* Prepare and print output */}}
50+
{{- if $objectErrors }}
51+
{{- $output := list -}}
52+
{{- range $name, $errors := $objectErrors }}
53+
{{- $output = append $output (printf "Errors for Java agent '%s':\n%s" $name (join "\n" $errors)) -}}
54+
{{- end }}
55+
{{- printf "\nCONFIGURATION CHECKS:\n%s" (join "\n\n" $output) | fail -}}
56+
{{- end -}}
57+
{{- end -}}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{{ range .Values.javaAgents }}
2+
---
3+
apiVersion: agents.lightrun.com/v1beta
4+
kind: LightrunJavaAgent
5+
metadata:
6+
name: {{ .name }}
7+
namespace: {{ .namespace }}
8+
spec:
9+
initContainer:
10+
image: {{ .initContainer.image }}
11+
sharedVolumeName: {{ .initContainer.sharedVolumeName | default "lightrun-agent-init" }}
12+
sharedVolumeMountPath: {{ .initContainer.sharedVolumeMountPath | default "/lightrun" }}
13+
deploymentName: {{ .deploymentName }}
14+
containerSelector: {{- toYaml .containerSelector | nindent 4 }}
15+
{{- if .agentPoolCredentials.existingSecret }}
16+
secretName: {{ .agentPoolCredentials.existingSecret }}
17+
{{- else }}
18+
secretName: {{ .name }}-secret
19+
{{- end }}
20+
serverHostname: {{ .serverHostname }}
21+
agentEnvVarName: {{ .agentEnvVarName | default "JAVA_TOOL_OPTIONS" }}
22+
{{- if .agentConfig }}
23+
agentConfig: {{ toYaml .agentConfig | nindent 4 }}
24+
{{- end }}
25+
{{- if .agentCliFlags }}
26+
agentCliFlags: {{ .agentCliFlags }}
27+
{{- end }}
28+
agentTags:
29+
{{- range .agentTags }}
30+
- {{. -}}
31+
{{- end }}
32+
{{- if .agentName }}
33+
agentName: {{ .agentName }}
34+
{{- end }}
35+
{{- end }}
36+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{{- /* run checkConfigs */}}
2+
{{ include "javaAgents.checkConfig" . }}

0 commit comments

Comments
 (0)