From abe4c7dc5a5f384d5f847a0aa7bfeb12dca9ef90 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Wed, 10 Apr 2024 16:44:38 -0400 Subject: [PATCH] Add instrumentation to chart (#1114) * Add instrumentation to chart * bump version * feedback iteration * optional --- charts/opentelemetry-kube-stack/Chart.yaml | 4 +- .../templates/_helpers.tpl | 51 +++- .../templates/clusterrole.yaml | 2 +- .../templates/collector.yaml | 19 +- .../templates/instrumentation.yaml | 57 ++++ .../values.schema.json | 267 ++++++++++++++++++ charts/opentelemetry-kube-stack/values.yaml | 172 ++++++++++- 7 files changed, 545 insertions(+), 27 deletions(-) create mode 100644 charts/opentelemetry-kube-stack/templates/instrumentation.yaml diff --git a/charts/opentelemetry-kube-stack/Chart.yaml b/charts/opentelemetry-kube-stack/Chart.yaml index 3bdeceecb..6adc58e9e 100644 --- a/charts/opentelemetry-kube-stack/Chart.yaml +++ b/charts/opentelemetry-kube-stack/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: opentelemetry-kube-stack -version: 0.0.2 +version: 0.0.3 description: | OpenTelemetry Quickstart chart for Kubernetes. Installs an operator and collector for an easy way to get started with Kubernetes observability. @@ -13,4 +13,4 @@ maintainers: - name: dmitryax - name: TylerHelmuth icon: https://raw.githubusercontent.com/cncf/artwork/a718fa97fffec1b9fd14147682e9e3ac0c8817cb/projects/opentelemetry/icon/color/opentelemetry-icon-color.png -appVersion: 0.96.0 +appVersion: 0.97.0 diff --git a/charts/opentelemetry-kube-stack/templates/_helpers.tpl b/charts/opentelemetry-kube-stack/templates/_helpers.tpl index 6b2e10b5f..789e8aefa 100644 --- a/charts/opentelemetry-kube-stack/templates/_helpers.tpl +++ b/charts/opentelemetry-kube-stack/templates/_helpers.tpl @@ -29,10 +29,45 @@ Allow the release namespace to be overridden {{- end -}} {{- end -}} +{{/* +Print a map of key values in a YAML block. This is useful for labels and annotations. +*/}} +{{- define "opentelemetry-kube-stack.renderkv" -}} +{{- with . }} +{{- range $key, $value := . }} +{{- printf "%s: %s" $key $value }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Render a deduped list of environment variables and 'extraEnvs' +*/}} +{{- define "opentelemetry-kube-stack.renderenvs" -}} +{{- $envMap := dict }} +{{- range $item := .extraEnvs }} +{{- $_ := set $envMap $item.name $item.value }} +{{- end }} +{{- range $item := .env }} +{{- $_ := set $envMap $item.name $item.value }} +{{- end }} +{{- range $key, $value := $envMap }} +- name: {{ $key }} + value: {{ $value }} +{{- end }} +{{- end }} + +{{/* +Create the name of the instrumentation to use +*/}} +{{- define "opentelemetry-kube-stack.instrumentation" -}} +{{- default .Release.Name .Values.instrumentation.name }} +{{- end }} + {{/* Create chart name and version as used by the chart label. */}} -{{- define "opentelemetry-collector.chart" -}} +{{- define "opentelemetry-kube-stack.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} @@ -40,7 +75,7 @@ Create chart name and version as used by the chart label. Common labels */}} {{- define "opentelemetry-kube-stack.labels" -}} -helm.sh/chart: {{ include "opentelemetry-collector.chart" . }} +helm.sh/chart: {{ include "opentelemetry-kube-stack.chart" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} @@ -50,7 +85,7 @@ app.kubernetes.io/managed-by: {{ .Release.Service }} {{/* Expand the name of the chart. */}} -{{- define "opentelemetry-collector.name" -}} +{{- define "opentelemetry-kube-stack.collectorName" -}} {{- default .Chart.Name .collector.name | trunc 63 | trimSuffix "-" }} {{- end }} @@ -59,7 +94,7 @@ Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} -{{- define "opentelemetry-collector.fullname" -}} +{{- define "opentelemetry-kube-stack.collectorFullname" -}} {{- if .fullnameOverride }} {{- .fullnameOverride | trunc 63 | trimSuffix "-" }} {{- else }} @@ -75,15 +110,15 @@ If release name contains chart name it will be used as a full name. {{/* Create the name of the clusterRole to use */}} -{{- define "opentelemetry-collector.clusterRoleName" -}} +{{- define "opentelemetry-kube-stack.clusterRoleName" -}} {{- default (printf "%s-collector" .Release.Name) .Values.clusterRole.name }} {{- end }} {{/* Create the name of the clusterRoleBinding to use */}} -{{- define "opentelemetry-collector.clusterRoleBindingName" -}} -{{- default (include "opentelemetry-collector.fullname" .) .Values.clusterRole.clusterRoleBinding.name }} +{{- define "opentelemetry-kube-stack.clusterRoleBindingName" -}} +{{- default (include "opentelemetry-kube-stack.fullname" .) .Values.clusterRole.clusterRoleBinding.name }} {{- end }} {{/* @@ -93,7 +128,7 @@ This allows a user to supply a scrape_configs_file. This file is templated and l If a user has already supplied a prometheus receiver config, the file's config is appended. Finally, the config is written as YAML. */}} -{{- define "opentelemetry-collector.config" -}} +{{- define "opentelemetry-kube-stack.config" -}} {{- if .collector.scrape_configs_file }} {{- $loaded_file := (.Files.Get .collector.scrape_configs_file) }} {{- $loaded_config := (fromYamlArray (tpl $loaded_file .)) }} diff --git a/charts/opentelemetry-kube-stack/templates/clusterrole.yaml b/charts/opentelemetry-kube-stack/templates/clusterrole.yaml index 418599510..89b3de3be 100644 --- a/charts/opentelemetry-kube-stack/templates/clusterrole.yaml +++ b/charts/opentelemetry-kube-stack/templates/clusterrole.yaml @@ -3,7 +3,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: {{ include "opentelemetry-collector.clusterRoleName" . }} + name: {{ include "opentelemetry-kube-stack.clusterRoleName" . }} rules: - apiGroups: [""] resources: diff --git a/charts/opentelemetry-kube-stack/templates/collector.yaml b/charts/opentelemetry-kube-stack/templates/collector.yaml index 8958d3a8b..5e10394e7 100644 --- a/charts/opentelemetry-kube-stack/templates/collector.yaml +++ b/charts/opentelemetry-kube-stack/templates/collector.yaml @@ -2,7 +2,7 @@ {{- if $collector.enabled -}} {{- $collector := (mergeOverwrite (deepCopy $.Values.defaultCRConfig) $collector) }} {{- $merged := (dict "Template" $.Template "Files" $.Files "Chart" $.Chart "clusterRole" $.Values.clusterRole "collector" $collector "Release" $.Release "fullnameOverride" $.Values.fullnameOverride) }} -{{- $fullname := (include "opentelemetry-collector.fullname" $merged) }} +{{- $fullname := (include "opentelemetry-kube-stack.collectorFullname" $merged) }} --- apiVersion: opentelemetry.io/v1alpha1 kind: OpenTelemetryCollector @@ -11,16 +11,10 @@ metadata: namespace: {{ include "opentelemetry-kube-stack.namespace" $ }} labels: {{- include "opentelemetry-kube-stack.labels" $ | nindent 4 }} - {{- with $collector.labels }} - {{- range $key, $value := . }} - {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} - {{- end }} - {{- end }} + {{- include "opentelemetry-kube-stack.renderkv" $collector.labels | nindent 4 }} {{- with $collector.annotations }} annotations: - {{- range $key, $value := . }} - {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} - {{- end }} + {{- include "opentelemetry-kube-stack.renderkv" . | nindent 4 }} {{- end }} spec: managementState: {{ $collector.managementState }} @@ -117,9 +111,6 @@ spec: {{- toYaml . | nindent 4 }} {{- end }} env: - {{- with $.Values.extraEnvs }} - {{- toYaml . | nindent 2 }} - {{- end }} - name: OTEL_K8S_NODE_NAME valueFrom: fieldRef: @@ -147,9 +138,7 @@ spec: - name: OTEL_RESOURCE_ATTRIBUTES value: "k8s.cluster.name={{ $.Values.clusterName }}" {{- end }} - {{- with $collector.env }} - {{- toYaml . | nindent 2 }} - {{- end }} + {{- include "opentelemetry-kube-stack.renderenvs" (dict "extraEnvs" $.Values.extraEnvs "env" $collector.env) | nindent 4 }} {{- with $collector.envFrom }} envFrom: {{- toYaml . | nindent 4 }} diff --git a/charts/opentelemetry-kube-stack/templates/instrumentation.yaml b/charts/opentelemetry-kube-stack/templates/instrumentation.yaml new file mode 100644 index 000000000..cd3adbc24 --- /dev/null +++ b/charts/opentelemetry-kube-stack/templates/instrumentation.yaml @@ -0,0 +1,57 @@ +{{- if .Values.instrumentation.enabled }} +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: Instrumentation +metadata: + name: {{ include "opentelemetry-kube-stack.instrumentation" . }} + labels: + {{- include "opentelemetry-kube-stack.labels" $ | nindent 4 }} + {{- include "opentelemetry-kube-stack.renderkv" .Values.instrumentation.labels | nindent 4 }} + {{- with .Values.instrumentation.annotations }} + annotations: + {{- include "opentelemetry-kube-stack.renderkv" . | nindent 4 }} + {{- end }} +spec: + exporter: + endpoint: {{ .Values.instrumentation.exporter.endpoint }} + propagators: + {{- toYaml .Values.instrumentation.propagators | nindent 4 }} + {{- with .Values.instrumentation.sampler }} + sampler: + {{- toYaml . | nindent 4 }} + {{- end }} + env: + {{- include "opentelemetry-kube-stack.renderenvs" (dict "extraEnvs" $.Values.extraEnvs "env" .Values.instrumentation.env) | nindent 4 }} + {{- with .Values.instrumentation.resource }} + resource: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.instrumentation.java }} + java: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.nodejs }} + nodejs: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.python }} + python: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.dotnet }} + dotnet: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.go }} + go: + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.instrumentation.apacheHttpd }} + apacheHtpd: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.instrumentation.nginx }} + nginx: + {{- toYaml . | nindent 4}} + {{- end }} +{{- end }} diff --git a/charts/opentelemetry-kube-stack/values.schema.json b/charts/opentelemetry-kube-stack/values.schema.json index 3cb9411f3..7bc7c1ad4 100644 --- a/charts/opentelemetry-kube-stack/values.schema.json +++ b/charts/opentelemetry-kube-stack/values.schema.json @@ -2736,6 +2736,270 @@ }, "additionalProperties": false, "type": "object" + }, + "InstrumentationSpec": { + "properties": { + "name": { + "type": "string" + }, + "labels": { + "type": "object" + }, + "annotations": { + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "exporter": { + "$ref": "#/$defs/Exporter" + }, + "resource": { + "$ref": "#/$defs/Resource" + }, + "propagators": { + "items": { + "type": "string" + }, + "type": "array" + }, + "sampler": { + "$ref": "#/$defs/Sampler" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "java": { + "$ref": "#/$defs/Java" + }, + "nodejs": { + "$ref": "#/$defs/NodeJS" + }, + "python": { + "$ref": "#/$defs/Python" + }, + "dotnet": { + "$ref": "#/$defs/DotNet" + }, + "go": { + "$ref": "#/$defs/Go" + }, + "apacheHttpd": { + "$ref": "#/$defs/ApacheHttpd" + }, + "nginx": { + "$ref": "#/$defs/Nginx" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Java": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resources": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Nginx": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "attrs": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "configFile": { + "type": "string" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "NodeJS": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Python": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Resource": { + "properties": { + "resourceAttributes": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "addK8sUIDAttributes": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Sampler": { + "properties": { + "type": { + "type": "string" + }, + "argument": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "ApacheHttpd": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "attrs": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "version": { + "type": "string" + }, + "configPath": { + "type": "string" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "DotNet": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Exporter": { + "properties": { + "endpoint": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Go": { + "properties": { + "image": { + "type": "string" + }, + "volumeLimitSize": { + "type": "string" + }, + "env": { + "items": { + "$ref": "#/$defs/EnvVar" + }, + "type": "array" + }, + "resourceRequirements": { + "$ref": "#/$defs/ResourceRequirements" + } + }, + "additionalProperties": false, + "type": "object" } }, "properties": { @@ -2781,6 +3045,9 @@ }, "required": ["enabled"] }, + "instrumentation": { + "$ref": "#/$defs/InstrumentationSpec" + }, "extraEnvs": { "type": "array", "items": { diff --git a/charts/opentelemetry-kube-stack/values.yaml b/charts/opentelemetry-kube-stack/values.yaml index 3faf2a279..847bf45fa 100644 --- a/charts/opentelemetry-kube-stack/values.yaml +++ b/charts/opentelemetry-kube-stack/values.yaml @@ -15,7 +15,7 @@ defaultCRConfig: enabled: false # Name of the collector - name: "demo" + name: "collector" # Annotations for the collector annotations: {} @@ -341,3 +341,173 @@ clusterRole: # Rules for the cluster role rules: [] + +# Instrumentation configuration +instrumentation: + # Whether instrumentation is enabled or not + enabled: false + labels: {} + annotations: {} + + # Exporter configuration + exporter: + # This is the default collector's service + # Upon creation of a tracing collector, edit this endpoint. + endpoint: http://collector-collector:4317 + + # Resource configuration + resource: + resourceAttributes: {} + # environment: dev + addK8sUIDAttributes: true + + # Propagators configuration + propagators: + - tracecontext + - baggage + - b3 + - b3multi + - jaeger + - xray + - ottrace + + # Sampler configuration + sampler: {} + # type: parentbased_always_on + # argument: "0.25" + + # Environment variables for instrumentation + env: [] + # - name: ENV_VAR1 + # value: value1 + # - name: ENV_VAR2 + # value: value2 + + # Java agent configuration + java: {} + # image: myregistry/java-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: JAVA_ENV_VAR + # value: java_value + # resources: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # NodeJS agent configuration + nodejs: {} + # image: myregistry/nodejs-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: NODEJS_ENV_VAR + # value: nodejs_value + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # Python agent configuration + python: {} + # image: myregistry/python-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: PYTHON_ENV_VAR + # value: python_value + # # Required if endpoint is set to 4317. + # # Python autoinstrumentation uses http/proto by default + # # so data must be sent to 4318 instead of 4317. + # - name: OTEL_EXPORTER_OTLP_ENDPOINT + # value: http://otel-collector:4318 + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # .NET agent configuration + dotnet: {} + # image: myregistry/dotnet-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: DOTNET_ENV_VAR + # value: dotnet_value + # # Required if endpoint is set to 4317. + # # Dotnet autoinstrumentation uses http/proto by default + # # See https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/888e2cd216c77d12e56b54ee91dafbc4e7452a52/docs/config.md#otlp + # - name: OTEL_EXPORTER_OTLP_ENDPOINT + # value: http://otel-collector:4318 + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # Go agent configuration + go: {} + # image: myregistry/go-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: GO_ENV_VAR + # value: go_value + # # Required if endpoint is set to 4317. + # # Dotnet autoinstrumentation uses http/proto by default + # # See https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/888e2cd216c77d12e56b54ee91dafbc4e7452a52/docs/config.md#otlp + # - name: OTEL_EXPORTER_OTLP_ENDPOINT + # value: http://otel-collector:4318 + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # Apache HTTPd agent configuration + apacheHttpd: {} + # image: myregistry/apache-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: APACHE_ENV_VAR + # value: apache_value + # attrs: + # - name: ATTRIBUTE_VAR + # value: attribute_value + # version: "2.4" + # configPath: "/usr/local/apache2/conf" + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m" + + # NGINX agent configuration + nginx: {} + # image: myregistry/nginx-agent:latest + # volumeLimitSize: 200Mi + # env: + # - name: NGINX_ENV_VAR + # value: nginx_value + # attrs: + # - name: ATTRIBUTE_VAR + # value: attribute_value + # configFile: "/etc/nginx/nginx.conf" + # resourceRequirements: + # requests: + # memory: "64Mi" + # cpu: "250m" + # limits: + # memory: "128Mi" + # cpu: "500m"