From fec32f473c2c280a2885d988f28b9afdef146c5b Mon Sep 17 00:00:00 2001 From: Robbie Lankford Date: Tue, 4 Feb 2025 19:00:36 -0800 Subject: [PATCH 1/6] add application-observability platform test Signed-off-by: Robbie Lankford --- .../application-observability/.envrc | 5 + .../application-observability/.gitignore | 2 + .../application-observability/Makefile | 30 + .../application-observability/README.md | 0 .../deployments/otel-demo-manifest.yaml | 1002 +++++++++++++++++ .../deployments/query-test.yaml | 39 + .../application-observability/values.yaml | 73 ++ 7 files changed, 1151 insertions(+) create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.envrc create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.gitignore create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/Makefile create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/README.md create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/otel-demo-manifest.yaml create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/query-test.yaml create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/values.yaml diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.envrc b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.envrc new file mode 100644 index 000000000..0c649be63 --- /dev/null +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.envrc @@ -0,0 +1,5 @@ +export GRAFANA_CLOUD_OTLP_USERNAME=$(op --account grafana.1password.com read "op://Kubernetes Monitoring/helmchart OTLP/username") +export GRAFANA_CLOUD_METRICS_USERNAME=$(op --account grafana.1password.com read "op://Kubernetes Monitoring/helmchart Prometheus/username") +export GRAFANA_CLOUD_LOGS_USERNAME=$(op --account grafana.1password.com read "op://Kubernetes Monitoring/helmchart Loki/username") +export GRAFANA_CLOUD_RW_POLICY_TOKEN=$(op --account grafana.1password.com read "op://Kubernetes Monitoring/helmchart Loki/password") +export RANDOM_NUMBER=$(shuf -i 100000-999999 -n 1) \ No newline at end of file diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.gitignore b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.gitignore new file mode 100644 index 000000000..a9f8e80bd --- /dev/null +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.gitignore @@ -0,0 +1,2 @@ +deployments/grafana-cloud-credentials.yaml +deployments/test-variables.yaml diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/Makefile b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/Makefile new file mode 100644 index 000000000..5c92eb517 --- /dev/null +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/Makefile @@ -0,0 +1,30 @@ +all: deployments/test-variables.yaml deployments/grafana-cloud-credentials.yaml +clean: + rm -f deployments/test-variables.yaml deployments/grafana-cloud-credentials.yaml + +deployments/test-variables.yaml: + echo "---" > $@ + kubectl create configmap test-variables \ + --from-literal=CLUSTER="$(shell yq eval '.cluster.name' values.yaml)-$$RANDOM_NUMBER" \ + --from-literal=RANDOM_NUMBER="$$RANDOM_NUMBER" \ + -o yaml --dry-run=client >> $@ + echo "---" >> $@ + kubectl create configmap test-variables --namespace=otel-demo \ + --from-literal=CLUSTER="$(shell yq eval '.cluster.name' values.yaml)-$$RANDOM_NUMBER" \ + --from-literal=RANDOM_NUMBER="$$RANDOM_NUMBER" \ + -o yaml --dry-run=client >> $@ + +deployments/grafana-cloud-credentials.yaml: + echo "---" > $@ + echo "# yamllint disable rule:line-length" >> $@ + kubectl create secret generic grafana-cloud-credentials \ + --from-literal=OTLP_GATEWAY_USER="$$GRAFANA_CLOUD_OTLP_USERNAME" \ + --from-literal=OTLP_GATEWAY_PASS="$$GRAFANA_CLOUD_RW_POLICY_TOKEN" \ + --from-literal=LOKI_USER="$$GRAFANA_CLOUD_LOGS_USERNAME" \ + --from-literal=LOKI_PASS="$$GRAFANA_CLOUD_RW_POLICY_TOKEN" \ + --from-literal=PROMETHEUS_USER="$$GRAFANA_CLOUD_METRICS_USERNAME" \ + --from-literal=PROMETHEUS_PASS="$$GRAFANA_CLOUD_RW_POLICY_TOKEN" \ + -o yaml --dry-run=client >> $@ + +run-test: + ../../../../../../scripts/run-cluster-test.sh . diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/README.md b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/otel-demo-manifest.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/otel-demo-manifest.yaml new file mode 100644 index 000000000..2daabccd4 --- /dev/null +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/otel-demo-manifest.yaml @@ -0,0 +1,1002 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: open-telemetry + namespace: default +spec: + interval: 1h + url: https://open-telemetry.github.io/opentelemetry-helm-charts +--- +apiVersion: v1 +kind: Namespace +metadata: + name: otel-demo +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: otel-demo + namespace: otel-demo +spec: + interval: 10m + timeout: 10m + chart: + spec: + chart: opentelemetry-demo + version: 0.33.8 + sourceRef: + kind: HelmRepository + name: open-telemetry + namespace: default + interval: 10m + values: + # yaml-language-server: $schema=./values.schema.json + default: + # List of environment variables applied to all components + env: + - name: RANDOM_NUMBER + valueFrom: + configMapKeyRef: + name: test-variables + key: RANDOM_NUMBER + - name: CLUSTER + valueFrom: + configMapKeyRef: + name: test-variables + key: CLUSTER + - name: OTEL_SERVICE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: "metadata.labels['app.kubernetes.io/component']" + - name: OTEL_COLLECTOR_NAME + value: 'k8smon-alloy-receiver.default' + - name: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE + value: cumulative + - name: OTEL_RESOURCE_ATTRIBUTES + value: 'service.name=$(OTEL_SERVICE_NAME),service.namespace=opentelemetry-demo,service.version={{ .Chart.AppVersion }},k8s.cluster.name=$(CLUSTER)' + # Allows overriding and additions to .Values.default.env + envOverrides: [ ] + # - name: OTEL_K8S_NODE_NAME + # value: "someConstantValue" + image: + repository: ghcr.io/open-telemetry/demo + # Overrides the image tag whose default is the chart appVersion. + # The service's name will be applied to the end of this value. + tag: "" + pullPolicy: IfNotPresent + pullSecrets: [ ] + # Default # of replicas for all components + replicas: 1 + # default revisionHistoryLimit for all components (number of old ReplicaSets to retain) + revisionHistoryLimit: 10 + # Default schedulingRules for all components + schedulingRules: + nodeSelector: { } + affinity: { } + tolerations: [ ] + # Default securityContext for all components + securityContext: { } + + serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: { } + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + + components: + ## Demo Components are named objects (services) with several properties + # demoService: + ## Enable the component (service) + # enabled: true + # useDefault: + ## Use default environment variables + # env: true + ## Override Image repository and Tag. Tag will use appVersion as default. + ## Component's name will be applied to end of this value. + # imageOverride: {} + ## Optional service definitions to apply + # service: + ## Service Type to use for this component. Default is ClusterIP. + # type: ClusterIP + ## Service Port to use to expose this component. Default is nil + # port: 8080 + ## Service Node Port to use to expose this component on a NodePort service. Default is nil + # nodePort: 30080 + ## Service Annotations to add to this component + # annotations: {} + ## Additional service ports to use to expose this component + # ports: + # - name: extraServicePort + # value: 8081 + ## Environment variables to add to the component's pod + # env: + ## Environment variables that upsert (append + merge) into the `env` specification for this component. + ## A variable named OTEL_RESOURCE_ATTRIBUTES_EXTRA will have its value appended to the OTEL_RESOURCE_ATTRIBUTES value. + # envOverrides: + ## Pod Scheduling rules for nodeSelector, affinity, or tolerations. + # schedulingRules: + # nodeSelector: {} + # affinity: {} + # tolerations: [] + ## Pod Annotations to add to this component + # podAnnotations: {} + ## Resources for this component + # resources: {} + ## Container security context for setting user ID (UID), group ID (GID) and other security policies + # securityContext: + ## Ingresses rules to add for the to the component + # ingress: + ## Enable the creation of Ingress rules. Default is false + # enabled: false + ## Annotations to add to the ingress rule + # annotations: {} + ## Which Ingress class (controller) to use. Default is unspecified. + # ingressClassName: nginx + ## Hosts definitions for the Ingress rule + # hosts: + # - host: demo.example.com + ## Each host can have multiple paths/routes + # paths: + # - path: / + # pathType: Prefix + # port: 8080 + ## Optional TLS specifications for the Ingress rule + # tls: + # - secretName: demo-tls + # hosts: + # - demo.example.com + ## Additional ingresses - only created if ingress.enabled is true + ## Useful for when differently annotated ingress services are required + ## Each additional ingress needs key "name" set to something unique + # additionalIngresses: [] + # - name: extra-demo-ingress + # ingressClassName: nginx + # annotations: {} + # hosts: + # - host: demo.example.com + # paths: + # - path: / + # pathType: Prefix + # port: 8080 + # tls: + # - secretName: demo-tls + # hosts: + # - demo.example.com + ## Command to use in the container spec, in case you don't want to go with the default command from the image. + # command: [] + ## Configuration to for this component; will create a Volume, and Mount backed by an optionally created ConfigMap. + ## The name, mountPath are required, and one of existingConfigMap or data is required. + ## If an existing ConfigMap is not provided, the contents under data will be used for the created ConfigMap. + # mountedConfigMaps: [] + # - name: my-config + # mountPath: /etc/config + # subPath: + # existingConfigMap: my-configmap + # data: + # my-config.yaml: | + # key: value + # # Kubernetes container health check options + # livenessProbe: {} + # # Optional init container to run before the pod starts. + # initContainers: + # - name: + # image: + # command: [list of commands for the init container to run] + # # Replicas for the component + # replicas: 1 + # # Number of old ReplicaSets to retain + # revisionHistoryLimit: 10 + # # Optional pod security context for setting user ID (UID), group ID (GID) and other security policies + # # This will be applied at pod level, can be applied globally for all pods: .Values.default.podSecurityContext + # # Or it can be applied to a specific component: .Values.components..podSecurityContext + # podSecurityContext: + # runAsGroup: 65534 + # runAsNonRoot: true + # runAsUser: 65534 + + accountingService: + enabled: true + useDefault: + env: true + env: + - name: KAFKA_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-kafka:9092' + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4318 + resources: + limits: + memory: 120Mi + initContainers: + - name: wait-for-kafka + image: busybox:latest + command: [ 'sh', '-c', 'until nc -z -v -w30 {{ include "otel-demo.name" . }}-kafka 9092; do echo waiting for kafka; sleep 2; done;' ] + + adService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: AD_SERVICE_PORT + value: "8080" + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4318 + - name: OTEL_LOGS_EXPORTER + value: otlp + resources: + limits: + memory: 300Mi + + cartService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: CART_SERVICE_PORT + value: "8080" + - name: ASPNETCORE_URLS + value: http://*:$(CART_SERVICE_PORT) + - name: VALKEY_ADDR + value: '{{ include "otel-demo.name" . }}-valkey:6379' + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + resources: + limits: + memory: 160Mi + initContainers: + - name: wait-for-valkey + image: busybox:latest + command: [ 'sh', '-c', 'until nc -z -v -w30 {{ include "otel-demo.name" . }}-valkey 6379; do echo waiting for valkey; sleep 2; done;' ] + + checkoutService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: CHECKOUT_SERVICE_PORT + value: "8080" + - name: CART_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-cartservice:8080' + - name: CURRENCY_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-currencyservice:8080' + - name: EMAIL_SERVICE_ADDR + value: 'http://{{ include "otel-demo.name" . }}-emailservice:8080' + - name: PAYMENT_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-paymentservice:8080' + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-productcatalogservice:8080' + - name: SHIPPING_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-shippingservice:8080' + - name: KAFKA_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-kafka:9092' + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + resources: + limits: + memory: 20Mi + initContainers: + - name: wait-for-kafka + image: busybox:latest + command: [ 'sh', '-c', 'until nc -z -v -w30 {{ include "otel-demo.name" . }}-kafka 9092; do echo waiting for kafka; sleep 2; done;' ] + + currencyService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: CURRENCY_SERVICE_PORT + value: "8080" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + - name: VERSION + value: "{{ .Chart.AppVersion }}" + resources: + limits: + memory: 20Mi + + emailService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: EMAIL_SERVICE_PORT + value: "8080" + - name: APP_ENV + value: production + - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4318/v1/traces + resources: + limits: + memory: 100Mi + + frauddetectionService: + enabled: true + useDefault: + env: true + env: + - name: KAFKA_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-kafka:9092' + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4318 + resources: + limits: + memory: 300Mi + initContainers: + - name: wait-for-kafka + image: busybox:latest + command: [ 'sh', '-c', 'until nc -z -v -w30 {{ include "otel-demo.name" . }}-kafka 9092; do echo waiting for kafka; sleep 2; done;' ] + + frontend: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: FRONTEND_PORT + value: "8080" + - name: FRONTEND_ADDR + value: :8080 + - name: AD_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-adservice:8080' + - name: CART_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-cartservice:8080' + - name: CHECKOUT_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-checkoutservice:8080' + - name: CURRENCY_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-currencyservice:8080' + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-productcatalogservice:8080' + - name: RECOMMENDATION_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-recommendationservice:8080' + - name: SHIPPING_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-shippingservice:8080' + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_COLLECTOR_HOST + value: $(OTEL_COLLECTOR_NAME) + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + - name: WEB_OTEL_SERVICE_NAME + value: frontend-web + - name: PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT + value: http://localhost:8080/otlp-http/v1/traces # This expects users to use `kubectl port-forward ...` + resources: + limits: + memory: 250Mi + securityContext: + runAsUser: 1001 # nextjs + runAsGroup: 1001 + runAsNonRoot: true + + frontendProxy: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: ENVOY_PORT + value: "8080" + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: FLAGD_UI_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_UI_PORT + value: "4000" + - name: FRONTEND_HOST + value: '{{ include "otel-demo.name" . }}-frontend' + - name: FRONTEND_PORT + value: "8080" + - name: GRAFANA_SERVICE_HOST + value: '{{ include "otel-demo.name" . }}-grafana' + - name: GRAFANA_SERVICE_PORT + value: "80" + - name: IMAGE_PROVIDER_HOST + value: '{{ include "otel-demo.name" . }}-imageprovider' + - name: IMAGE_PROVIDER_PORT + value: "8081" + - name: JAEGER_SERVICE_HOST + value: '{{ include "otel-demo.name" . }}-jaeger-query' + - name: JAEGER_SERVICE_PORT + value: "16686" + - name: LOCUST_WEB_HOST + value: '{{ include "otel-demo.name" . }}-loadgenerator' + - name: LOCUST_WEB_PORT + value: "8089" + - name: OTEL_COLLECTOR_HOST + value: $(OTEL_COLLECTOR_NAME) + - name: OTEL_COLLECTOR_PORT_GRPC + value: "4317" + - name: OTEL_COLLECTOR_PORT_HTTP + value: "4318" + resources: + limits: + memory: 50Mi + securityContext: + runAsUser: 101 # envoy + runAsGroup: 101 + runAsNonRoot: true + + imageprovider: + enabled: true + useDefault: + env: true + service: + port: 8081 + env: + - name: IMAGE_PROVIDER_PORT + value: "8081" + - name: OTEL_COLLECTOR_PORT_GRPC + value: "4317" + - name: OTEL_COLLECTOR_HOST + value: $(OTEL_COLLECTOR_NAME) + resources: + limits: + memory: 50Mi + + loadgenerator: + enabled: true + useDefault: + env: true + service: + port: 8089 + env: + - name: LOCUST_WEB_PORT + value: "8089" + - name: LOCUST_USERS + value: "10" + - name: LOCUST_SPAWN_RATE + value: "1" + - name: LOCUST_HOST + value: 'http://{{ include "otel-demo.name" . }}-frontendproxy:8080' + - name: LOCUST_HEADLESS + value: "false" + - name: LOCUST_AUTOSTART + value: "true" + - name: LOCUST_BROWSER_TRAFFIC_ENABLED + value: "true" + - name: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION + value: python + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + resources: + limits: + memory: 1500Mi + + paymentService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: PAYMENT_SERVICE_PORT + value: "8080" + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + resources: + limits: + memory: 120Mi + securityContext: + runAsUser: 1000 # node + runAsGroup: 1000 + runAsNonRoot: true + + productCatalogService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: PRODUCT_CATALOG_SERVICE_PORT + value: "8080" + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + resources: + limits: + memory: 20Mi + + quoteService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: QUOTE_SERVICE_PORT + value: "8080" + - name: OTEL_PHP_AUTOLOAD_ENABLED + value: "true" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4318 + resources: + limits: + memory: 40Mi + securityContext: + runAsUser: 33 # www-data + runAsGroup: 33 + runAsNonRoot: true + + recommendationService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: RECOMMENDATION_SERVICE_PORT + value: "8080" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: '{{ include "otel-demo.name" . }}-productcatalogservice:8080' + - name: OTEL_PYTHON_LOG_CORRELATION + value: "true" + - name: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION + value: python + - name: FLAGD_HOST + value: '{{ include "otel-demo.name" . }}-flagd' + - name: FLAGD_PORT + value: "8013" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + resources: + limits: + memory: 500Mi # This is high to enable supporting the recommendationCache feature flag use case + + shippingService: + enabled: true + useDefault: + env: true + service: + port: 8080 + env: + - name: SHIPPING_SERVICE_PORT + value: "8080" + - name: QUOTE_SERVICE_ADDR + value: 'http://{{ include "otel-demo.name" . }}-quoteservice:8080' + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4317 + resources: + limits: + memory: 20Mi + + flagd: + enabled: true + imageOverride: + repository: "ghcr.io/open-feature/flagd" + tag: "v0.11.1" + useDefault: + env: true + replicas: 1 + service: + port: 8013 + env: + - name: FLAGD_METRICS_EXPORTER + value: otel + - name: FLAGD_OTEL_COLLECTOR_URI + value: $(OTEL_COLLECTOR_NAME):4317 + resources: + limits: + memory: 75Mi + command: + - "/flagd-build" + - "start" + - "--uri" + - "file:./etc/flagd/demo.flagd.json" + mountedEmptyDirs: + - name: config-rw + mountPath: /etc/flagd + # flgad-ui as a sidecar container in the same pod so the flag json file can be shared + sidecarContainers: + - name: flagdui + useDefault: + env: true + service: + port: 4000 + env: + - name: FLAGD_METRICS_EXPORTER + value: otel + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4318 + resources: + limits: + memory: 75Mi + volumeMounts: + - name: config-rw + mountPath: /app/data + initContainers: + - name: init-config + image: busybox + command: [ 'sh', '-c', 'cp /config-ro/demo.flagd.json /config-rw/demo.flagd.json && cat /config-rw/demo.flagd.json' ] + volumeMounts: + - mountPath: /config-ro + name: config-ro + - mountPath: /config-rw + name: config-rw + additionalVolumes: + - name: config-ro + configMap: + name: '{{ include "otel-demo.name" . }}-flagd-config' + + kafka: + enabled: true + useDefault: + env: true + replicas: 1 + ports: + - name: plaintext + value: 9092 + - name: controller + value: 9093 + env: + - name: KAFKA_ADVERTISED_LISTENERS + value: 'PLAINTEXT://{{ include "otel-demo.name" . }}-kafka:9092' + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://$(OTEL_COLLECTOR_NAME):4318 + - name: KAFKA_HEAP_OPTS + value: "-Xmx400M -Xms400M" + resources: + limits: + memory: 600Mi + securityContext: + runAsUser: 1000 # appuser + runAsGroup: 1000 + runAsNonRoot: true + + valkey: + enabled: true + useDefault: + env: true + imageOverride: + repository: "valkey/valkey" + tag: "7.2-alpine" + replicas: 1 + ports: + - name: valkey + value: 6379 + resources: + limits: + memory: 20Mi + securityContext: + runAsUser: 999 # valkey + runAsGroup: 1000 + runAsNonRoot: true + + opentelemetry-collector: + image: + repository: "otel/opentelemetry-collector-contrib" + enabled: false + nameOverride: otelcol + mode: deployment + presets: + kubernetesAttributes: + enabled: true + resources: + limits: + memory: 200Mi + service: + type: ClusterIP + ports: + metrics: + enabled: true + prometheus: + enabled: true + containerPort: 9464 + servicePort: 9464 + protocol: TCP + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9464" + opentelemetry_community_demo: "true" + config: + receivers: + otlp: + protocols: + http: + # Since this collector needs to receive data from the web, enable cors for all origins + # `allowed_origins` can be refined for your deployment domain + cors: + allowed_origins: + - "http://*" + - "https://*" + httpcheck/frontendproxy: + targets: + - endpoint: 'http://{{ include "otel-demo.name" . }}-frontendproxy:8080' + redis: + endpoint: "valkey-cart:6379" + collection_interval: 10s + + exporters: + ## Create an exporter to Jaeger using the standard `otlp` export format + otlp: + endpoint: '{{ include "otel-demo.name" . }}-jaeger-collector:4317' + tls: + insecure: true + # Create an exporter to Prometheus (metrics) + otlphttp/prometheus: + endpoint: 'http://{{ include "otel-demo.name" . }}-prometheus-server:9090/api/v1/otlp' + tls: + insecure: true + opensearch: + logs_index: otel + http: + endpoint: "http://otel-demo-opensearch:9200" + tls: + insecure: true + + processors: + # This processor is used to help limit high cardinality on next.js span names + # When this PR is merged (and released) we can remove this transform processor + # https://github.com/vercel/next.js/pull/64852 + transform: + error_mode: ignore + trace_statements: + - context: span + statements: + # could be removed when https://github.com/vercel/next.js/pull/64852 is fixed upstream + - replace_pattern(name, "\\?.*", "") + - replace_match(name, "GET /api/products/*", "GET /api/products/{productId}") + resource: + attributes: + - key: service.instance.id + from_attribute: k8s.pod.uid + action: insert + + connectors: + spanmetrics: { } + + service: + pipelines: + traces: + processors: [ memory_limiter, resource, transform, batch ] + exporters: [ otlp, debug, spanmetrics ] + metrics: + receivers: [ httpcheck/frontendproxy, redis, otlp, spanmetrics ] + processors: [ memory_limiter, resource, batch ] + exporters: [ otlphttp/prometheus, debug ] + logs: + processors: [ memory_limiter, resource, batch ] + exporters: [ opensearch, debug ] + + jaeger: + enabled: false + provisionDataStore: + cassandra: false + allInOne: + enabled: true + args: + - "--memory.max-traces=5000" + - "--query.base-path=/jaeger/ui" + - "--prometheus.server-url=http://{{ include \"otel-demo.name\" . }}-prometheus-server:9090" + - "--prometheus.query.normalize-calls=true" + - "--prometheus.query.normalize-duration=true" + extraEnv: + - name: METRICS_STORAGE_TYPE + value: prometheus + - name: COLLECTOR_OTLP_GRPC_HOST_PORT + value: 0.0.0.0:4317 + - name: COLLECTOR_OTLP_HTTP_HOST_PORT + value: 0.0.0.0:4318 + resources: + limits: + memory: 400Mi + storage: + type: memory + agent: + enabled: false + collector: + enabled: false + query: + enabled: false + + + prometheus: + enabled: false + alertmanager: + enabled: false + configmapReload: + prometheus: + enabled: false + kube-state-metrics: + enabled: false + prometheus-node-exporter: + enabled: false + prometheus-pushgateway: + enabled: false + + server: + extraFlags: + - "enable-feature=exemplar-storage" + - "web.enable-otlp-receiver" + global: + scrape_interval: 5s + scrape_timeout: 3s + evaluation_interval: 30s + tsdb: + out_of_order_time_window: 30m + prometheus.yml: + otlp: + keep_identifying_resource_attributes: true + # Recommended attributes to be promoted to labels. + promote_resource_attributes: + - service.instance.id + - service.name + - service.namespace + - cloud.availability_zone + - cloud.region + - container.name + - deployment.environment.name + - k8s.cluster.name + - k8s.container.name + - k8s.cronjob.name + - k8s.daemonset.name + - k8s.deployment.name + - k8s.job.name + - k8s.namespace.name + - k8s.pod.name + - k8s.replicaset.name + - k8s.statefulset.name + persistentVolume: + enabled: false + service: + servicePort: 9090 + resources: + limits: + memory: 300Mi + + serverFiles: + prometheus.yml: + scrape_configs: + - job_name: 'otel-collector' + honor_labels: true + kubernetes_sd_configs: + - role: pod + namespaces: + own_namespace: true + relabel_configs: + - source_labels: [ __meta_kubernetes_pod_annotation_opentelemetry_community_demo ] + action: keep + regex: true + + grafana: + enabled: false + testFramework: + enabled: false + grafana.ini: + auth: + disable_login_form: true + auth.anonymous: + enabled: true + org_name: Main Org. + org_role: Admin + server: + root_url: "%(protocol)s://%(domain)s:%(http_port)s/grafana" + serve_from_sub_path: true + adminPassword: admin + plugins: + - grafana-opensearch-datasource + datasources: + datasources.yaml: + apiVersion: 1 + datasources: + - name: Prometheus + uid: webstore-metrics + type: prometheus + url: 'http://{{ include "otel-demo.name" . }}-prometheus-server:9090' + editable: true + isDefault: true + jsonData: + exemplarTraceIdDestinations: + - datasourceUid: webstore-traces + name: trace_id + + - url: http://localhost:8080/jaeger/ui/trace/$${__value.raw} + name: trace_id + urlDisplayLabel: View in Jaeger UI + + - name: Jaeger + uid: webstore-traces + type: jaeger + url: 'http://{{ include "otel-demo.name" . }}-jaeger-query:16686/jaeger/ui' + editable: true + isDefault: false + + - name: OpenSearch + type: grafana-opensearch-datasource + url: 'http://otel-demo-opensearch:9200/' + access: proxy + editable: true + isDefault: false + jsonData: + database: otel + flavor: opensearch + logLevelField: severity + logMessageField: body + pplEnabled: true + timeField: observedTimestamp + version: 2.18.0 + dashboardProviders: + dashboardproviders.yaml: + apiVersion: 1 + providers: + - name: 'default' + orgId: 1 + folder: '' + type: file + disableDeletion: false + editable: true + options: + path: /var/lib/grafana/dashboards/default + dashboardsConfigMaps: + default: '{{ include "otel-demo.name" . }}-grafana-dashboards' + resources: + limits: + memory: 150Mi + + opensearch: + enabled: true + fullnameOverride: otel-demo-opensearch + clusterName: demo-cluster + nodeGroup: otel-demo + singleNode: true + opensearchJavaOpts: "-Xms300m -Xmx300m" + persistence: + enabled: false + extraEnvs: + - name: "bootstrap.memory_lock" + value: "true" + - name: "DISABLE_INSTALL_DEMO_CONFIG" + value: "true" + - name: "DISABLE_SECURITY_PLUGIN" + value: "true" + resources: + limits: + memory: 1Gi + diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/query-test.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/query-test.yaml new file mode 100644 index 000000000..192faa4c7 --- /dev/null +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/query-test.yaml @@ -0,0 +1,39 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: k8s-monitoring-test +spec: + interval: 1m + url: https://github.com/grafana/k8s-monitoring-helm + ref: + branch: main + ignore: | + /* + !/charts/k8s-monitoring-test +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: k8s-monitoring-test +spec: + interval: 1m + chart: + spec: + chart: charts/k8s-monitoring-test + sourceRef: + kind: GitRepository + name: k8s-monitoring-test + interval: 1m + values: + tests: + - env: + PROMETHEUS_URL: https://prometheus-prod-13-prod-us-east-0.grafana.net/api/prom/api/v1/query + LOKI_URL: https://logs-prod-006.grafana.net/loki/api/v1/query + envFrom: + - secretRef: {name: grafana-cloud-credentials} + - configMapRef: {name: test-variables} + queries: + # otel demo services + - query: group by (telemetry_sdk_language, job) (traces_target_info{deployment_environment=~".*", cluster="$CLUSTER"}) + type: promql diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/values.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/values.yaml new file mode 100644 index 000000000..c67b4c75e --- /dev/null +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/values.yaml @@ -0,0 +1,73 @@ +--- +cluster: + name: application-observability-gc-feature-test + +destinations: + - name: grafanaCloudLogs + type: loki + url: https://logs-prod-006.grafana.net/loki/api/v1/push + auth: + type: basic + usernameKey: LOKI_USER + passwordKey: LOKI_PASS + secret: + create: false + name: grafana-cloud-credentials + - name: otlp-gateway + type: otlp + url: https://otlp-gateway-prod-us-east-0.grafana.net/otlp + protocol: http + auth: + type: basic + usernameKey: OTLP_GATEWAY_USER + passwordKey: OTLP_GATEWAY_PASS + secret: + create: false + name: grafana-cloud-credentials + metrics: + enabled: true + logs: + enabled: false + traces: + enabled: true + processors: + batch: + size: 4096 + maxSize: 4096 + +applicationObservability: + enabled: true + traces: + transforms: + span: + - replace_pattern(name, "\\?.*", "") + - replace_match(name, "GET /api/products/*", "GET /api/products/{productId}") + + receivers: + otlp: + grpc: + enabled: true + http: + enabled: true + +podLogs: + enabled: true + +alloy-logs: + enabled: true + +alloy-receiver: + enabled: true + controller: + type: deployment + alloy: + extraPorts: + - name: otlp-http + port: 4318 + targetPort: 4318 + protocol: TCP + - name: otlp-grpc + port: 4317 + targetPort: 4317 + protocol: TCP + From e38ab3fd654994732dda6c24fdf880e93a23948c Mon Sep 17 00:00:00 2001 From: Robbie Lankford Date: Wed, 5 Feb 2025 14:30:04 -0800 Subject: [PATCH 2/6] update otel demo manifest and rename dirs --- .../deployments/otel-demo-manifest.yaml | 1002 ----------------- .../app-observability}/.envrc | 0 .../app-observability}/.gitignore | 0 .../app-observability}/Makefile | 0 .../app-observability}/README.md | 0 .../deployments/otel-demo-manifest.yaml | 69 ++ .../deployments/query-test.yaml | 0 .../app-observability}/values.yaml | 0 .../k8s-monitoring/.envrc | 0 .../k8s-monitoring/.gitignore | 0 .../k8s-monitoring/.rendered/output.yaml | 0 .../k8s-monitoring/Makefile | 0 .../deployments/query-test.yaml | 0 .../k8s-monitoring/values.yaml | 0 14 files changed, 69 insertions(+), 1002 deletions(-) delete mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/otel-demo-manifest.yaml rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features/application-observability => grafana-cloud/app-observability}/.envrc (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features/application-observability => grafana-cloud/app-observability}/.gitignore (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features/application-observability => grafana-cloud/app-observability}/Makefile (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features/application-observability => grafana-cloud/app-observability}/README.md (100%) create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/otel-demo-manifest.yaml rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features/application-observability => grafana-cloud/app-observability}/deployments/query-test.yaml (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features/application-observability => grafana-cloud/app-observability}/values.yaml (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features => grafana-cloud}/k8s-monitoring/.envrc (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features => grafana-cloud}/k8s-monitoring/.gitignore (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features => grafana-cloud}/k8s-monitoring/.rendered/output.yaml (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features => grafana-cloud}/k8s-monitoring/Makefile (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features => grafana-cloud}/k8s-monitoring/deployments/query-test.yaml (100%) rename charts/k8s-monitoring/tests/platform/{grafana-cloud-features => grafana-cloud}/k8s-monitoring/values.yaml (100%) diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/otel-demo-manifest.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/otel-demo-manifest.yaml deleted file mode 100644 index 2daabccd4..000000000 --- a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/otel-demo-manifest.yaml +++ /dev/null @@ -1,1002 +0,0 @@ ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: open-telemetry - namespace: default -spec: - interval: 1h - url: https://open-telemetry.github.io/opentelemetry-helm-charts ---- -apiVersion: v1 -kind: Namespace -metadata: - name: otel-demo ---- -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: otel-demo - namespace: otel-demo -spec: - interval: 10m - timeout: 10m - chart: - spec: - chart: opentelemetry-demo - version: 0.33.8 - sourceRef: - kind: HelmRepository - name: open-telemetry - namespace: default - interval: 10m - values: - # yaml-language-server: $schema=./values.schema.json - default: - # List of environment variables applied to all components - env: - - name: RANDOM_NUMBER - valueFrom: - configMapKeyRef: - name: test-variables - key: RANDOM_NUMBER - - name: CLUSTER - valueFrom: - configMapKeyRef: - name: test-variables - key: CLUSTER - - name: OTEL_SERVICE_NAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: "metadata.labels['app.kubernetes.io/component']" - - name: OTEL_COLLECTOR_NAME - value: 'k8smon-alloy-receiver.default' - - name: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - value: cumulative - - name: OTEL_RESOURCE_ATTRIBUTES - value: 'service.name=$(OTEL_SERVICE_NAME),service.namespace=opentelemetry-demo,service.version={{ .Chart.AppVersion }},k8s.cluster.name=$(CLUSTER)' - # Allows overriding and additions to .Values.default.env - envOverrides: [ ] - # - name: OTEL_K8S_NODE_NAME - # value: "someConstantValue" - image: - repository: ghcr.io/open-telemetry/demo - # Overrides the image tag whose default is the chart appVersion. - # The service's name will be applied to the end of this value. - tag: "" - pullPolicy: IfNotPresent - pullSecrets: [ ] - # Default # of replicas for all components - replicas: 1 - # default revisionHistoryLimit for all components (number of old ReplicaSets to retain) - revisionHistoryLimit: 10 - # Default schedulingRules for all components - schedulingRules: - nodeSelector: { } - affinity: { } - tolerations: [ ] - # Default securityContext for all components - securityContext: { } - - serviceAccount: - # Specifies whether a service account should be created - create: true - # Annotations to add to the service account - annotations: { } - # The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template - name: "" - - components: - ## Demo Components are named objects (services) with several properties - # demoService: - ## Enable the component (service) - # enabled: true - # useDefault: - ## Use default environment variables - # env: true - ## Override Image repository and Tag. Tag will use appVersion as default. - ## Component's name will be applied to end of this value. - # imageOverride: {} - ## Optional service definitions to apply - # service: - ## Service Type to use for this component. Default is ClusterIP. - # type: ClusterIP - ## Service Port to use to expose this component. Default is nil - # port: 8080 - ## Service Node Port to use to expose this component on a NodePort service. Default is nil - # nodePort: 30080 - ## Service Annotations to add to this component - # annotations: {} - ## Additional service ports to use to expose this component - # ports: - # - name: extraServicePort - # value: 8081 - ## Environment variables to add to the component's pod - # env: - ## Environment variables that upsert (append + merge) into the `env` specification for this component. - ## A variable named OTEL_RESOURCE_ATTRIBUTES_EXTRA will have its value appended to the OTEL_RESOURCE_ATTRIBUTES value. - # envOverrides: - ## Pod Scheduling rules for nodeSelector, affinity, or tolerations. - # schedulingRules: - # nodeSelector: {} - # affinity: {} - # tolerations: [] - ## Pod Annotations to add to this component - # podAnnotations: {} - ## Resources for this component - # resources: {} - ## Container security context for setting user ID (UID), group ID (GID) and other security policies - # securityContext: - ## Ingresses rules to add for the to the component - # ingress: - ## Enable the creation of Ingress rules. Default is false - # enabled: false - ## Annotations to add to the ingress rule - # annotations: {} - ## Which Ingress class (controller) to use. Default is unspecified. - # ingressClassName: nginx - ## Hosts definitions for the Ingress rule - # hosts: - # - host: demo.example.com - ## Each host can have multiple paths/routes - # paths: - # - path: / - # pathType: Prefix - # port: 8080 - ## Optional TLS specifications for the Ingress rule - # tls: - # - secretName: demo-tls - # hosts: - # - demo.example.com - ## Additional ingresses - only created if ingress.enabled is true - ## Useful for when differently annotated ingress services are required - ## Each additional ingress needs key "name" set to something unique - # additionalIngresses: [] - # - name: extra-demo-ingress - # ingressClassName: nginx - # annotations: {} - # hosts: - # - host: demo.example.com - # paths: - # - path: / - # pathType: Prefix - # port: 8080 - # tls: - # - secretName: demo-tls - # hosts: - # - demo.example.com - ## Command to use in the container spec, in case you don't want to go with the default command from the image. - # command: [] - ## Configuration to for this component; will create a Volume, and Mount backed by an optionally created ConfigMap. - ## The name, mountPath are required, and one of existingConfigMap or data is required. - ## If an existing ConfigMap is not provided, the contents under data will be used for the created ConfigMap. - # mountedConfigMaps: [] - # - name: my-config - # mountPath: /etc/config - # subPath: - # existingConfigMap: my-configmap - # data: - # my-config.yaml: | - # key: value - # # Kubernetes container health check options - # livenessProbe: {} - # # Optional init container to run before the pod starts. - # initContainers: - # - name: - # image: - # command: [list of commands for the init container to run] - # # Replicas for the component - # replicas: 1 - # # Number of old ReplicaSets to retain - # revisionHistoryLimit: 10 - # # Optional pod security context for setting user ID (UID), group ID (GID) and other security policies - # # This will be applied at pod level, can be applied globally for all pods: .Values.default.podSecurityContext - # # Or it can be applied to a specific component: .Values.components..podSecurityContext - # podSecurityContext: - # runAsGroup: 65534 - # runAsNonRoot: true - # runAsUser: 65534 - - accountingService: - enabled: true - useDefault: - env: true - env: - - name: KAFKA_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-kafka:9092' - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4318 - resources: - limits: - memory: 120Mi - initContainers: - - name: wait-for-kafka - image: busybox:latest - command: [ 'sh', '-c', 'until nc -z -v -w30 {{ include "otel-demo.name" . }}-kafka 9092; do echo waiting for kafka; sleep 2; done;' ] - - adService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: AD_SERVICE_PORT - value: "8080" - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4318 - - name: OTEL_LOGS_EXPORTER - value: otlp - resources: - limits: - memory: 300Mi - - cartService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: CART_SERVICE_PORT - value: "8080" - - name: ASPNETCORE_URLS - value: http://*:$(CART_SERVICE_PORT) - - name: VALKEY_ADDR - value: '{{ include "otel-demo.name" . }}-valkey:6379' - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - resources: - limits: - memory: 160Mi - initContainers: - - name: wait-for-valkey - image: busybox:latest - command: [ 'sh', '-c', 'until nc -z -v -w30 {{ include "otel-demo.name" . }}-valkey 6379; do echo waiting for valkey; sleep 2; done;' ] - - checkoutService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: CHECKOUT_SERVICE_PORT - value: "8080" - - name: CART_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-cartservice:8080' - - name: CURRENCY_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-currencyservice:8080' - - name: EMAIL_SERVICE_ADDR - value: 'http://{{ include "otel-demo.name" . }}-emailservice:8080' - - name: PAYMENT_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-paymentservice:8080' - - name: PRODUCT_CATALOG_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-productcatalogservice:8080' - - name: SHIPPING_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-shippingservice:8080' - - name: KAFKA_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-kafka:9092' - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - resources: - limits: - memory: 20Mi - initContainers: - - name: wait-for-kafka - image: busybox:latest - command: [ 'sh', '-c', 'until nc -z -v -w30 {{ include "otel-demo.name" . }}-kafka 9092; do echo waiting for kafka; sleep 2; done;' ] - - currencyService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: CURRENCY_SERVICE_PORT - value: "8080" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - - name: VERSION - value: "{{ .Chart.AppVersion }}" - resources: - limits: - memory: 20Mi - - emailService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: EMAIL_SERVICE_PORT - value: "8080" - - name: APP_ENV - value: production - - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4318/v1/traces - resources: - limits: - memory: 100Mi - - frauddetectionService: - enabled: true - useDefault: - env: true - env: - - name: KAFKA_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-kafka:9092' - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4318 - resources: - limits: - memory: 300Mi - initContainers: - - name: wait-for-kafka - image: busybox:latest - command: [ 'sh', '-c', 'until nc -z -v -w30 {{ include "otel-demo.name" . }}-kafka 9092; do echo waiting for kafka; sleep 2; done;' ] - - frontend: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: FRONTEND_PORT - value: "8080" - - name: FRONTEND_ADDR - value: :8080 - - name: AD_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-adservice:8080' - - name: CART_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-cartservice:8080' - - name: CHECKOUT_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-checkoutservice:8080' - - name: CURRENCY_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-currencyservice:8080' - - name: PRODUCT_CATALOG_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-productcatalogservice:8080' - - name: RECOMMENDATION_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-recommendationservice:8080' - - name: SHIPPING_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-shippingservice:8080' - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_COLLECTOR_HOST - value: $(OTEL_COLLECTOR_NAME) - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - - name: WEB_OTEL_SERVICE_NAME - value: frontend-web - - name: PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - value: http://localhost:8080/otlp-http/v1/traces # This expects users to use `kubectl port-forward ...` - resources: - limits: - memory: 250Mi - securityContext: - runAsUser: 1001 # nextjs - runAsGroup: 1001 - runAsNonRoot: true - - frontendProxy: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: ENVOY_PORT - value: "8080" - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: FLAGD_UI_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_UI_PORT - value: "4000" - - name: FRONTEND_HOST - value: '{{ include "otel-demo.name" . }}-frontend' - - name: FRONTEND_PORT - value: "8080" - - name: GRAFANA_SERVICE_HOST - value: '{{ include "otel-demo.name" . }}-grafana' - - name: GRAFANA_SERVICE_PORT - value: "80" - - name: IMAGE_PROVIDER_HOST - value: '{{ include "otel-demo.name" . }}-imageprovider' - - name: IMAGE_PROVIDER_PORT - value: "8081" - - name: JAEGER_SERVICE_HOST - value: '{{ include "otel-demo.name" . }}-jaeger-query' - - name: JAEGER_SERVICE_PORT - value: "16686" - - name: LOCUST_WEB_HOST - value: '{{ include "otel-demo.name" . }}-loadgenerator' - - name: LOCUST_WEB_PORT - value: "8089" - - name: OTEL_COLLECTOR_HOST - value: $(OTEL_COLLECTOR_NAME) - - name: OTEL_COLLECTOR_PORT_GRPC - value: "4317" - - name: OTEL_COLLECTOR_PORT_HTTP - value: "4318" - resources: - limits: - memory: 50Mi - securityContext: - runAsUser: 101 # envoy - runAsGroup: 101 - runAsNonRoot: true - - imageprovider: - enabled: true - useDefault: - env: true - service: - port: 8081 - env: - - name: IMAGE_PROVIDER_PORT - value: "8081" - - name: OTEL_COLLECTOR_PORT_GRPC - value: "4317" - - name: OTEL_COLLECTOR_HOST - value: $(OTEL_COLLECTOR_NAME) - resources: - limits: - memory: 50Mi - - loadgenerator: - enabled: true - useDefault: - env: true - service: - port: 8089 - env: - - name: LOCUST_WEB_PORT - value: "8089" - - name: LOCUST_USERS - value: "10" - - name: LOCUST_SPAWN_RATE - value: "1" - - name: LOCUST_HOST - value: 'http://{{ include "otel-demo.name" . }}-frontendproxy:8080' - - name: LOCUST_HEADLESS - value: "false" - - name: LOCUST_AUTOSTART - value: "true" - - name: LOCUST_BROWSER_TRAFFIC_ENABLED - value: "true" - - name: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION - value: python - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - resources: - limits: - memory: 1500Mi - - paymentService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: PAYMENT_SERVICE_PORT - value: "8080" - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - resources: - limits: - memory: 120Mi - securityContext: - runAsUser: 1000 # node - runAsGroup: 1000 - runAsNonRoot: true - - productCatalogService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: PRODUCT_CATALOG_SERVICE_PORT - value: "8080" - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - resources: - limits: - memory: 20Mi - - quoteService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: QUOTE_SERVICE_PORT - value: "8080" - - name: OTEL_PHP_AUTOLOAD_ENABLED - value: "true" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4318 - resources: - limits: - memory: 40Mi - securityContext: - runAsUser: 33 # www-data - runAsGroup: 33 - runAsNonRoot: true - - recommendationService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: RECOMMENDATION_SERVICE_PORT - value: "8080" - - name: PRODUCT_CATALOG_SERVICE_ADDR - value: '{{ include "otel-demo.name" . }}-productcatalogservice:8080' - - name: OTEL_PYTHON_LOG_CORRELATION - value: "true" - - name: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION - value: python - - name: FLAGD_HOST - value: '{{ include "otel-demo.name" . }}-flagd' - - name: FLAGD_PORT - value: "8013" - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - resources: - limits: - memory: 500Mi # This is high to enable supporting the recommendationCache feature flag use case - - shippingService: - enabled: true - useDefault: - env: true - service: - port: 8080 - env: - - name: SHIPPING_SERVICE_PORT - value: "8080" - - name: QUOTE_SERVICE_ADDR - value: 'http://{{ include "otel-demo.name" . }}-quoteservice:8080' - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4317 - resources: - limits: - memory: 20Mi - - flagd: - enabled: true - imageOverride: - repository: "ghcr.io/open-feature/flagd" - tag: "v0.11.1" - useDefault: - env: true - replicas: 1 - service: - port: 8013 - env: - - name: FLAGD_METRICS_EXPORTER - value: otel - - name: FLAGD_OTEL_COLLECTOR_URI - value: $(OTEL_COLLECTOR_NAME):4317 - resources: - limits: - memory: 75Mi - command: - - "/flagd-build" - - "start" - - "--uri" - - "file:./etc/flagd/demo.flagd.json" - mountedEmptyDirs: - - name: config-rw - mountPath: /etc/flagd - # flgad-ui as a sidecar container in the same pod so the flag json file can be shared - sidecarContainers: - - name: flagdui - useDefault: - env: true - service: - port: 4000 - env: - - name: FLAGD_METRICS_EXPORTER - value: otel - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4318 - resources: - limits: - memory: 75Mi - volumeMounts: - - name: config-rw - mountPath: /app/data - initContainers: - - name: init-config - image: busybox - command: [ 'sh', '-c', 'cp /config-ro/demo.flagd.json /config-rw/demo.flagd.json && cat /config-rw/demo.flagd.json' ] - volumeMounts: - - mountPath: /config-ro - name: config-ro - - mountPath: /config-rw - name: config-rw - additionalVolumes: - - name: config-ro - configMap: - name: '{{ include "otel-demo.name" . }}-flagd-config' - - kafka: - enabled: true - useDefault: - env: true - replicas: 1 - ports: - - name: plaintext - value: 9092 - - name: controller - value: 9093 - env: - - name: KAFKA_ADVERTISED_LISTENERS - value: 'PLAINTEXT://{{ include "otel-demo.name" . }}-kafka:9092' - - name: OTEL_EXPORTER_OTLP_ENDPOINT - value: http://$(OTEL_COLLECTOR_NAME):4318 - - name: KAFKA_HEAP_OPTS - value: "-Xmx400M -Xms400M" - resources: - limits: - memory: 600Mi - securityContext: - runAsUser: 1000 # appuser - runAsGroup: 1000 - runAsNonRoot: true - - valkey: - enabled: true - useDefault: - env: true - imageOverride: - repository: "valkey/valkey" - tag: "7.2-alpine" - replicas: 1 - ports: - - name: valkey - value: 6379 - resources: - limits: - memory: 20Mi - securityContext: - runAsUser: 999 # valkey - runAsGroup: 1000 - runAsNonRoot: true - - opentelemetry-collector: - image: - repository: "otel/opentelemetry-collector-contrib" - enabled: false - nameOverride: otelcol - mode: deployment - presets: - kubernetesAttributes: - enabled: true - resources: - limits: - memory: 200Mi - service: - type: ClusterIP - ports: - metrics: - enabled: true - prometheus: - enabled: true - containerPort: 9464 - servicePort: 9464 - protocol: TCP - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "9464" - opentelemetry_community_demo: "true" - config: - receivers: - otlp: - protocols: - http: - # Since this collector needs to receive data from the web, enable cors for all origins - # `allowed_origins` can be refined for your deployment domain - cors: - allowed_origins: - - "http://*" - - "https://*" - httpcheck/frontendproxy: - targets: - - endpoint: 'http://{{ include "otel-demo.name" . }}-frontendproxy:8080' - redis: - endpoint: "valkey-cart:6379" - collection_interval: 10s - - exporters: - ## Create an exporter to Jaeger using the standard `otlp` export format - otlp: - endpoint: '{{ include "otel-demo.name" . }}-jaeger-collector:4317' - tls: - insecure: true - # Create an exporter to Prometheus (metrics) - otlphttp/prometheus: - endpoint: 'http://{{ include "otel-demo.name" . }}-prometheus-server:9090/api/v1/otlp' - tls: - insecure: true - opensearch: - logs_index: otel - http: - endpoint: "http://otel-demo-opensearch:9200" - tls: - insecure: true - - processors: - # This processor is used to help limit high cardinality on next.js span names - # When this PR is merged (and released) we can remove this transform processor - # https://github.com/vercel/next.js/pull/64852 - transform: - error_mode: ignore - trace_statements: - - context: span - statements: - # could be removed when https://github.com/vercel/next.js/pull/64852 is fixed upstream - - replace_pattern(name, "\\?.*", "") - - replace_match(name, "GET /api/products/*", "GET /api/products/{productId}") - resource: - attributes: - - key: service.instance.id - from_attribute: k8s.pod.uid - action: insert - - connectors: - spanmetrics: { } - - service: - pipelines: - traces: - processors: [ memory_limiter, resource, transform, batch ] - exporters: [ otlp, debug, spanmetrics ] - metrics: - receivers: [ httpcheck/frontendproxy, redis, otlp, spanmetrics ] - processors: [ memory_limiter, resource, batch ] - exporters: [ otlphttp/prometheus, debug ] - logs: - processors: [ memory_limiter, resource, batch ] - exporters: [ opensearch, debug ] - - jaeger: - enabled: false - provisionDataStore: - cassandra: false - allInOne: - enabled: true - args: - - "--memory.max-traces=5000" - - "--query.base-path=/jaeger/ui" - - "--prometheus.server-url=http://{{ include \"otel-demo.name\" . }}-prometheus-server:9090" - - "--prometheus.query.normalize-calls=true" - - "--prometheus.query.normalize-duration=true" - extraEnv: - - name: METRICS_STORAGE_TYPE - value: prometheus - - name: COLLECTOR_OTLP_GRPC_HOST_PORT - value: 0.0.0.0:4317 - - name: COLLECTOR_OTLP_HTTP_HOST_PORT - value: 0.0.0.0:4318 - resources: - limits: - memory: 400Mi - storage: - type: memory - agent: - enabled: false - collector: - enabled: false - query: - enabled: false - - - prometheus: - enabled: false - alertmanager: - enabled: false - configmapReload: - prometheus: - enabled: false - kube-state-metrics: - enabled: false - prometheus-node-exporter: - enabled: false - prometheus-pushgateway: - enabled: false - - server: - extraFlags: - - "enable-feature=exemplar-storage" - - "web.enable-otlp-receiver" - global: - scrape_interval: 5s - scrape_timeout: 3s - evaluation_interval: 30s - tsdb: - out_of_order_time_window: 30m - prometheus.yml: - otlp: - keep_identifying_resource_attributes: true - # Recommended attributes to be promoted to labels. - promote_resource_attributes: - - service.instance.id - - service.name - - service.namespace - - cloud.availability_zone - - cloud.region - - container.name - - deployment.environment.name - - k8s.cluster.name - - k8s.container.name - - k8s.cronjob.name - - k8s.daemonset.name - - k8s.deployment.name - - k8s.job.name - - k8s.namespace.name - - k8s.pod.name - - k8s.replicaset.name - - k8s.statefulset.name - persistentVolume: - enabled: false - service: - servicePort: 9090 - resources: - limits: - memory: 300Mi - - serverFiles: - prometheus.yml: - scrape_configs: - - job_name: 'otel-collector' - honor_labels: true - kubernetes_sd_configs: - - role: pod - namespaces: - own_namespace: true - relabel_configs: - - source_labels: [ __meta_kubernetes_pod_annotation_opentelemetry_community_demo ] - action: keep - regex: true - - grafana: - enabled: false - testFramework: - enabled: false - grafana.ini: - auth: - disable_login_form: true - auth.anonymous: - enabled: true - org_name: Main Org. - org_role: Admin - server: - root_url: "%(protocol)s://%(domain)s:%(http_port)s/grafana" - serve_from_sub_path: true - adminPassword: admin - plugins: - - grafana-opensearch-datasource - datasources: - datasources.yaml: - apiVersion: 1 - datasources: - - name: Prometheus - uid: webstore-metrics - type: prometheus - url: 'http://{{ include "otel-demo.name" . }}-prometheus-server:9090' - editable: true - isDefault: true - jsonData: - exemplarTraceIdDestinations: - - datasourceUid: webstore-traces - name: trace_id - - - url: http://localhost:8080/jaeger/ui/trace/$${__value.raw} - name: trace_id - urlDisplayLabel: View in Jaeger UI - - - name: Jaeger - uid: webstore-traces - type: jaeger - url: 'http://{{ include "otel-demo.name" . }}-jaeger-query:16686/jaeger/ui' - editable: true - isDefault: false - - - name: OpenSearch - type: grafana-opensearch-datasource - url: 'http://otel-demo-opensearch:9200/' - access: proxy - editable: true - isDefault: false - jsonData: - database: otel - flavor: opensearch - logLevelField: severity - logMessageField: body - pplEnabled: true - timeField: observedTimestamp - version: 2.18.0 - dashboardProviders: - dashboardproviders.yaml: - apiVersion: 1 - providers: - - name: 'default' - orgId: 1 - folder: '' - type: file - disableDeletion: false - editable: true - options: - path: /var/lib/grafana/dashboards/default - dashboardsConfigMaps: - default: '{{ include "otel-demo.name" . }}-grafana-dashboards' - resources: - limits: - memory: 150Mi - - opensearch: - enabled: true - fullnameOverride: otel-demo-opensearch - clusterName: demo-cluster - nodeGroup: otel-demo - singleNode: true - opensearchJavaOpts: "-Xms300m -Xmx300m" - persistence: - enabled: false - extraEnvs: - - name: "bootstrap.memory_lock" - value: "true" - - name: "DISABLE_INSTALL_DEMO_CONFIG" - value: "true" - - name: "DISABLE_SECURITY_PLUGIN" - value: "true" - resources: - limits: - memory: 1Gi - diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.envrc b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.envrc similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.envrc rename to charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.envrc diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.gitignore b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.gitignore similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/.gitignore rename to charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.gitignore diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/Makefile b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/Makefile similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/Makefile rename to charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/Makefile diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/README.md b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/README.md similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/README.md rename to charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/README.md diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/otel-demo-manifest.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/otel-demo-manifest.yaml new file mode 100644 index 000000000..e73654e63 --- /dev/null +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/otel-demo-manifest.yaml @@ -0,0 +1,69 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: open-telemetry + namespace: default +spec: + interval: 1h + url: https://open-telemetry.github.io/opentelemetry-helm-charts +--- +apiVersion: v1 +kind: Namespace +metadata: + name: otel-demo +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: otel-demo + namespace: otel-demo +spec: + interval: 10m + timeout: 10m + chart: + spec: + chart: opentelemetry-demo + version: 0.33.8 + sourceRef: + kind: HelmRepository + name: open-telemetry + namespace: default + interval: 10m + values: + default: + # List of environment variables applied to all components + env: + - name: RANDOM_NUMBER + valueFrom: + configMapKeyRef: + name: test-variables + key: RANDOM_NUMBER + - name: CLUSTER + valueFrom: + configMapKeyRef: + name: test-variables + key: CLUSTER + - name: OTEL_SERVICE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: "metadata.labels['app.kubernetes.io/component']" + - name: OTEL_COLLECTOR_NAME + value: 'k8smon-alloy-receiver.default' + - name: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE + value: cumulative + - name: OTEL_RESOURCE_ATTRIBUTES + value: 'service.name=$(OTEL_SERVICE_NAME),service.namespace=opentelemetry-demo,service.version={{ .Chart.AppVersion }},k8s.cluster.name=$(CLUSTER)' + + opentelemetry-collector: + enabled: false + + jaeger: + enabled: false + + prometheus: + enabled: false + + grafana: + enabled: false \ No newline at end of file diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/query-test.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/query-test.yaml similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/deployments/query-test.yaml rename to charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/query-test.yaml diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/values.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/values.yaml similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/application-observability/values.yaml rename to charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/values.yaml diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/.envrc b/charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/.envrc similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/.envrc rename to charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/.envrc diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/.gitignore b/charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/.gitignore similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/.gitignore rename to charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/.gitignore diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/.rendered/output.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/.rendered/output.yaml similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/.rendered/output.yaml rename to charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/.rendered/output.yaml diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/Makefile b/charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/Makefile similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/Makefile rename to charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/Makefile diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/deployments/query-test.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/deployments/query-test.yaml similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/deployments/query-test.yaml rename to charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/deployments/query-test.yaml diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/values.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/values.yaml similarity index 100% rename from charts/k8s-monitoring/tests/platform/grafana-cloud-features/k8s-monitoring/values.yaml rename to charts/k8s-monitoring/tests/platform/grafana-cloud/k8s-monitoring/values.yaml From ab2d101bde677997b57b189edc6633101df659af Mon Sep 17 00:00:00 2001 From: Robbie Lankford Date: Wed, 5 Feb 2025 14:35:46 -0800 Subject: [PATCH 3/6] make build --- .../app-observability/.rendered/output.yaml | 1068 +++++++++++++++++ 1 file changed, 1068 insertions(+) create mode 100644 charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.rendered/output.yaml diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.rendered/output.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.rendered/output.yaml new file mode 100644 index 000000000..88630eccf --- /dev/null +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.rendered/output.yaml @@ -0,0 +1,1068 @@ +--- +# Source: k8s-monitoring/charts/alloy-logs/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: k8smon-alloy-logs + namespace: default + labels: + helm.sh/chart: alloy-logs-0.11.0 + app.kubernetes.io/name: alloy-logs + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac +--- +# Source: k8s-monitoring/charts/alloy-receiver/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: k8smon-alloy-receiver + namespace: default + labels: + helm.sh/chart: alloy-receiver-0.11.0 + app.kubernetes.io/name: alloy-receiver + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac +--- +# Source: k8s-monitoring/templates/alloy-config.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: k8smon-alloy-logs + namespace: default +data: + config.alloy: |- + // Destination: grafanaCloudLogs (loki) + otelcol.exporter.loki "grafanacloudlogs" { + forward_to = [loki.write.grafanacloudlogs.receiver] + } + + loki.write "grafanacloudlogs" { + endpoint { + url = "https://logs-prod-006.grafana.net/loki/api/v1/push" + tenant_id = nonsensitive(remote.kubernetes.secret.grafanacloudlogs.data["tenantId"]) + basic_auth { + username = nonsensitive(remote.kubernetes.secret.grafanacloudlogs.data["LOKI_USER"]) + password = remote.kubernetes.secret.grafanacloudlogs.data["LOKI_PASS"] + } + tls_config { + insecure_skip_verify = false + ca_pem = nonsensitive(remote.kubernetes.secret.grafanacloudlogs.data["ca"]) + cert_pem = nonsensitive(remote.kubernetes.secret.grafanacloudlogs.data["cert"]) + key_pem = remote.kubernetes.secret.grafanacloudlogs.data["key"] + } + } + external_labels = { + cluster = "application-observability-gc-feature-test", + "k8s_cluster_name" = "application-observability-gc-feature-test", + } + } + + remote.kubernetes.secret "grafanacloudlogs" { + name = "grafana-cloud-credentials" + namespace = "default" + } + // Feature: Pod Logs + declare "pod_logs" { + argument "logs_destinations" { + comment = "Must be a list of log destinations where collected logs should be forwarded to" + } + + discovery.relabel "filtered_pods" { + targets = discovery.kubernetes.pods.targets + rule { + source_labels = ["__meta_kubernetes_namespace"] + action = "replace" + target_label = "namespace" + } + rule { + source_labels = ["__meta_kubernetes_pod_name"] + action = "replace" + target_label = "pod" + } + rule { + source_labels = ["__meta_kubernetes_pod_container_name"] + action = "replace" + target_label = "container" + } + rule { + source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_container_name"] + separator = "/" + action = "replace" + replacement = "$1" + target_label = "job" + } + + // set the container runtime as a label + rule { + action = "replace" + source_labels = ["__meta_kubernetes_pod_container_id"] + regex = "^(\\S+):\\/\\/.+$" + replacement = "$1" + target_label = "tmp_container_runtime" + } + + // make all labels on the pod available to the pipeline as labels, + // they are omitted before write to loki via stage.label_keep unless explicitly set + rule { + action = "labelmap" + regex = "__meta_kubernetes_pod_label_(.+)" + } + + // make all annotations on the pod available to the pipeline as labels, + // they are omitted before write to loki via stage.label_keep unless explicitly set + rule { + action = "labelmap" + regex = "__meta_kubernetes_pod_annotation_(.+)" + } + + // explicitly set service_name. if not set, loki will automatically try to populate a default. + // see https://grafana.com/docs/loki/latest/get-started/labels/#default-labels-for-all-users + // + // choose the first value found from the following ordered list: + // - pod.annotation[resource.opentelemetry.io/service.name] + // - pod.label[app.kubernetes.io/name] + // - k8s.pod.name + // - k8s.container.name + rule { + action = "replace" + source_labels = [ + "__meta_kubernetes_pod_annotation_resource_opentelemetry_io_service_name", + "__meta_kubernetes_pod_label_app_kubernetes_io_name", + "__meta_kubernetes_pod_name", + "__meta_kubernetes_pod_container_name", + ] + separator = ";" + regex = "^(?:;*)?([^;]+).*$" + replacement = "$1" + target_label = "service_name" + } + + // set service_namespace + rule { + action = "replace" + source_labels = ["__meta_kubernetes_pod_annotation_resource_opentelemetry_io_service_namespace"] + target_label = "service_namespace" + } + + // set deployment_environment and deployment_environment_name + rule { + action = "replace" + source_labels = ["__meta_kubernetes_pod_annotation_resource_opentelemetry_io_deployment_environment_name"] + target_label = "deployment_environment_name" + } + rule { + action = "replace" + source_labels = ["__meta_kubernetes_pod_annotation_resource_opentelemetry_io_deployment_environment"] + target_label = "deployment_environment" + } + rule { + source_labels = ["__meta_kubernetes_pod_annotation_k8s_grafana_com_logs_job"] + target_label = "job" + } + rule { + source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"] + target_label = "app_kubernetes_io_name" + } + } + + discovery.kubernetes "pods" { + role = "pod" + selectors { + role = "pod" + field = "spec.nodeName=" + sys.env("HOSTNAME") + } + } + + discovery.relabel "filtered_pods_with_paths" { + targets = discovery.relabel.filtered_pods.output + + rule { + source_labels = ["__meta_kubernetes_pod_uid", "__meta_kubernetes_pod_container_name"] + separator = "/" + action = "replace" + replacement = "/var/log/pods/*$1/*.log" + target_label = "__path__" + } + } + + local.file_match "pod_logs" { + path_targets = discovery.relabel.filtered_pods_with_paths.output + } + + loki.source.file "pod_logs" { + targets = local.file_match.pod_logs.targets + forward_to = [loki.process.pod_logs.receiver] + } + + loki.process "pod_logs" { + stage.match { + selector = "{tmp_container_runtime=~\"containerd|cri-o\"}" + // the cri processing stage extracts the following k/v pairs: log, stream, time, flags + stage.cri {} + + // Set the extract flags and stream values as labels + stage.labels { + values = { + flags = "", + stream = "", + } + } + } + + stage.match { + selector = "{tmp_container_runtime=\"docker\"}" + // the docker processing stage extracts the following k/v pairs: log, stream, time + stage.docker {} + + // Set the extract stream value as a label + stage.labels { + values = { + stream = "", + } + } + } + + // Drop the filename label, since it's not really useful in the context of Kubernetes, where we already have cluster, + // namespace, pod, and container labels. Drop any structured metadata. Also drop the temporary + // container runtime label as it is no longer needed. + stage.label_drop { + values = [ + "filename", + "tmp_container_runtime", + ] + } + + // Only keep the labels that are defined in the `keepLabels` list. + stage.label_keep { + values = ["app_kubernetes_io_name","container","instance","job","level","namespace","pod","service_name","service_namespace","deployment_environment","deployment_environment_name","integration"] + } + + forward_to = argument.logs_destinations.value + } + } + pod_logs "feature" { + logs_destinations = [ + loki.write.grafanacloudlogs.receiver, + ] + } +--- +# Source: k8s-monitoring/templates/alloy-config.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: k8smon-alloy-receiver + namespace: default +data: + config.alloy: |- + // Destination: grafanaCloudLogs (loki) + otelcol.exporter.loki "grafanacloudlogs" { + forward_to = [loki.write.grafanacloudlogs.receiver] + } + + loki.write "grafanacloudlogs" { + endpoint { + url = "https://logs-prod-006.grafana.net/loki/api/v1/push" + tenant_id = nonsensitive(remote.kubernetes.secret.grafanacloudlogs.data["tenantId"]) + basic_auth { + username = nonsensitive(remote.kubernetes.secret.grafanacloudlogs.data["LOKI_USER"]) + password = remote.kubernetes.secret.grafanacloudlogs.data["LOKI_PASS"] + } + tls_config { + insecure_skip_verify = false + ca_pem = nonsensitive(remote.kubernetes.secret.grafanacloudlogs.data["ca"]) + cert_pem = nonsensitive(remote.kubernetes.secret.grafanacloudlogs.data["cert"]) + key_pem = remote.kubernetes.secret.grafanacloudlogs.data["key"] + } + } + external_labels = { + cluster = "application-observability-gc-feature-test", + "k8s_cluster_name" = "application-observability-gc-feature-test", + } + } + + remote.kubernetes.secret "grafanacloudlogs" { + name = "grafana-cloud-credentials" + namespace = "default" + } + + // Destination: otlp-gateway (otlp) + otelcol.receiver.prometheus "otlp_gateway" { + output { + metrics = [otelcol.processor.attributes.otlp_gateway.input] + } + } + otelcol.auth.basic "otlp_gateway" { + username = nonsensitive(remote.kubernetes.secret.otlp_gateway.data["OTLP_GATEWAY_USER"]) + password = remote.kubernetes.secret.otlp_gateway.data["OTLP_GATEWAY_PASS"] + } + + otelcol.processor.attributes "otlp_gateway" { + action { + key = "cluster" + action = "upsert" + value = "application-observability-gc-feature-test" + } + action { + key = "k8s.cluster.name" + action = "upsert" + value = "application-observability-gc-feature-test" + } + output { + metrics = [otelcol.processor.transform.otlp_gateway.input] + logs = [otelcol.processor.transform.otlp_gateway.input] + traces = [otelcol.processor.transform.otlp_gateway.input] + } + } + + otelcol.processor.transform "otlp_gateway" { + error_mode = "ignore" + + output { + metrics = [otelcol.processor.batch.otlp_gateway.input] + traces = [otelcol.processor.batch.otlp_gateway.input] + } + } + + otelcol.processor.batch "otlp_gateway" { + timeout = "2s" + send_batch_size = 4096 + send_batch_max_size = 4096 + + output { + metrics = [otelcol.exporter.otlphttp.otlp_gateway.input] + traces = [otelcol.exporter.otlphttp.otlp_gateway.input] + } + } + otelcol.exporter.otlphttp "otlp_gateway" { + client { + endpoint = "https://otlp-gateway-prod-us-east-0.grafana.net/otlp" + auth = otelcol.auth.basic.otlp_gateway.handler + headers = { + "X-Scope-OrgID" = nonsensitive(remote.kubernetes.secret.otlp_gateway.data["tenantId"]), + } + tls { + insecure = false + insecure_skip_verify = false + ca_pem = nonsensitive(remote.kubernetes.secret.otlp_gateway.data["ca"]) + cert_pem = nonsensitive(remote.kubernetes.secret.otlp_gateway.data["cert"]) + key_pem = remote.kubernetes.secret.otlp_gateway.data["key"] + } + } + } + + remote.kubernetes.secret "otlp_gateway" { + name = "grafana-cloud-credentials" + namespace = "default" + } + // Feature: Application Observability + declare "application_observability" { + argument "metrics_destinations" { + comment = "Must be a list of metrics destinations where collected metrics should be forwarded to" + } + + argument "logs_destinations" { + comment = "Must be a list of log destinations where collected logs should be forwarded to" + } + + argument "traces_destinations" { + comment = "Must be a list of trace destinations where collected trace should be forwarded to" + } + + // OTLP Receiver + otelcol.receiver.otlp "receiver" { + grpc { + endpoint = "0.0.0.0:4317" + } + http { + endpoint = "0.0.0.0:4318" + } + debug_metrics { + disable_high_cardinality_metrics = true + } + output { + metrics = [otelcol.processor.resourcedetection.default.input] + logs = [otelcol.processor.resourcedetection.default.input] + traces = [otelcol.processor.resourcedetection.default.input] + } + } + + // Resource Detection Processor + otelcol.processor.resourcedetection "default" { + detectors = ["env", "system"] + system { + hostname_sources = ["os"] + } + + output { + metrics = [otelcol.processor.k8sattributes.default.input] + logs = [otelcol.processor.k8sattributes.default.input] + traces = [otelcol.processor.k8sattributes.default.input] + } + } + + // K8s Attributes Processor + otelcol.processor.k8sattributes "default" { + extract { + metadata = ["k8s.namespace.name","k8s.pod.name","k8s.deployment.name","k8s.statefulset.name","k8s.daemonset.name","k8s.cronjob.name","k8s.job.name","k8s.node.name","k8s.pod.uid","k8s.pod.start_time"] + } + pod_association { + source { + from = "connection" + } + } + + output { + metrics = [otelcol.processor.transform.default.input] + logs = [otelcol.processor.transform.default.input] + traces = [otelcol.processor.transform.default.input, otelcol.connector.host_info.default.input] + } + } + + // Host Info Connector + otelcol.connector.host_info "default" { + host_identifiers = [ "k8s.node.name" ] + + output { + metrics = [otelcol.processor.batch.default.input] + } + } + + // Transform Processor + otelcol.processor.transform "default" { + error_mode = "ignore" + log_statements { + context = "resource" + statements = [ + "set(attributes[\"pod\"], attributes[\"k8s.pod.name\"])", + "set(attributes[\"namespace\"], attributes[\"k8s.namespace.name\"])", + "set(attributes[\"loki.resource.labels\"], \"cluster, namespace, job, pod\")", + ] + } + trace_statements { + context = "span" + statements = [ + "replace_pattern(name, \"\\\\?.*\", \"\")", + "replace_match(name, \"GET /api/products/*\", \"GET /api/products/{productId}\")", + ] + } + + output { + metrics = [otelcol.processor.batch.default.input] + logs = [otelcol.processor.batch.default.input] + traces = [otelcol.processor.batch.default.input] + } + } + + // Batch Processor + otelcol.processor.batch "default" { + send_batch_size = 16384 + send_batch_max_size = 0 + timeout = "2s" + + output { + metrics = argument.metrics_destinations.value + logs = argument.logs_destinations.value + traces = argument.traces_destinations.value + } + } + } + application_observability "feature" { + metrics_destinations = [ + otelcol.processor.attributes.otlp_gateway.input, + ] + logs_destinations = [ + otelcol.exporter.loki.grafanacloudlogs.input, + ] + traces_destinations = [ + otelcol.processor.attributes.otlp_gateway.input, + ] + } + // Self Reporting + prometheus.exporter.unix "kubernetes_monitoring_telemetry" { + set_collectors = ["textfile"] + textfile { + directory = "/etc/alloy" + } + } + + discovery.relabel "kubernetes_monitoring_telemetry" { + targets = prometheus.exporter.unix.kubernetes_monitoring_telemetry.targets + rule { + target_label = "instance" + action = "replace" + replacement = "k8smon" + } + rule { + target_label = "job" + action = "replace" + replacement = "integrations/kubernetes/kubernetes_monitoring_telemetry" + } + } + + prometheus.scrape "kubernetes_monitoring_telemetry" { + job_name = "integrations/kubernetes/kubernetes_monitoring_telemetry" + targets = discovery.relabel.kubernetes_monitoring_telemetry.output + scrape_interval = "60s" + clustering { + enabled = true + } + forward_to = [prometheus.relabel.kubernetes_monitoring_telemetry.receiver] + } + + prometheus.relabel "kubernetes_monitoring_telemetry" { + rule { + source_labels = ["__name__"] + regex = "grafana_kubernetes_monitoring_.*" + action = "keep" + } + forward_to = [ + otelcol.receiver.prometheus.otlp_gateway.receiver, + ] + } + + self-reporting-metric.prom: | + + # HELP grafana_kubernetes_monitoring_build_info A metric to report the version of the Kubernetes Monitoring Helm chart + # TYPE grafana_kubernetes_monitoring_build_info gauge + grafana_kubernetes_monitoring_build_info{version="2.0.8", namespace="default"} 1 + # HELP grafana_kubernetes_monitoring_feature_info A metric to report the enabled features of the Kubernetes Monitoring Helm chart + # TYPE grafana_kubernetes_monitoring_feature_info gauge + grafana_kubernetes_monitoring_feature_info{feature="applicationObservability", protocols="otlpgrpc,otlphttp", version="1.0.0"} 1 + grafana_kubernetes_monitoring_feature_info{feature="podLogs", method="volumes", version="1.0.0"} 1 +--- +# Source: k8s-monitoring/charts/alloy-logs/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: k8smon-alloy-logs + labels: + helm.sh/chart: alloy-logs-0.11.0 + app.kubernetes.io/name: alloy-logs + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac +rules: + # Rules which allow discovery.kubernetes to function. + - apiGroups: + - "" + - "discovery.k8s.io" + - "networking.k8s.io" + resources: + - endpoints + - endpointslices + - ingresses + - nodes + - nodes/proxy + - nodes/metrics + - pods + - services + verbs: + - get + - list + - watch + # Rules which allow loki.source.kubernetes and loki.source.podlogs to work. + - apiGroups: + - "" + resources: + - pods + - pods/log + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - "monitoring.grafana.com" + resources: + - podlogs + verbs: + - get + - list + - watch + # Rules which allow mimir.rules.kubernetes to work. + - apiGroups: ["monitoring.coreos.com"] + resources: + - prometheusrules + verbs: + - get + - list + - watch + - nonResourceURLs: + - /metrics + verbs: + - get + # Rules for prometheus.kubernetes.* + - apiGroups: ["monitoring.coreos.com"] + resources: + - podmonitors + - servicemonitors + - probes + verbs: + - get + - list + - watch + # Rules which allow eventhandler to work. + - apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch + # needed for remote.kubernetes.* + - apiGroups: [""] + resources: + - "configmaps" + - "secrets" + verbs: + - get + - list + - watch + # needed for otelcol.processor.k8sattributes + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] +--- +# Source: k8s-monitoring/charts/alloy-receiver/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: k8smon-alloy-receiver + labels: + helm.sh/chart: alloy-receiver-0.11.0 + app.kubernetes.io/name: alloy-receiver + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac +rules: + # Rules which allow discovery.kubernetes to function. + - apiGroups: + - "" + - "discovery.k8s.io" + - "networking.k8s.io" + resources: + - endpoints + - endpointslices + - ingresses + - nodes + - nodes/proxy + - nodes/metrics + - pods + - services + verbs: + - get + - list + - watch + # Rules which allow loki.source.kubernetes and loki.source.podlogs to work. + - apiGroups: + - "" + resources: + - pods + - pods/log + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - "monitoring.grafana.com" + resources: + - podlogs + verbs: + - get + - list + - watch + # Rules which allow mimir.rules.kubernetes to work. + - apiGroups: ["monitoring.coreos.com"] + resources: + - prometheusrules + verbs: + - get + - list + - watch + - nonResourceURLs: + - /metrics + verbs: + - get + # Rules for prometheus.kubernetes.* + - apiGroups: ["monitoring.coreos.com"] + resources: + - podmonitors + - servicemonitors + - probes + verbs: + - get + - list + - watch + # Rules which allow eventhandler to work. + - apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch + # needed for remote.kubernetes.* + - apiGroups: [""] + resources: + - "configmaps" + - "secrets" + verbs: + - get + - list + - watch + # needed for otelcol.processor.k8sattributes + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] +--- +# Source: k8s-monitoring/charts/alloy-logs/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: k8smon-alloy-logs + labels: + helm.sh/chart: alloy-logs-0.11.0 + app.kubernetes.io/name: alloy-logs + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: k8smon-alloy-logs +subjects: + - kind: ServiceAccount + name: k8smon-alloy-logs + namespace: default +--- +# Source: k8s-monitoring/charts/alloy-receiver/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: k8smon-alloy-receiver + labels: + helm.sh/chart: alloy-receiver-0.11.0 + app.kubernetes.io/name: alloy-receiver + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: k8smon-alloy-receiver +subjects: + - kind: ServiceAccount + name: k8smon-alloy-receiver + namespace: default +--- +# Source: k8s-monitoring/charts/alloy-logs/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: k8smon-alloy-logs + labels: + helm.sh/chart: alloy-logs-0.11.0 + app.kubernetes.io/name: alloy-logs + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: networking +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: alloy-logs + app.kubernetes.io/instance: k8smon + internalTrafficPolicy: Cluster + ports: + - name: http-metrics + port: 12345 + targetPort: 12345 + protocol: "TCP" +--- +# Source: k8s-monitoring/charts/alloy-receiver/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: k8smon-alloy-receiver + labels: + helm.sh/chart: alloy-receiver-0.11.0 + app.kubernetes.io/name: alloy-receiver + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: networking +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: alloy-receiver + app.kubernetes.io/instance: k8smon + internalTrafficPolicy: Cluster + ports: + - name: http-metrics + port: 12345 + targetPort: 12345 + protocol: "TCP" + - name: otlp-http + port: 4318 + targetPort: 4318 + protocol: TCP + - name: otlp-grpc + port: 4317 + targetPort: 4317 + protocol: TCP +--- +# Source: k8s-monitoring/charts/alloy-logs/templates/controllers/daemonset.yaml +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: k8smon-alloy-logs + labels: + helm.sh/chart: alloy-logs-0.11.0 + app.kubernetes.io/name: alloy-logs + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy +spec: + minReadySeconds: 10 + selector: + matchLabels: + app.kubernetes.io/name: alloy-logs + app.kubernetes.io/instance: k8smon + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: alloy + k8s.grafana.com/logs.job: integrations/alloy + labels: + app.kubernetes.io/name: alloy-logs + app.kubernetes.io/instance: k8smon + spec: + serviceAccountName: k8smon-alloy-logs + containers: + - name: alloy + image: docker.io/grafana/alloy:v1.6.1 + imagePullPolicy: IfNotPresent + args: + - run + - /etc/alloy/config.alloy + - --storage.path=/tmp/alloy + - --server.http.listen-addr=0.0.0.0:12345 + - --server.http.ui-path-prefix=/ + - --stability.level=generally-available + env: + - name: ALLOY_DEPLOY_MODE + value: "helm" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + ports: + - containerPort: 12345 + name: http-metrics + readinessProbe: + httpGet: + path: /-/ready + port: 12345 + scheme: HTTP + initialDelaySeconds: 10 + timeoutSeconds: 1 + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - CHOWN + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - SETGID + - SETUID + - SETPCAP + - NET_BIND_SERVICE + - NET_RAW + - SYS_CHROOT + - MKNOD + - AUDIT_WRITE + - SETFCAP + drop: + - ALL + seccompProfile: + type: RuntimeDefault + volumeMounts: + - name: config + mountPath: /etc/alloy + - name: varlog + mountPath: /var/log + readOnly: true + - name: dockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + - name: config-reloader + image: ghcr.io/jimmidyson/configmap-reload:v0.14.0 + args: + - --volume-dir=/etc/alloy + - --webhook-url=http://localhost:12345/-/reload + volumeMounts: + - name: config + mountPath: /etc/alloy + resources: + requests: + cpu: 1m + memory: 5Mi + dnsPolicy: ClusterFirst + nodeSelector: + kubernetes.io/os: linux + volumes: + - name: config + configMap: + name: k8smon-alloy-logs + - name: varlog + hostPath: + path: /var/log + - name: dockercontainers + hostPath: + path: /var/lib/docker/containers +--- +# Source: k8s-monitoring/charts/alloy-receiver/templates/controllers/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: k8smon-alloy-receiver + labels: + helm.sh/chart: alloy-receiver-0.11.0 + app.kubernetes.io/name: alloy-receiver + app.kubernetes.io/instance: k8smon + + app.kubernetes.io/version: "v1.6.1" + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy +spec: + replicas: 1 + minReadySeconds: 10 + selector: + matchLabels: + app.kubernetes.io/name: alloy-receiver + app.kubernetes.io/instance: k8smon + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: alloy + k8s.grafana.com/logs.job: integrations/alloy + labels: + app.kubernetes.io/name: alloy-receiver + app.kubernetes.io/instance: k8smon + spec: + serviceAccountName: k8smon-alloy-receiver + containers: + - name: alloy + image: docker.io/grafana/alloy:v1.6.1 + imagePullPolicy: IfNotPresent + args: + - run + - /etc/alloy/config.alloy + - --storage.path=/tmp/alloy + - --server.http.listen-addr=0.0.0.0:12345 + - --server.http.ui-path-prefix=/ + - --stability.level=generally-available + env: + - name: ALLOY_DEPLOY_MODE + value: "helm" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + ports: + - containerPort: 12345 + name: http-metrics + - containerPort: 4318 + name: otlp-http + protocol: TCP + - containerPort: 4317 + name: otlp-grpc + protocol: TCP + readinessProbe: + httpGet: + path: /-/ready + port: 12345 + scheme: HTTP + initialDelaySeconds: 10 + timeoutSeconds: 1 + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - CHOWN + - DAC_OVERRIDE + - FOWNER + - FSETID + - KILL + - SETGID + - SETUID + - SETPCAP + - NET_BIND_SERVICE + - NET_RAW + - SYS_CHROOT + - MKNOD + - AUDIT_WRITE + - SETFCAP + drop: + - ALL + seccompProfile: + type: RuntimeDefault + volumeMounts: + - name: config + mountPath: /etc/alloy + - name: config-reloader + image: ghcr.io/jimmidyson/configmap-reload:v0.14.0 + args: + - --volume-dir=/etc/alloy + - --webhook-url=http://localhost:12345/-/reload + volumeMounts: + - name: config + mountPath: /etc/alloy + resources: + requests: + cpu: 1m + memory: 5Mi + dnsPolicy: ClusterFirst + nodeSelector: + kubernetes.io/os: linux + volumes: + - name: config + configMap: + name: k8smon-alloy-receiver From d18722c2b7678bec907af48da9dfca256b6856e5 Mon Sep 17 00:00:00 2001 From: Robbie Lankford Date: Wed, 5 Feb 2025 14:42:41 -0800 Subject: [PATCH 4/6] yamllint fixes --- .../app-observability/deployments/otel-demo-manifest.yaml | 2 +- .../tests/platform/grafana-cloud/app-observability/values.yaml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/otel-demo-manifest.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/otel-demo-manifest.yaml index e73654e63..f9a786c41 100644 --- a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/otel-demo-manifest.yaml +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/otel-demo-manifest.yaml @@ -66,4 +66,4 @@ spec: enabled: false grafana: - enabled: false \ No newline at end of file + enabled: false diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/values.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/values.yaml index c67b4c75e..c032e230c 100644 --- a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/values.yaml +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/values.yaml @@ -70,4 +70,3 @@ alloy-receiver: port: 4317 targetPort: 4317 protocol: TCP - From 02a88ec4ee84b7eee5bdca416209cd1d57f2b853 Mon Sep 17 00:00:00 2001 From: Robbie Lankford Date: Wed, 5 Feb 2025 14:52:04 -0800 Subject: [PATCH 5/6] update .envrc --- .../tests/platform/grafana-cloud/app-observability/.envrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.envrc b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.envrc index 0c649be63..285ec8878 100644 --- a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.envrc +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/.envrc @@ -2,4 +2,4 @@ export GRAFANA_CLOUD_OTLP_USERNAME=$(op --account grafana.1password.com read "o export GRAFANA_CLOUD_METRICS_USERNAME=$(op --account grafana.1password.com read "op://Kubernetes Monitoring/helmchart Prometheus/username") export GRAFANA_CLOUD_LOGS_USERNAME=$(op --account grafana.1password.com read "op://Kubernetes Monitoring/helmchart Loki/username") export GRAFANA_CLOUD_RW_POLICY_TOKEN=$(op --account grafana.1password.com read "op://Kubernetes Monitoring/helmchart Loki/password") -export RANDOM_NUMBER=$(shuf -i 100000-999999 -n 1) \ No newline at end of file +export RANDOM_NUMBER=$(shuf -i 100000-999999 -n 1) From 082cd213c6fd180b4629e74974cd35bba3ab51de Mon Sep 17 00:00:00 2001 From: Robbie Lankford Date: Wed, 5 Feb 2025 15:10:47 -0800 Subject: [PATCH 6/6] fix query-test query --- .../grafana-cloud/app-observability/deployments/query-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/query-test.yaml b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/query-test.yaml index 192faa4c7..5d8e8212a 100644 --- a/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/query-test.yaml +++ b/charts/k8s-monitoring/tests/platform/grafana-cloud/app-observability/deployments/query-test.yaml @@ -35,5 +35,5 @@ spec: - configMapRef: {name: test-variables} queries: # otel demo services - - query: group by (telemetry_sdk_language, job) (traces_target_info{deployment_environment=~".*", cluster="$CLUSTER"}) + - query: group by (telemetry_sdk_language, job) (traces_target_info{deployment_environment=~".*", k8s_cluster_name="$CLUSTER"}) type: promql