Skip to content

Commit efb1734

Browse files
simonswinealsoba13
andauthored
feat: Helm support for v1/v2 storage (#4417)
* WIP: Helm support for v1/v2 * Make helm deployable again * Milestone: v2 micros-services works * Fix folders and search addressed to fix single-binary v2 * Update helm-docs to support ignored Also install it using go get instead docker * Build helm always without CGO * Introduce cluster label change when switching from single binary to micro-services Without that there is a chance the single binary instances are kept in the ring without being cleaned up. * Provide info about the migration in the NOTES * Add some WIP v2 migration docs for helm * Update migration guide * Upgrade helm-ci * Update image for super linter * Fix linting issues * Call helm-docs correctly * Fix lint check * Make superlinter work * Not too sure super linter brings any value * Apply suggestions from code review Co-authored-by: Alberto <[email protected]> * Apply suggestions from review everywhere --------- Co-authored-by: Alberto <[email protected]>
1 parent 7754cfc commit efb1734

21 files changed

+9550
-69
lines changed

.github/workflows/helm-ci.yml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,21 @@ on: pull_request
33
permissions:
44
contents: read
55
jobs:
6-
call-lint:
7-
uses: grafana/helm-charts/.github/workflows/linter.yml@main
8-
with:
9-
filter_regex_include: operations/pyroscope/helm/pyroscope/templates/.*
6+
# We used to import this from grafana/helm-charts/.github/workflows/linter.yml@main, but we want to update to later version of helm-docs.
7+
lint:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout code
11+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
12+
with:
13+
persist-credentials: false
14+
- name: Check Docs
15+
run: |
16+
make helm/docs
17+
if ! git diff --exit-code -- operations/pyroscope/helm/pyroscope/; then
18+
echo 'Documentation not up to date. Please run "make helm/docs" and commit changes!' >&2
19+
exit 1
20+
fi
1021
1122
call-lint-test:
1223
uses: grafana/helm-charts/.github/workflows/lint-test.yaml@main

Makefile

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ GO_MOD_PATHS := api/ lidia/ examples/language-sdk-instrumentation/golang-push/ri
4646
# Add extra arguments to helm commands
4747
HELM_ARGS =
4848

49+
HELM_FLAGS_V1 :=
50+
HELM_FLAGS_V1_MICROSERVICES := --set architecture.microservices.enabled=true --set minio.enabled=true
51+
HELM_FLAGS_V2 := --set architecture.storage.v1=false --set architecture.storage.v2=true
52+
HELM_FLAGS_V2_MICROSERVICES := $(HELM_FLAGS_V1_MICROSERVICES) $(HELM_FLAGS_V2)
53+
54+
4955
# Local deployment params
5056
KIND_CLUSTER = pyroscope-dev
5157

@@ -223,7 +229,9 @@ define deploy
223229
# Load image into nodes
224230
$(BIN)/kind load docker-image --name $(KIND_CLUSTER) $(IMAGE_PREFIX)pyroscope:$(IMAGE_TAG)
225231
kubectl get pods
226-
$(BIN)/helm upgrade --install $(1) ./operations/pyroscope/helm/pyroscope $(2) $(HELM_ARGS) \
232+
$(BIN)/helm upgrade --install pyroscope ./operations/pyroscope/helm/pyroscope $(2) $(HELM_ARGS) \
233+
--set architecture.deployUnifiedServices=true \
234+
--set architecture.overwriteResources.requests.cpu=10m \
227235
--set pyroscope.image.tag=$(IMAGE_TAG) \
228236
--set pyroscope.image.repository=$(IMAGE_PREFIX)pyroscope \
229237
--set pyroscope.podAnnotations.image-digest=$(shell cat .docker-image-digest-pyroscope) \
@@ -280,7 +288,8 @@ docker-image/pyroscope/push-debug: frontend/build go/bin-debug docker-image/pyro
280288
$(call docker_buildx,--push,debug.)
281289

282290
.PHONY: docker-image/pyroscope/build
283-
docker-image/pyroscope/build: frontend/build go/bin
291+
docker-image/pyroscope/build: frontend/build
292+
GOOS=linux $(MAKE) go/bin
284293
$(call docker_buildx,--load --iidfile .docker-image-digest-pyroscope,)
285294

286295
.PHONY: docker-image/pyroscope/push
@@ -356,7 +365,7 @@ $(BIN)/jb: Makefile go.mod
356365

357366
$(BIN)/helm: Makefile go.mod
358367
@mkdir -p $(@D)
359-
GOBIN=$(abspath $(@D)) $(GO) install helm.sh/helm/v3/cmd/[email protected]
368+
CGO_ENABLED=0 GOBIN=$(abspath $(@D)) $(GO) install helm.sh/helm/v3/cmd/[email protected]
360369

361370
$(BIN)/kubeconform: Makefile go.mod
362371
@mkdir -p $(@D)
@@ -379,6 +388,10 @@ $(BIN)/gotestsum: Makefile go.mod
379388
@mkdir -p $(@D)
380389
GOBIN=$(abspath $(@D)) $(GO) install gotest.tools/[email protected]
381390

391+
$(BIN)/helm-docs: Makefile go.mod
392+
@mkdir -p $(@D)
393+
GOBIN=$(abspath $(@D)) $(GO) install github.com/norwoodj/helm-docs/cmd/[email protected]
394+
382395
.PHONY: cve/check
383396
cve/check:
384397
docker run -t -i --rm --volume "$(CURDIR)/:/repo" -u "$(shell id -u)" aquasec/trivy:0.45.1 filesystem --cache-dir /repo/.cache/trivy --scanners vuln --skip-dirs .tmp/ --skip-dirs node_modules/ --skip-dirs tools/monitoring/vendor/ /repo
@@ -388,8 +401,8 @@ helm/lint: $(BIN)/helm
388401
$(BIN)/helm lint ./operations/pyroscope/helm/pyroscope/
389402

390403
.PHONY: helm/docs
391-
helm/docs: $(BIN)/helm
392-
docker run --rm --volume "$(CURDIR)/operations/pyroscope/helm:/helm-docs" -u "$(shell id -u)" jnorwood/helm-docs:v1.8.1
404+
helm/docs: $(BIN)/helm-docs
405+
$(BIN)/helm-docs -c operations/pyroscope/helm/pyroscope
393406

394407
.PHONY: goreleaser/lint
395408
goreleaser/lint: $(BIN)/goreleaser
@@ -402,14 +415,23 @@ helm/check: $(BIN)/kubeconform $(BIN)/helm
402415
$(BIN)/helm dependency update ./operations/pyroscope/helm/pyroscope/
403416
$(BIN)/helm dependency build ./operations/pyroscope/helm/pyroscope/
404417
mkdir -p ./operations/pyroscope/helm/pyroscope/rendered/
405-
$(BIN)/helm template -n default --kube-version "1.23.0" pyroscope-dev ./operations/pyroscope/helm/pyroscope/ \
418+
$(BIN)/helm template -n default --kube-version "1.23.0" pyroscope-dev ./operations/pyroscope/helm/pyroscope/ $(HELM_FLAGS_V1) \
406419
| tee ./operations/pyroscope/helm/pyroscope/rendered/single-binary.yaml \
407420
| $(BIN)/kubeconform --summary --strict --kubernetes-version 1.23.0
408-
$(BIN)/helm template -n default --kube-version "1.23.0" pyroscope-dev ./operations/pyroscope/helm/pyroscope/ --values operations/pyroscope/helm/pyroscope/values-micro-services.yaml \
421+
$(BIN)/helm template -n default --kube-version "1.23.0" pyroscope-dev ./operations/pyroscope/helm/pyroscope/ $(HELM_FLAGS_V2) \
422+
| tee ./operations/pyroscope/helm/pyroscope/rendered/single-binary-v2.yaml \
423+
| $(BIN)/kubeconform --summary --strict --kubernetes-version 1.23.0
424+
$(BIN)/helm template -n default --kube-version "1.23.0" pyroscope-dev ./operations/pyroscope/helm/pyroscope/ $(HELM_FLAGS_V1_MICROSERVICES) \
409425
| tee ./operations/pyroscope/helm/pyroscope/rendered/micro-services.yaml \
410426
| $(BIN)/kubeconform --summary --strict --kubernetes-version 1.23.0
427+
$(BIN)/helm template -n default --kube-version "1.23.0" pyroscope-dev ./operations/pyroscope/helm/pyroscope/ $(HELM_FLAGS_V2_MICROSERVICES) \
428+
| tee ./operations/pyroscope/helm/pyroscope/rendered/micro-services-v2.yaml \
429+
| $(BIN)/kubeconform --summary --strict --kubernetes-version 1.23.0
430+
$(BIN)/helm template -n default --kube-version "1.23.0" pyroscope-dev ./operations/pyroscope/helm/pyroscope/ --values operations/pyroscope/helm/pyroscope/values-micro-services.yaml \
431+
| tee ./operations/pyroscope/helm/pyroscope/rendered/legacy-micro-services.yaml \
432+
| $(BIN)/kubeconform --summary --strict --kubernetes-version 1.23.0
411433
$(BIN)/helm template -n default --kube-version "1.23.0" pyroscope-dev ./operations/pyroscope/helm/pyroscope/ --values operations/pyroscope/helm/pyroscope/values-micro-services-hpa.yaml \
412-
| tee ./operations/pyroscope/helm/pyroscope/rendered/micro-services-hpa.yaml \
434+
| tee ./operations/pyroscope/helm/pyroscope/rendered/legacy-micro-services-hpa.yaml \
413435
| $(BIN)/kubeconform --summary --strict --kubernetes-version 1.23.0
414436
cat operations/pyroscope/helm/pyroscope/values-micro-services.yaml \
415437
| go run ./tools/yaml-to-json \
@@ -423,15 +445,19 @@ helm/check: $(BIN)/kubeconform $(BIN)/helm
423445

424446
.PHONY: deploy
425447
deploy: $(BIN)/kind $(BIN)/helm docker-image/pyroscope/build
426-
$(call deploy,pyroscope-dev,)
427-
# Create a service to provide the same endpoint as micro-services
428-
echo '{"kind":"Service","apiVersion":"v1","metadata":{"name":"pyroscope-micro-services-query-frontend"},"spec":{"ports":[{"name":"pyroscope","port":4040,"targetPort":4040}],"selector":{"app.kubernetes.io/component":"all","app.kubernetes.io/instance":"pyroscope-dev"},"type":"ClusterIP"}}' | kubectl apply -f -
448+
$(call deploy,pyroscope-dev,$(HELM_FLAGS_V2))
449+
450+
.PHONY: deploy-v1
451+
deploy-v1: $(BIN)/kind $(BIN)/helm docker-image/pyroscope/build
452+
$(call deploy,pyroscope-dev,$(HELM_FLAGS_V1))
429453

430454
.PHONY: deploy-micro-services
431455
deploy-micro-services: $(BIN)/kind $(BIN)/helm docker-image/pyroscope/build
432-
# Ensure to delete existing service, that has been created manually by the deploy target
433-
kubectl delete svc --field-selector metadata.name=pyroscope-micro-services-query-frontend -l app.kubernetes.io/managed-by!=Helm || true
434-
$(call deploy,pyroscope-micro-services,--values=operations/pyroscope/helm/pyroscope/values-micro-services.yaml --set pyroscope.components.querier.resources=null --set pyroscope.components.distributor.resources=null --set pyroscope.components.ingester.resources=null --set pyroscope.components.store-gateway.resources=null --set pyroscope.components.compactor.resources=null)
456+
$(call deploy,pyroscope-micro-services,$(HELM_FLAGS_V2_MICROSERVICES))
457+
458+
.PHONY: deploy-micro-services-v1
459+
deploy-micro-services-v1: $(BIN)/kind $(BIN)/helm docker-image/pyroscope/build
460+
$(call deploy,pyroscope-micro-services,$(HELM_FLAGS_V1_MICROSERVICES))
435461

436462
.PHONY: deploy-monitoring
437463
deploy-monitoring: $(BIN)/tk $(BIN)/kind tools/monitoring/environments/default/spec.json

cmd/pyroscope/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ VOLUME /data
1616
COPY --chown=pyroscope:pyroscope --from=debug /data /data
1717
VOLUME /data-compactor
1818
COPY --chown=pyroscope:pyroscope --from=debug /data /data-compactor
19+
VOLUME /data-metastore
20+
COPY --chown=pyroscope:pyroscope --from=debug /data /data-metastore
1921

2022
COPY cmd/pyroscope/pyroscope.yaml /etc/pyroscope/config.yaml
2123
COPY profilecli /usr/bin/profilecli

cmd/pyroscope/debug.Dockerfile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ RUN addgroup -g 10001 -S pyroscope && \
77

88
# This folder is created by adduser command with right owner/group
99
VOLUME /data
10-
11-
# This folder needs to be created and set to the right owner/group
1210
VOLUME /data-compactor
13-
RUN mkdir -p /data-compactor && chown pyroscope:pyroscope /data /data-compactor
11+
VOLUME /data-metastore
12+
RUN chown pyroscope:pyroscope /data /data-compactor /data-metastore
1413

1514
COPY .tmp/bin/dlv /usr/bin/dlv
1615
COPY cmd/pyroscope/pyroscope.yaml /etc/pyroscope/config.yaml

docs/internal/V2-MIGRATION.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Migration v1 to v2
2+
3+
## Single binary
4+
5+
### First deploy v1
6+
7+
- Note: Needs persistence enabled otherwise data will be lost after restart
8+
9+
```
10+
helm upgrade \
11+
pyroscope \
12+
./operations/pyroscope/helm/pyroscope \
13+
--install \
14+
--set architecture.storage.v1=true \
15+
--set architecture.storage.v2=false \
16+
--set pyroscope.persistence.enabled=true
17+
```
18+
19+
### Step: 2: Deploy v2 and enable dual ingest
20+
21+
- Note: The python command will switch to the v2 read path for data ingested 10 minutes after it is run.
22+
23+
```
24+
helm upgrade \
25+
pyroscope \
26+
./operations/pyroscope/helm/pyroscope \
27+
--set architecture.storage.v1=true \
28+
--set architecture.storage.v2=true \
29+
--set pyroscope.persistence.enabled=true \
30+
--set architecture.storage.migration.queryBackendFrom=$(python3 -c "import datetime; print((datetime.datetime.now(datetime.UTC)+ datetime.timedelta(minutes = 10)).strftime('%Y-%m-%dT%H:%M:%SZ'))")
31+
```
32+
33+
### Step 3: Remove v1 components
34+
35+
Once data before Step 2 is no longer relevant, we can get rid of the v1 components. This will loose all data before Step 2.
36+
37+
```
38+
helm upgrade \
39+
pyroscope \
40+
./operations/pyroscope/helm/pyroscope \
41+
--set architecture.storage.v1=false \
42+
--set architecture.storage.v2=true \
43+
--set pyroscope.persistence.enabled=true
44+
```
45+
46+
47+
## Micro-Services
48+
49+
### First deploy v1
50+
51+
- Note: Needs persistence enabled otherwise data will be lost after restart
52+
- Note: `--set architecture.overwriteResources.requests.cpu=10m` allow this to be tested without allocation many resources, this should not be used in production
53+
54+
55+
```
56+
helm upgrade \
57+
pyroscope \
58+
./operations/pyroscope/helm/pyroscope \
59+
--install \
60+
--set architecture.microservices.enabled=true \
61+
--set architecture.overwriteResources.requests.cpu=10m \
62+
--set minio.enabled=true \
63+
--set architecture.storage.v1=true \
64+
--set architecture.storage.v2=false \
65+
--set pyroscope.persistence.enabled=true
66+
```
67+
68+
### Step: 2: Deploy v2 and enable dual ingest
69+
70+
- Note: The python command will switch to the v2 read path for data ingested 10 minutes after it is run.
71+
72+
```
73+
helm upgrade \
74+
pyroscope \
75+
./operations/pyroscope/helm/pyroscope \
76+
--set architecture.microservices.enabled=true \
77+
--set architecture.overwriteResources.requests.cpu=10m \
78+
--set minio.enabled=true \
79+
--set architecture.storage.v1=true \
80+
--set architecture.storage.v2=true \
81+
--set pyroscope.persistence.enabled=true \
82+
--set architecture.storage.migration.queryBackendFrom=$(python3 -c "import datetime; print((datetime.datetime.now(datetime.UTC)+ datetime.timedelta(minutes = 10)).strftime('%Y-%m-%dT%H:%M:%SZ'))")
83+
```
84+
85+
86+
### Step 3: Remove v1 components
87+
88+
Once data before Step 2 is no longer relevant, we can get rid of the v1 components. This will loose all data before Step 2.
89+
90+
```
91+
helm upgrade \
92+
pyroscope \
93+
./operations/pyroscope/helm/pyroscope \
94+
--set architecture.microservices.enabled=true \
95+
--set minio.enabled=true \
96+
--set architecture.storage.v1=false \
97+
--set architecture.storage.v2=true \
98+
--set pyroscope.persistence.enabled=true
99+

operations/pyroscope/helm/pyroscope/README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@
2525
|-----|------|---------|-------------|
2626
| agent | object | `{"agent":{"clustering":{"enabled":true},"configMap":{"create":false,"name":"grafana-agent-config-pyroscope"}},"controller":{"podAnnotations":{"profiles.grafana.com/cpu.port_name":"http-metrics","profiles.grafana.com/cpu.scrape":"true","profiles.grafana.com/goroutine.port_name":"http-metrics","profiles.grafana.com/goroutine.scrape":"true","profiles.grafana.com/memory.port_name":"http-metrics","profiles.grafana.com/memory.scrape":"true"},"replicas":1,"type":"statefulset"},"enabled":false}` | ----------------------------------- |
2727
| alloy | object | `{"alloy":{"clustering":{"enabled":true},"configMap":{"create":false,"name":"alloy-config-pyroscope"},"stabilityLevel":"public-preview"},"controller":{"podAnnotations":{"profiles.grafana.com/cpu.port_name":"http-metrics","profiles.grafana.com/cpu.scrape":"true","profiles.grafana.com/goroutine.port_name":"http-metrics","profiles.grafana.com/goroutine.scrape":"true","profiles.grafana.com/memory.port_name":"http-metrics","profiles.grafana.com/memory.scrape":"true","profiles.grafana.com/service_git_ref":"v1.8.1","profiles.grafana.com/service_repository":"https://github.com/grafana/alloy"},"replicas":1,"type":"statefulset"},"enabled":true}` | ----------------------------------- |
28+
| architecture.deployUnifiedServices | bool | `false` | Deploy unified write/read services. These endpoints will can be used no matter if the helm chart is configured as single-binary or microservices |
29+
| architecture.microservices.clusterLabelSuffix | string | `"-micro-services"` | Memberlist cluster label that will be used for all members of this cluster |
30+
| architecture.microservices.enabled | bool | `false` | Enable micro-services deployment mode. This is recommend for larger scale deployment and allow right size each aspect of Pyroscope. |
31+
| architecture.overwriteResources | object | `{}` | This flag is useful for testing, it will overwrite all pods resource statements with its contents |
32+
| architecture.storage.migration.ingesterWeight | float | `1` | Specifies the fraction [0:1] that should be send to the v1 write path / ingester in combined mode. 0 means no traffics is sent to ingester. 1 means 100% of requests are sent to ingester. |
33+
| architecture.storage.migration.queryBackend | bool | `true` | Specify a time stamp from when the v2 read path should serve traffic. |
34+
| architecture.storage.migration.queryBackendFrom | string | `"auto"` | Specify a time stamp from when the v2 read path should serve traffic. |
35+
| architecture.storage.migration.segmentWriterWeight | float | `1` | Specifies the fraction [0:1] that should be send to the v2 write path / segment-writer in combined mode. 0 means no traffics is sent to segment-writer. 1 means 100% of requests are sent to segment-writer. |
36+
| architecture.storage.v1 | bool | `true` | Enable v1 storage layer. |
37+
| architecture.storage.v2 | bool | `false` | Enable v2 storage layer. |
2838
| ingress.annotations | object | `{}` | |
2939
| ingress.className | string | `""` | |
3040
| ingress.enabled | bool | `false` | |
@@ -45,13 +55,17 @@
4555
| pyroscope.extraVolumeMounts | list | `[]` | |
4656
| pyroscope.extraVolumes | list | `[]` | |
4757
| pyroscope.fullnameOverride | string | `""` | |
58+
| pyroscope.grpc.port | int | `9095` | |
59+
| pyroscope.grpc.port_name | string | `"grpc"` | |
4860
| pyroscope.image.pullPolicy | string | `"IfNotPresent"` | |
4961
| pyroscope.image.repository | string | `"grafana/pyroscope"` | |
5062
| pyroscope.image.tag | string | `""` | |
5163
| pyroscope.imagePullSecrets | list | `[]` | |
5264
| pyroscope.initContainers | list | `[]` | |
5365
| pyroscope.memberlist.port | int | `7946` | |
5466
| pyroscope.memberlist.port_name | string | `"memberlist"` | |
67+
| pyroscope.metastore.port | int | `9099` | |
68+
| pyroscope.metastore.port_name | string | `"raft"` | |
5569
| pyroscope.nameOverride | string | `""` | |
5670
| pyroscope.nodeSelector | object | `{}` | |
5771
| pyroscope.persistence.accessModes[0] | string | `"ReadWriteOnce"` | |
@@ -97,5 +111,3 @@
97111
| serviceMonitor.targetLabels | list | `[]` | ServiceMonitor will add labels from the service to the Prometheus metric https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitorspec |
98112
| serviceMonitor.tlsConfig | string | `nil` | ServiceMonitor will use these tlsConfig settings to make the health check requests |
99113

100-
----------------------------------------------
101-
Autogenerated from chart metadata using [helm-docs v1.8.1](https://github.com/norwoodj/helm-docs/releases/v1.8.1)

0 commit comments

Comments
 (0)