Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEVOPS-2134-add-lightrun-java-agents-helm-chart #31

Merged
merged 5 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
- lightrun-init-agent/*
- .github/**
- helm-chart/*
- charts/*
- grafana/*
- config/*
- examples/*
Expand Down Expand Up @@ -60,6 +61,11 @@ jobs:
yq -i '.version = "${{steps.release_tag.outputs.new_tag}}"' helm-chart/Chart.yaml
yq -i '.controllerManager.manager.image.tag = "${{steps.release_tag.outputs.new_tag}}"' helm-chart/values.yaml
helm package ./helm-chart -u -d ./helm-repo/
- name: Pack Lightrun Agents Helm chart
shell: bash
run: |
yq -i '.version = "${{steps.release_tag.outputs.new_tag}}"' charts/lightrun-agents/Chart.yaml
helm package ./charts/lightrun-agents -u -d ./helm-repo/

- name: Login to DockerHub
if: ${{ success() }}
Expand Down
23 changes: 23 additions & 0 deletions charts/lightrun-agents/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
18 changes: 18 additions & 0 deletions charts/lightrun-agents/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v2
name: lightrun-agents
description: A Helm chart for Kubernetes that deploy lightrun agents CRDs

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.0.1
186 changes: 186 additions & 0 deletions charts/lightrun-agents/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# Helm Chart for Deploying Lightrun Agents

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.

## Prerequisites

- Kubernetes 1.19+
- 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.

## Installation

### 1 - Add the repo to your Helm repository list

```shell
helm repo add lightrun-k8s-operator https://lightrun-platform.github.io/lightrun-k8s-operator

```

### 2 - Prepare values.yaml

The values.yaml file includes the following configurable parameters for each Java agent object:

| Parameter | Description | Default |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `javaAgents[].agentCliFlags` | [Command-line flags for the Lightrun Java Agent.](https://docs.lightrun.com/jvm/agent-configuration/#additional-command-line-flags). | Optional `""` (empty string) |
| `javaAgents[].agentConfig` | [Additional configuration for the Lightrun Java Agent.](https://docs.lightrun.com/jvm/agent-configuration/#agent-flags). | Optional `{}` (empty map) |
| `javaAgents[].agentEnvVarName` | Specifies the Java environment variable name used to add `--agentpath`. | Optional (if not provided, defaults to `"JAVA_TOOL_OPTIONS"`) |
| `javaAgents[].agentName` | Custom name to assign to the Lightrun Java Agent. | Optional (if not provided, defaults to pod name) |
| `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`) |
| `javaAgents[].agentPoolCredentials.apiKey` | Lightrun agent API key. | Required if `existingSecret` not set |
| `javaAgents[].agentPoolCredentials.pinnedCertHash` | 64 character sha256 certificate public key hash for pinning. | Required if `existingSecret` not set |
| `javaAgents[].agentTags` | [List of Lightrun Java Agent tags](https://docs.lightrun.com/jvm/tagging/#manage-lightrun-java-agent-tags). | Optional `[]` (empty list) |
| `javaAgents[].containerSelector` | Selector for containers within the deployment to inject the Lightrun Java Agent. | Required |
| `javaAgents[].deploymentName` | Name of the Kubernetes deployment to attach the Lightrun Java Agent. | Required |
| `javaAgents[].initContainer.image` | Image for the Lightrun Java Agent init container. | Required |
| `javaAgents[].initContainer.sharedVolumeMountPath` | Mount path for the shared volume in the init container. | Optional (if not provided, defaults to `"/lightrun"`" |
| `javaAgents[].initContainer.sharedVolumeName` | Name of the shared volume for the init container. | Optional (if not provided, defaults to `"lightrun-agent-init"`" |
| `javaAgents[].name` | Name of the Lightrun Java Agent custom resource. | Required |
| `javaAgents[].namespace` | Namespace of the Lightrun Java Agent custom resource. Must be in the same namespace as the workload | Required |
| `javaAgents[].serverHostname` | Hostname of the Lightrun server to connect the agent. | Required |

#### 2.1 - Set `initContainer.image`

Based on your workload's OS and architecture, you should select the appropriate DockerHub repository from the following options:

- [linux amd64](https://hub.docker.com/repository/docker/lightruncom/k8s-operator-init-java-agent-linux/general)
- [linux arm64](https://hub.docker.com/repository/docker/lightruncom/k8s-operator-init-java-agent-linux-arm64/general)
- [alpine amd64](https://hub.docker.com/repository/docker/lightruncom/k8s-operator-init-java-agent-alpine/general)
- [alpine arm64](https://hub.docker.com/repository/docker/lightruncom/k8s-operator-init-java-agent-alpine-arm64/general)

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.

For your convenience, here are some possible combinations of how the final image might look:

```text
Linux amd64 with the latest version -> lightruncom/k8s-operator-init-java-agent-linux:latest
Linux amd64 with a specific version -> lightruncom/k8s-operator-init-java-agent-linux:1.39.1-init.0
Linux arm64 with the latest version -> lightruncom/k8s-operator-init-java-agent-linux-arm64:latest
Linux arm64 with a specific version -> lightruncom/k8s-operator-init-java-agent-linux-arm64:1.39.1-init.0
Alpine amd64 with the latest version -> lightruncom/k8s-operator-init-java-agent-alpine:latest
Alpine amd64 with a specific version -> lightruncom/k8s-operator-init-java-agent-alpine:1.39.1-init.0
Alpine arm64 with the latest version -> lightruncom/k8s-operator-init-java-agent-alpine-arm64:latest
Alpine arm64 with a specific version -> lightruncom/k8s-operator-init-java-agent-alpine-arm64:1.39.1-init.0
```

#### 2.2 Install the chart

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.

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.

```bash
helm install <release-name> lightrun-k8s-operator/lightrun-agents -n <namespace> -f values.yaml
```

## Examples

### Basic

- The `my-service-1` does not use an `existingSecret` and instead the `agentPoolCredentials.apiKey` and `agentPoolCredentials.pinnedCertHash` are provided directly.

- The `my-service-2` uses an `existingSecret` named `my-existing-secret`

```yaml
javaAgents:
- name: 'my-service-1'
namespace: 'my-namespace-1'
deploymentName: "my-deployment-1"
containerSelector:
- my-container-1
serverHostname: 'lightrun.example.com'
initContainer:
image: "lightruncom/k8s-operator-init-java-agent-linux:latest"
agentPoolCredentials:
existingSecret: ""
apiKey: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
pinnedCertHash: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
agentTags:
- env-production
- service-my-server
- region-us_east_1
- provider-aws
- name: 'my-service-2'
namespace: 'my-namespace-2'
initContainer:
image: "lightruncom/k8s-operator-init-java-agent-linux:latest"
deploymentName: "my-deployment-2"
containerSelector:
- my-container-2
serverHostname: 'lightrun.example.com'
agentPoolCredentials:
existingSecret: "my-existing-secret"
apiKey: ""
pinnedCertHash: ""
agentTags:
- env-production
- service-my-other-server
- region-us_east_1
- provider-aws
```

### Full

- The `my-service-1` does not use an `existingSecret` and instead the `agentPoolCredentials.apiKey` and `agentPoolCredentials.pinnedCertHash` are provided directly.

- The `my-service-2` uses an `existingSecret` named `my-existing-secret`

```yaml
javaAgents:
- name: 'my-service-1'
namespace: 'my-namespace-1'
deploymentName: "my-deployment-1"
containerSelector:
- my-container-1
serverHostname: 'lightrun.example.com'
agentEnvVarName: '_JAVA_OPTIONS'
agentConfig:
max_log_cpu_cost: "2"
agentCliFlags: "--lightrun_extra_class_path=<PATH_TO_JAR>:<PATH_TO_JAR>,lightrun_init_wait_time_ms"
initContainer:
image: "lightruncom/k8s-operator-init-java-agent-linux:latest"
sharedVolumeName: 'my-shared-volume'
sharedVolumeMountPath: '/mypath'
agentPoolCredentials:
existingSecret: ""
apiKey: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
pinnedCertHash: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
agentTags:
- env-production
- service-my-server
- region-us_east_1
- provider-aws
- name: 'my-service-2'
namespace: 'my-namespace-2'
initContainer:
image: "lightruncom/k8s-operator-init-java-agent-linux:latest"
sharedVolumeName: 'my-shared-volume'
sharedVolumeMountPath: '/mypath'
deploymentName: "my-deployment-2"
containerSelector:
- my-container-2
serverHostname: 'lightrun.example.com'
agentEnvVarName: 'JAVA_OPTS'
agentConfig:
max_log_cpu_cost: "2"
agentCliFlags: "--lightrun_extra_class_path=<PATH_TO_JAR>:<PATH_TO_JAR>,lightrun_init_wait_time_ms"
agentPoolCredentials:
existingSecret: "my-existing-secret"
apiKey: ""
pinnedCertHash: ""
agentTags:
- env-production
- service-my-other-server
- region-us_east_1
- provider-aws
```

## Uninstallation

To uninstall the chart:

```bash
helm uninstall <release-name> -n <namespace>
```

This command removes all the Kubernetes components associated with the chart and deletes the release.
57 changes: 57 additions & 0 deletions charts/lightrun-agents/templates/_checkConfig.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{{/*
Compile all warnings into a single message, and call fail.
*/}}

{{- define "javaAgents.checkConfig" -}}
{{- $objectErrors := dict -}} {{/* Create a dictionary to store errors by agent name */}}

{{- range .Values.javaAgents }}
{{- $objectName := .name }}
{{- $objectErrorMsgs := list -}} {{/* Create a list to store errors for the current agent */}}

{{- /* Add error messages to the list if fields are missing */}}
{{- if not .namespace }}
{{- $objectErrorMsgs = append $objectErrorMsgs "Namespace Checker:\n Error: The 'namespace' field is missing. Please provide the 'namespace' parameter." -}}
{{- end }}
{{- if not .serverHostname }}
{{- $objectErrorMsgs = append $objectErrorMsgs "Server Hostname Checker:\n Error: The 'serverHostname' field is missing. Please provide the 'serverHostname' parameter." -}}
{{- end }}
{{- if not .name }}
{{- $objectErrorMsgs = append $objectErrorMsgs "Name Checker:\n Error: The 'name' field is missing. Please provide the 'name' parameter." -}}
{{- end }}
{{- if not .initContainer.image }}
{{- $objectErrorMsgs = append $objectErrorMsgs "Init Container Image Checker:\n Error: The 'initContainer.image' field is missing. Please provide the 'initContainer.image' parameter." -}}
{{- end }}
{{- if not .deploymentName }}
{{- $objectErrorMsgs = append $objectErrorMsgs "Deployment Name Checker:\n Error: The 'deploymentName' field is missing. Please provide the 'deploymentName' parameter." -}}
{{- end }}
{{- if not .containerSelector }}
{{- $objectErrorMsgs = append $objectErrorMsgs "Container Selector Checker:\n Error: The 'containerSelector' field is missing. Please provide the 'containerSelector' parameter." -}}
{{- end }}

{{- if .agentPoolCredentials.existingSecret }}
{{- if and .agentPoolCredentials.apiKey .agentPoolCredentials.pinnedCertHash }}
{{- $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'." -}}
{{- end }}
{{- end }}

{{- if not .agentPoolCredentials.existingSecret }}
{{- if not (and .agentPoolCredentials.apiKey .agentPoolCredentials.pinnedCertHash) }}
{{- $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'." -}}
{{- end }}
{{- end }}

{{- if $objectErrorMsgs }}
{{- $objectErrors = merge $objectErrors (dict $objectName $objectErrorMsgs) -}}
{{- end }}
{{- end }}

{{- /* Prepare and print output */}}
{{- if $objectErrors }}
{{- $output := list -}}
{{- range $name, $errors := $objectErrors }}
{{- $output = append $output (printf "Errors for Java agent '%s':\n%s" $name (join "\n" $errors)) -}}
{{- end }}
{{- printf "\nCONFIGURATION CHECKS:\n%s" (join "\n\n" $output) | fail -}}
{{- end -}}
{{- end -}}
36 changes: 36 additions & 0 deletions charts/lightrun-agents/templates/java-agent-cr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{{ range .Values.javaAgents }}
---
apiVersion: agents.lightrun.com/v1beta
kind: LightrunJavaAgent
metadata:
name: {{ .name }}
namespace: {{ .namespace }}
spec:
initContainer:
image: {{ .initContainer.image }}
sharedVolumeName: {{ .initContainer.sharedVolumeName | default "lightrun-agent-init" }}
sharedVolumeMountPath: {{ .initContainer.sharedVolumeMountPath | default "/lightrun" }}
deploymentName: {{ .deploymentName }}
containerSelector: {{- toYaml .containerSelector | nindent 4 }}
{{- if .agentPoolCredentials.existingSecret }}
secretName: {{ .agentPoolCredentials.existingSecret }}
{{- else }}
secretName: {{ .name }}-secret
{{- end }}
serverHostname: {{ .serverHostname }}
agentEnvVarName: {{ .agentEnvVarName | default "JAVA_TOOL_OPTIONS" }}
{{- if .agentConfig }}
agentConfig: {{ toYaml .agentConfig | nindent 4 }}
{{- end }}
{{- if .agentCliFlags }}
agentCliFlags: {{ .agentCliFlags }}
{{- end }}
agentTags:
{{- range .agentTags }}
- {{. -}}
{{- end }}
{{- if .agentName }}
agentName: {{ .agentName }}
{{- end }}
{{- end }}

2 changes: 2 additions & 0 deletions charts/lightrun-agents/templates/notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{{- /* run checkConfigs */}}
{{ include "javaAgents.checkConfig" . }}
Loading