From 407ffdc35f91c220e3ebd3514e5682d3eefb31f1 Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Fri, 19 Jun 2026 11:55:28 +0530 Subject: [PATCH 1/7] helm: release pai chart 0.3.0 --- helm-releases/pai-0.3.0.tgz | Bin 0 -> 6423 bytes index.yaml | 194 ++++++++++++++++++++---------------- 2 files changed, 106 insertions(+), 88 deletions(-) create mode 100644 helm-releases/pai-0.3.0.tgz diff --git a/helm-releases/pai-0.3.0.tgz b/helm-releases/pai-0.3.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..67d6bc9b9728a1480742512dc1af73440280a0ad GIT binary patch literal 6423 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 Date: Thu, 9 Jul 2026 03:56:13 +0530 Subject: [PATCH 2/7] helm: simplify chart with common/per-node values --- helm/Chart.lock | 9 - helm/Chart.yaml | 13 +- helm/README.md | 40 +- helm/charts/fluent-bit-0.48.1.tgz | Bin 14818 -> 0 bytes helm/charts/vector-0.20.1.tgz | Bin 28013 -> 0 bytes helm/templates/_helpers_config_logstream.txt | 52 -- helm/templates/data-pvc.yaml | 13 +- helm/templates/ingestor-service.yaml | 11 +- helm/templates/ingestor-statefulset.yaml | 239 ++++--- helm/templates/logstream-configmap.yaml | 12 - helm/templates/logstream-job.yaml | 65 -- helm/templates/querier-service.yaml | 9 +- helm/templates/querier-statefulset.yaml | 260 +++----- helm/templates/service-monitor.yaml | 69 -- helm/templates/stage-pvc.yaml | 13 +- helm/templates/standalone-deployment.yaml | 166 ++--- helm/templates/standalone-service.yaml | 9 +- helm/values-aws.yaml | 33 + helm/values-azure.yaml | 32 + helm/values-gcp.yaml | 37 ++ helm/values.yaml | 638 +++---------------- 21 files changed, 532 insertions(+), 1188 deletions(-) delete mode 100644 helm/Chart.lock delete mode 100644 helm/charts/fluent-bit-0.48.1.tgz delete mode 100644 helm/charts/vector-0.20.1.tgz delete mode 100644 helm/templates/_helpers_config_logstream.txt delete mode 100644 helm/templates/logstream-configmap.yaml delete mode 100644 helm/templates/logstream-job.yaml delete mode 100644 helm/templates/service-monitor.yaml create mode 100644 helm/values-aws.yaml create mode 100644 helm/values-azure.yaml create mode 100644 helm/values-gcp.yaml diff --git a/helm/Chart.lock b/helm/Chart.lock deleted file mode 100644 index 10b0b8ce1..000000000 --- a/helm/Chart.lock +++ /dev/null @@ -1,9 +0,0 @@ -dependencies: -- name: vector - repository: https://helm.vector.dev - version: 0.20.1 -- name: fluent-bit - repository: https://fluent.github.io/helm-charts - version: 0.25.0 -digest: sha256:5657989e00b94e31ddcb44d0c925f8d30849c46851879a27708b50cd1af6ee33 -generated: "2023-04-24T18:46:09.186176+05:30" diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 296b7c1cf..b3861fdca 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: parseable description: Helm chart for Parseable OSS version. Columnar data lake platform - purpose built for observability type: application -version: 2.8.2 +version: 3.0.0 appVersion: "v2.8.0" icon: "https://raw.githubusercontent.com/parseablehq/.github/main/images/logo.svg" @@ -10,14 +10,3 @@ maintainers: - name: Parseable Team email: hi@parseable.com url: https://parseable.com - -dependencies: -- name: vector - version: 0.20.1 - repository: https://helm.vector.dev - condition: vector.enabled -- name: fluent-bit - version: 0.48.0 - repository: https://fluent.github.io/helm-charts - condition: fluent-bit.enabled - \ No newline at end of file diff --git a/helm/README.md b/helm/README.md index e74171073..5645016dd 100644 --- a/helm/README.md +++ b/helm/README.md @@ -1,3 +1,41 @@ # Parseable Helm Chart -Refer the Parseable Helm Chart [documentation ↗︎](https://www.parseable.io/docs/installation/kubernetes-helm) +## Install (standalone, local-store) + +```sh +kubectl create secret generic parseable-env-secret \ + --from-literal=addr=0.0.0.0:8000 \ + --from-literal=username=admin \ + --from-literal=password=admin \ + --from-literal=staging.dir=/parseable/staging \ + --from-literal=fs.dir=/parseable/data + +helm install parseable ./ -n parseable --create-namespace +``` + +## Distributed on a cloud (querier + ingestors) + +Create the secret with the keys for your cloud (see the matching values file), then: + +```sh +# AWS (S3) +helm install parseable ./ -n parseable --create-namespace -f values-aws.yaml + +# GCP (GCS) +helm install parseable ./ -n parseable --create-namespace -f values-gcp.yaml + +# Azure (Blob) +helm install parseable ./ -n parseable --create-namespace -f values-azure.yaml +``` + +## Upgrade + +```sh +helm upgrade parseable ./ -n parseable -f values.yaml +``` + +## Uninstall + +```sh +helm uninstall parseable -n parseable +``` diff --git a/helm/charts/fluent-bit-0.48.1.tgz b/helm/charts/fluent-bit-0.48.1.tgz deleted file mode 100644 index cd471f64558ff577137a83732f35e2829ad20afb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14818 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 I7yzCD0B_qDRR910 diff --git a/helm/charts/vector-0.20.1.tgz b/helm/charts/vector-0.20.1.tgz deleted file mode 100644 index 349a449b9052e5084ec14cfefcd99a01d5bbb78e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28013 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¥?!~ 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 "_" + secrets: + name: parseable-env-secret + prefix: P_ + keys: + - addr + - username + - password + - staging.dir + - fs.dir + + # file credential (e.g. GCS key.json); sets GOOGLE_APPLICATION_CREDENTIALS + credentialFile: enabled: false - image: - repository: busybox - tag: latest - pullPolicy: IfNotPresent - command: [] - args: [] + secretName: parseable-env-secret + secretKey: key.json + mountPath: /var/secrets/google + + auditLogging: + enabled: false + p_server: "" + p_username: "" + p_password: "" + + # defaults for every node; a node under nodes: can override any of these + common: env: RUST_LOG: warn - ports: 8000 - volumeMounts: - - name: test-volume - mountPath: /parseable/test - volumeClaimTemplates: - - metadata: - name: test-volume - spec: - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: 1Gi resources: limits: cpu: 500m @@ -200,367 +55,66 @@ parseable: requests: cpu: 250m memory: 1Gi - securityContext: - allowPrivilegeEscalation: false - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "80" - prometheus.io/path: "/api/v1/metrics" - podSecurityContext: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 - fsGroupChangePolicy: "Always" - nameOverride: "" - fullnameOverride: "" - podLabels: - app: parseable - component: query - ## Use this section to create ServiceMonitor object for - ## this Parseable deployment. Read more on ServiceMonitor - ## here: https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1.ServiceMonitor - metrics: - serviceMonitor: - enabled: false - labels: {} - namespace: "" - spec: - jobLabel: "" - targetLabels: [] - podTargetLabels: [] - endpoints: [] - selector: {} - namespaceSelector: {} - sampleLimit: 0 - scrapeProtocols: [] - targetLimit: 0 - labelLimit: 0 - labelNameLengthLimit: 0 - labelValueLengthLimit: 0 - keepDroppedTargets: 0 - attachMetadata: {} - scrapeClass: "" - bodySizeLimit: {} - kafkaConnector: - enabled: false - env: - # General Kafka Configuration - P_KAFKA_BOOTSTRAP_SERVERS: "my-kafka.kafka.svc.cluster.local:9092" # Comma-separated list of Kafka bootstrap servers - P_KAFKA_PARTITION_LISTENER_CONCURRENCY: "2" # Number of parallel threads for Kafka partition listeners - P_KAFKA_CONSUMER_TOPICS: "test-log-stream-0,test-log-stream-1" - # P_KAFKA_CLIENT_ID: "parseable-connect" # Client ID for Kafka connection - # P_CONNECTOR_BAD_DATA_POLICY: "fail" # Default Policy for handling bad data - - # Consumer Configurations. These config are Default Parseable KafkaConnector configs. Change only if necessary. - # P_KAFKA_CONSUMER_GROUP_ID: "parseable-connect-cg" - # P_KAFKA_CONSUMER_BUFFER_SIZE: "10000" - # P_KAFKA_CONSUMER_BUFFER_TIMEOUT: "10000ms" - # P_KAFKA_CONSUMER_SESSION_TIMEOUT: "60000" - # P_KAFKA_CONSUMER_HEARTBEAT_INTERVAL: "3000" - # P_KAFKA_CONSUMER_PARTITION_STRATEGY: "roundrobin,range" - # P_KAFKA_CONSUMER_MAX_POLL_INTERVAL: "300000" - # P_KAFKA_CONSUMER_ENABLE_AUTO_OFFSET_STORE: "true" - # P_KAFKA_CONSUMER_AUTO_OFFSET_RESET: "earliest" - # P_KAFKA_CONSUMER_FETCH_MIN_BYTES: "1" - # P_KAFKA_CONSUMER_FETCH_MAX_BYTES: "52428800" - # P_KAFKA_CONSUMER_FETCH_MAX_WAIT: "500" - # P_KAFKA_CONSUMER_MAX_PARTITION_FETCH_BYTES: "1048576" - # P_KAFKA_CONSUMER_QUEUED_MIN_MESSAGES: "100000" - # P_KAFKA_CONSUMER_QUEUED_MAX_MESSAGES_KBYTES: "65536" - # P_KAFKA_CONSUMER_ENABLE_PARTITION_EOF: "false" - # P_KAFKA_CONSUMER_CHECK_CRCS: "false" - # P_KAFKA_CONSUMER_ISOLATION_LEVEL: "read_committed" - # P_KAFKA_CONSUMER_FETCH_MESSAGE_MAX_BYTES: "1048576" - # P_KAFKA_CONSUMER_STATS_INTERVAL: "10000" - - # Security Configuration Options - By Default PLAINTEXT - - # Option 1: SSL Encryption Only - # P_KAFKA_SECURITY_PROTOCOL: "SSL" - # P_KAFKA_SSL_CA_LOCATION: "/etc/ssl/certs/ca-certificates.crt" - # P_KAFKA_SSL_CERTIFICATE_LOCATION: "/etc/ssl/certs/client-cert.pem" - # P_KAFKA_SSL_KEY_LOCATION: "/etc/ssl/private/client-key.pem" - # P_KAFKA_SSL_KEY_PASSWORD: "my-key-password" # Optional: only if key is password protected - - # Option 2: SASL Authentication with SSL Encryption - # P_KAFKA_SECURITY_PROTOCOL: "SASL_SSL" - # P_KAFKA_SSL_CA_LOCATION: "/etc/ssl/certs/ca-certificates.crt" - # P_KAFKA_SASL_MECHANISM: "SCRAM-SHA-512" # Can also be PLAIN, SCRAM-SHA-256, or GSSAPI - # P_KAFKA_SASL_USERNAME: "kafka-user" - # P_KAFKA_SASL_PASSWORD: "kafka-password" - - # Option 3: SASL Authentication without Encryption - # P_KAFKA_SECURITY_PROTOCOL: "SASL_PLAINTEXT" - # P_KAFKA_SASL_MECHANISM: "PLAIN" # Can also be SCRAM-SHA-256, SCRAM-SHA-512, or GSSAPI - # P_KAFKA_SASL_USERNAME: "kafka-user" - # P_KAFKA_SASL_PASSWORD: "kafka-password" - - # Option 4: OAuth Bearer Token Authentication (Not supported yet) - # P_KAFKA_SECURITY_PROTOCOL: "SASL_SSL" - # P_KAFKA_SASL_MECHANISM: "OAUTHBEARER" - # P_KAFKA_OAUTH_TOKEN_ENDPOINT: "https://oauth.example.com/token" - # P_KAFKA_OAUTH_CLIENT_ID: "kafka-client" - # P_KAFKA_OAUTH_CLIENT_SECRET: "client-secret" - # P_KAFKA_OAUTH_SCOPE: "kafka-access" # Optional: only if required by OAuth provider - -## Default values for Vector -# See Vector helm documentation to learn more: -# https://vector.dev/docs/setup/installation/package-managers/helm/ -vector: - enabled: false - role: "Agent" - rollWorkload: true - image: - repository: timberio/vector - pullPolicy: IfNotPresent - pullSecrets: [] - tag: "" - sha: "" - replicas: 1 - podManagementPolicy: OrderedReady - podDisruptionBudget: - enabled: false - minAvailable: 1 - maxUnavailable: - rbac: - create: true - serviceAccount: - create: true - annotations: {} - name: - automountToken: true - podLabels: - vector.dev/exclude: "true" - args: - - --config-dir - - "/etc/vector/" - terminationGracePeriodSeconds: 60 - service: - enabled: true - type: "ClusterIP" - annotations: {} - topologyKeys: [] - ports: [] - externalTrafficPolicy: "" - loadBalancerIP: "" - ipFamilyPolicy: "" - ipFamilies: [] - serviceHeadless: - enabled: true - dnsPolicy: ClusterFirst - customConfig: - data_dir: /vector-data-dir - api: - enabled: true - address: 127.0.0.1:8686 - playground: false - sources: - kubernetes_logs: - type: kubernetes_logs - sinks: - parseable: - type: http - method: post - batch: - max_bytes: 10485760 - max_events: 1000 - timeout_secs: 10 - compression: gzip - inputs: - - kubernetes_logs - encoding: - codec: json - uri: "http://parseable.parseable.svc.cluster.local/api/v1/ingest" - auth: - strategy: basic - user: admin - password: admin - request: - headers: - X-P-Stream: vectordemo - healthcheck: + readinessProbe: + httpGet: + path: /api/v1/readiness + port: 8000 + securityContext: + allowPrivilegeEscalation: false + podSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: "Always" + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "80" + prometheus.io/path: "/api/v1/metrics" + podLabels: {} + nodeSelector: {} + tolerations: [] + affinity: {} + + # per-node overrides; env is merged with common (node wins), rest replaces + nodes: + standalone: + env: {} + service: + type: ClusterIP + port: 80 + persistence: + staging: enabled: true - path: "http://parseable.parseable.svc.cluster.local/api/v1/liveness" - port: 80 - -# Default values for fluent-bit. -# See fluent-bit helm documentation to learn more: -# https://github.com/fluent/helm-charts/tree/main/charts/fluent-bit -fluent-bit: - enabled: false - kind: DaemonSet - serverHost: parseable-ingestor-service.parseable.svc.cluster.local - serverUsername: admin - serverPassword: admin - serverStream: $NAMESPACE - excludeNamespaces: kube-system, default - replicaCount: 1 - image: - repository: parseable/fluent-bit - tag: "v2" - pullPolicy: Always - testFramework: - enabled: true - image: - repository: busybox - pullPolicy: Always - tag: latest - serviceAccount: - create: true - annotations: {} - name: - rbac: - create: true - nodeAccess: false - eventsAccess: true - dnsPolicy: ClusterFirst - service: - type: ClusterIP - port: 2020 - loadBalancerClass: - loadBalancerSourceRanges: [] - labels: {} - livenessProbe: - httpGet: - path: / - port: http - readinessProbe: - httpGet: - path: /api/v1/health - port: http - flush: 1 - metricsPort: 2020 - ## https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/classic-mode/configuration-file - config: - service: | - [SERVICE] - Daemon Off - Flush {{ .Values.flush }} - Log_Level {{ .Values.logLevel }} - Parsers_File parsers.conf - Parsers_File custom_parsers.conf - HTTP_Server On - HTTP_Listen 0.0.0.0 - HTTP_Port {{ .Values.metricsPort }} - Health_Check On - - ## https://docs.fluentbit.io/manual/pipeline/inputs - inputs: | - [INPUT] - Name tail - Path /var/log/containers/*.log - multiline.parser docker, cri - Tag kube.* - Mem_Buf_Limit 5MB - Skip_Long_Lines On - - # [INPUT] - # Name tail - # Path /var/log/containers/{NGINX_POD_NAME}-*.log - # Parser nginx_access - # Tag kube.* - # Mem_Buf_Limit 5MB - # Skip_Long_Lines On - - # [INPUT] - # Name tail - # Path /var/log/containers/{NGINX_POD_NAME}-*.log - # Parser nginx_error - # Tag kube.* - # Mem_Buf_Limit 5MB - # Skip_Long_Lines On - - [INPUT] - name kubernetes_events - tag k8s_events - - [INPUT] - Name systemd - Tag host.* - Systemd_Filter _SYSTEMD_UNIT=kubelet.service - Read_From_Tail On - - ## https://docs.fluentbit.io/manual/pipeline/filters - filters: | - [FILTER] - Name kubernetes - Match kube.* - Merge_Log On - Keep_Log Off - K8S-Logging.Parser On - K8S-Logging.Exclude On - - ## https://docs.fluentbit.io/manual/pipeline/outputs - outputs: | - [OUTPUT] - Name parseable - Match kube.* - Server_Host {{ .Values.serverHost }} - Username {{ .Values.serverUsername }} - Password {{ .Values.serverPassword }} - Server_Port 80 - Stream {{ .Values.serverStream }} - Exclude_Namespaces {{ .Values.excludeNamespaces }} - - [OUTPUT] - Name parseable - Match k8s_events - Server_Host {{ .Values.serverHost }} - Server_Port 80 - Username {{ .Values.serverUsername }} - Password {{ .Values.serverPassword }} - Stream k8s-events - - upstream: {} - - customParsers: | - [PARSER] - Name docker_no_time - Format json - Time_Keep Off - Time_Key time - Time_Format %Y-%m-%dT%H:%M:%S.%L - - # [PARSER] - # Name nginx_error - # Format regex - # Regex ^(?\S+Z) stderr F (?\S+ \S+) \[(?\S+)\] (?\d+#\d+): \*(?\d+) (?.*?) client: (?\S+), server: (?\S+), request: "(?\S+) (?\S+) HTTP/\S+", upstream: "(?[^"]+)", host: "(?\S+)"$ - # Time_Key timestamp - # Time_Format %Y/%m/%d %H:%M:%S - - # [PARSER] - # Name nginx_access - # Format regex - # Regex (?[^ ]*) - (?[^ ]*) \[(?[^\]]*)\] "(?\S+)(?: +(?[^\"]*?)(?: +\S*)?)?" (?[^ ]*) (?[^ ]*) "(?[^\"]*)" "(?[^\"]*)" (?[^ ]*) (?[^ ]*) \[(?[^ ]*)\] \[(?[^ ]*)\] (?[^,]*),?(?:[^,]*),?(?:[^ ]*) (?[^,]*),?(?:[^,]*),?(?:[^ ]*) (?[^,]*),?(?:[^,]*),?(?:[^ ]*) (?[^,]*),?(?:[^,]*),?(?:[^ ]*) (?[^ ]*) - # Time_Key timestamp - # Time_Format %d/%b/%Y:%H:%M:%S %z + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + data: + enabled: false + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + + query: + env: {} + service: + type: ClusterIP + port: 80 + # enables the hot tier; not supported with local-store + persistence: + enabled: false + storageClass: "" + accessMode: ReadWriteOnce + size: 100Gi - # The config volume is mounted by default, either to the existingConfigMap value, or the default of "fluent-bit.fullname" - volumeMounts: - - name: config - mountPath: /fluent-bit/etc/fluent-bit.conf - subPath: fluent-bit.conf - - name: config - mountPath: /fluent-bit/etc/custom_parsers.conf - subPath: custom_parsers.conf - daemonSetVolumes: - - name: varlog - hostPath: - path: /var/log - - name: varlibdockercontainers - hostPath: - path: /var/lib/docker/containers - - name: etcmachineid - hostPath: - path: /etc/machine-id - type: File - daemonSetVolumeMounts: - - name: varlog - mountPath: /var/log - - name: varlibdockercontainers - mountPath: /var/lib/docker/containers - readOnly: true - - name: etcmachineid - mountPath: /etc/machine-id - readOnly: true - logLevel: info + ingestor: + count: 3 + port: 8000 + env: {} + service: + type: ClusterIP + port: 80 + persistence: + enabled: false + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi From 7b1555bc671a623e76565d3b083f2ceef313fb23 Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Sun, 12 Jul 2026 13:48:28 +0530 Subject: [PATCH 3/7] helm: unified OSS/enterprise chart with per-node values --- helm/Chart.yaml | 2 +- helm/README.md | 73 +++- helm/templates/_helpers.tpl | 61 +--- helm/templates/create-datasets-job.yaml | 66 ++++ helm/templates/data-pvc.yaml | 16 - helm/templates/ingestor-service.yaml | 18 - helm/templates/ingestor-statefulset.yaml | 166 --------- helm/templates/ingestor.yaml | 253 ++++++++++++++ helm/templates/prism.yaml | 225 ++++++++++++ helm/templates/querier-service.yaml | 18 - helm/templates/querier-statefulset.yaml | 152 --------- helm/templates/querier.yaml | 263 ++++++++++++++ helm/templates/serviceaccount.yaml | 5 +- helm/templates/servicemonitor.yaml | 38 +++ helm/templates/stage-pvc.yaml | 16 - helm/templates/standalone-deployment.yaml | 132 ------- helm/templates/standalone-service.yaml | 18 - helm/templates/standalone.yaml | 212 ++++++++++++ helm/values-aws.yaml | 42 +-- helm/values-azure.yaml | 41 +-- helm/values-gcp.yaml | 50 +-- helm/values.yaml | 398 +++++++++++++++++----- 22 files changed, 1486 insertions(+), 779 deletions(-) create mode 100644 helm/templates/create-datasets-job.yaml delete mode 100644 helm/templates/data-pvc.yaml delete mode 100644 helm/templates/ingestor-service.yaml delete mode 100644 helm/templates/ingestor-statefulset.yaml create mode 100644 helm/templates/ingestor.yaml create mode 100644 helm/templates/prism.yaml delete mode 100644 helm/templates/querier-service.yaml delete mode 100644 helm/templates/querier-statefulset.yaml create mode 100644 helm/templates/querier.yaml create mode 100644 helm/templates/servicemonitor.yaml delete mode 100644 helm/templates/stage-pvc.yaml delete mode 100644 helm/templates/standalone-deployment.yaml delete mode 100644 helm/templates/standalone-service.yaml create mode 100644 helm/templates/standalone.yaml diff --git a/helm/Chart.yaml b/helm/Chart.yaml index b3861fdca..7b55783e7 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: parseable description: Helm chart for Parseable OSS version. Columnar data lake platform - purpose built for observability type: application -version: 3.0.0 +version: 4.0.0 appVersion: "v2.8.0" icon: "https://raw.githubusercontent.com/parseablehq/.github/main/images/logo.svg" diff --git a/helm/README.md b/helm/README.md index 5645016dd..9ee2e5899 100644 --- a/helm/README.md +++ b/helm/README.md @@ -1,41 +1,80 @@ # Parseable Helm Chart -## Install (standalone, local-store) +## Standalone (single pod, local-store) ```sh -kubectl create secret generic parseable-env-secret \ +kubectl create namespace parseable + +kubectl -n parseable create secret generic parseable-env-secret \ --from-literal=addr=0.0.0.0:8000 \ --from-literal=username=admin \ - --from-literal=password=admin \ - --from-literal=staging.dir=/parseable/staging \ - --from-literal=fs.dir=/parseable/data + --from-literal=password=admin -helm install parseable ./ -n parseable --create-namespace +helm install parseable ./ -n parseable ``` -## Distributed on a cloud (querier + ingestors) +## Distributed (querier + ingestors) -Create the secret with the keys for your cloud (see the matching values file), then: +Create the namespace, then the object-store secret for your cloud (below). ```sh -# AWS (S3) -helm install parseable ./ -n parseable --create-namespace -f values-aws.yaml +kubectl create namespace parseable +``` + +### AWS (S3) -# GCP (GCS) -helm install parseable ./ -n parseable --create-namespace -f values-gcp.yaml +```sh +kubectl -n parseable create secret generic parseable-env-secret \ + --from-literal=addr=0.0.0.0:8000 \ + --from-literal=username=admin --from-literal=password=admin \ + --from-literal=s3.url= \ + --from-literal=s3.access.key= --from-literal=s3.secret.key= \ + --from-literal=s3.bucket= --from-literal=s3.region= -# Azure (Blob) -helm install parseable ./ -n parseable --create-namespace -f values-azure.yaml +helm install parseable ./ -n parseable -f values-aws.yaml ``` -## Upgrade +### GCP (GCS) ```sh -helm upgrade parseable ./ -n parseable -f values.yaml +kubectl -n parseable create secret generic parseable-env-secret \ + --from-literal=addr=0.0.0.0:8000 \ + --from-literal=username=admin --from-literal=password=admin \ + --from-literal=gcs.url= --from-literal=gcs.bucket= + +kubectl -n parseable create secret generic parseable-gcs-key \ + --from-file=key.json= + +helm install parseable ./ -n parseable -f values-gcp.yaml +``` + +### Azure (Blob) + +```sh +kubectl -n parseable create secret generic parseable-env-secret \ + --from-literal=addr=0.0.0.0:8000 \ + --from-literal=username=admin --from-literal=password=admin \ + --from-literal=azr.access_key= --from-literal=azr.account= \ + --from-literal=azr.container= \ + --from-literal=azr.url=https://.blob.core.windows.net + +helm install parseable ./ -n parseable -f values-azure.yaml +``` + +## Enterprise (adds prism) + +```sh +kubectl -n parseable create secret generic parseable-license \ + --from-file=parseable_license.json=/parseable_license.json \ + --from-file=parseable_license.sig=/parseable_license.sig + +helm install parseable ./ -n parseable -f values-aws.yaml \ + --set parseable.enterprise.enabled=true ``` -## Uninstall +## Upgrade / Uninstall ```sh +helm upgrade parseable ./ -n parseable -f values-aws.yaml helm uninstall parseable -n parseable ``` diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl index 67be278c9..991a4634c 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/templates/_helpers.tpl @@ -7,8 +7,6 @@ Expand the name of the chart. {{/* Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. */}} {{- define "parseable.fullname" -}} {{- if .Values.parseable.fullnameOverride }} @@ -24,76 +22,27 @@ If release name contains chart name it will be used as a full name. {{- end }} {{/* -Create chart name and version as used by the chart label. +Chart name and version, for the helm.sh/chart label. */}} {{- define "parseable.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} {{/* -Common labels +Metadata labels attached to every object (no component/selector labels). */}} {{- define "parseable.labels" -}} helm.sh/chart: {{ include "parseable.chart" . }} -{{ include "parseable.labelsSelector" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Ingestor Labels -*/}} -{{- define "parseable.ingestorLabels" -}} -helm.sh/chart: {{ include "parseable.chart" . }} -{{ include "parseable.ingestorLabelsSelector" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} +app.kubernetes.io/name: {{ include "parseable.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Querier Labels -*/}} -{{- define "parseable.querierLabels" -}} -helm.sh/chart: {{ include "parseable.chart" . }} -{{ include "parseable.querierLabelsSelector" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "parseable.labelsSelector" -}} -app.kubernetes.io/name: {{ include "parseable.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Ingestor Labels Selector for ingestor statefulset -*/}} -{{- define "parseable.ingestorLabelsSelector" -}} -app.kubernetes.io/name: {{ include "parseable.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -app.parseable.com/type: ingestor -{{- end }} - -{{/* -Querier Labels Selector for querier deployment -*/}} -{{- define "parseable.querierLabelsSelector" -}} -app.kubernetes.io/name: {{ include "parseable.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -app.parseable.com/type: querier {{- end }} {{/* -Create the name of the service account to use +Name of the service account to use. */}} {{- define "parseable.serviceAccountName" -}} {{- if .Values.parseable.serviceAccount.create }} diff --git a/helm/templates/create-datasets-job.yaml b/helm/templates/create-datasets-job.yaml new file mode 100644 index 000000000..23cfa7371 --- /dev/null +++ b/helm/templates/create-datasets-job.yaml @@ -0,0 +1,66 @@ +{{- if .Values.parseable.datasets }} +{{- $p := .Values.parseable }} +{{- $fullname := include "parseable.fullname" . }} +{{- $target := ternary (printf "%s-standalone-service" $fullname) (printf "%s-querier-service" $fullname) (eq $p.deploymentMode "standalone") }} +{{- $url := printf "http://%s.%s" $target .Release.Namespace }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $fullname }}-datasets + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} +data: + create-datasets.sh: |- + #!/bin/sh + set -eu + base="{{ $url }}" + {{- range $ds := $p.datasets }} + echo "Creating dataset {{ $ds.name }}..." + curl -sf -X PUT -u "$P_USERNAME:$P_PASSWORD" "$base/api/v1/logstream/{{ $ds.name }}" + {{- if $ds.retention }} + curl -sf -X PUT -u "$P_USERNAME:$P_PASSWORD" -H "Content-Type: application/json" \ + -d '[{"description":"created by helm","action":"{{ $ds.retention.action }}","duration":"{{ $ds.retention.duration }}"}]' \ + "$base/api/v1/logstream/{{ $ds.name }}/retention" + {{- end }} + {{- end }} + echo "Done." +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ $fullname }}-datasets + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + backoffLimit: 10 + template: + metadata: + labels: + {{- include "parseable.labels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + securityContext: + {{- toYaml $p.podSecurityContext | nindent 8 }} + volumes: + - name: script + configMap: + name: {{ $fullname }}-datasets + defaultMode: 0755 + containers: + - name: create-datasets + image: curlimages/curl:latest + command: [ "/bin/sh", "/scripts/create-datasets.sh" ] + env: + - name: P_USERNAME + valueFrom: { secretKeyRef: { name: {{ $p.store.secretName }}, key: username } } + - name: P_PASSWORD + valueFrom: { secretKeyRef: { name: {{ $p.store.secretName }}, key: password } } + volumeMounts: + - name: script + mountPath: /scripts +{{- end }} diff --git a/helm/templates/data-pvc.yaml b/helm/templates/data-pvc.yaml deleted file mode 100644 index 197a4d552..000000000 --- a/helm/templates/data-pvc.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- $p := .Values.parseable.nodes.standalone.persistence.data }} -{{- if and (not .Values.parseable.highAvailability.enabled) $p.enabled }} -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ include "parseable.fullname" . }}-data-pvc - labels: - {{- include "parseable.labels" . | nindent 4 }} -spec: - accessModes: - - {{ $p.accessMode | quote }} - resources: - requests: - storage: {{ $p.size | quote }} - storageClassName: "{{ $p.storageClass }}" -{{- end }} diff --git a/helm/templates/ingestor-service.yaml b/helm/templates/ingestor-service.yaml deleted file mode 100644 index b9efbee38..000000000 --- a/helm/templates/ingestor-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.parseable.highAvailability.enabled }} -{{- $node := .Values.parseable.nodes.ingestor }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "parseable.fullname" . }}-ingestor-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "parseable.labelsSelector" . | nindent 4 }} -spec: - type: {{ $node.service.type }} - ports: - - port: {{ $node.service.port }} - targetPort: {{ $node.port }} - protocol: TCP - selector: - {{- include "parseable.ingestorLabelsSelector" . | nindent 4 }} -{{- end }} diff --git a/helm/templates/ingestor-statefulset.yaml b/helm/templates/ingestor-statefulset.yaml deleted file mode 100644 index 59113de16..000000000 --- a/helm/templates/ingestor-statefulset.yaml +++ /dev/null @@ -1,166 +0,0 @@ -{{- if .Values.parseable.highAvailability.enabled }} -{{- $common := .Values.parseable.common }} -{{- $node := .Values.parseable.nodes.ingestor }} -{{- $secret := .Values.parseable.secrets }} -{{- $cred := .Values.parseable.credentialFile }} -{{- $audit := .Values.parseable.auditLogging }} -{{- $env := merge (deepCopy ($node.env | default dict)) ($common.env | default dict) }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "parseable.fullname" . }}-ingestor-headless - namespace: {{ .Release.Namespace }} -spec: - ports: - - port: 8000 - name: "parseable-port" - clusterIP: None - selector: - {{- include "parseable.ingestorLabelsSelector" . | nindent 4 }} ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ include "parseable.fullname" . }}-ingestor - namespace: {{ .Release.Namespace }} - labels: - {{- include "parseable.ingestorLabels" . | nindent 4 }} -spec: - selector: - matchLabels: - {{- include "parseable.ingestorLabelsSelector" . | nindent 6 }} - serviceName: {{ include "parseable.fullname" . }}-ingestor-headless - replicas: {{ $node.count }} - minReadySeconds: 2 - template: - metadata: - {{- with ($node.podAnnotations | default $common.podAnnotations) }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- with ($node.podLabels | default $common.podLabels) }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- include "parseable.ingestorLabelsSelector" . | nindent 8 }} - spec: - terminationGracePeriodSeconds: 10 - serviceAccountName: {{ include "parseable.serviceAccountName" . }} - securityContext: - {{- toYaml $common.podSecurityContext | nindent 8 }} - {{- with ($node.nodeSelector | default $common.nodeSelector) }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with ($node.tolerations | default $common.tolerations) }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with ($node.affinity | default $common.affinity) }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - # ingestors register against the querier, so wait for it to be ready first - initContainers: - - name: wait-for-query-service - image: curlimages/curl:latest - command: - - /bin/sh - - -c - - | - echo "Waiting for query service readiness at /api/v1/readiness..." - for i in $(seq 1 60); do - if curl -sf http://{{ include "parseable.fullname" . }}-querier-service.{{ .Release.Namespace }}/api/v1/readiness; then - echo "Query service is ready!" - exit 0 - fi - echo "Query service is not ready yet. Retrying in 2 seconds..." - sleep 2 - done - echo "Query service did not become ready in time. Exiting." - exit 1 - {{- if $cred.enabled }} - volumes: - - name: {{ $cred.secretName }} - secret: - secretName: {{ $cred.secretName }} - {{- end }} - containers: - - name: {{ .Chart.Name }} - securityContext: - {{- toYaml $common.securityContext | nindent 12 }} - image: "{{ .Values.parseable.image.repository }}:{{ .Values.parseable.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.parseable.image.pullPolicy }} - args: - - "/usr/bin/parseable" - - {{ .Values.parseable.store | quote }} - - --ingestor-endpoint=$(HOSTNAME).{{ include "parseable.fullname" . }}-ingestor-headless.{{ .Release.Namespace }}.svc.cluster.local:{{ $node.port }} - env: - - name: HOSTNAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.name - - name: P_MODE - value: "ingest" - # common.env merged with nodes.ingestor.env (node wins) - {{- range $key, $value := $env }} - - name: {{ $key }} - value: {{ tpl $value $ | quote }} - {{- end }} - # credentials from the secret in .Values.parseable.secrets - {{- if and $secret $secret.name $secret.keys }} - {{- $prefix := $secret.prefix | default "" | upper }} - {{- range $key := $secret.keys }} - - name: {{ $prefix }}{{ $key | upper | replace "." "_" | replace "-" "_" }} - valueFrom: - secretKeyRef: - name: {{ $secret.name }} - key: {{ $key }} - {{- end }} - {{- end }} - {{- if $cred.enabled }} - - name: GOOGLE_APPLICATION_CREDENTIALS - value: "{{ $cred.mountPath }}/{{ $cred.secretKey }}" - {{- end }} - {{- if $audit.enabled }} - - name: P_AUDIT_LOGGER - value: {{ $audit.p_server | quote }} - - name: P_AUDIT_USERNAME - value: {{ $audit.p_username | quote }} - - name: P_AUDIT_PASSWORD - value: {{ $audit.p_password | quote }} - {{- end }} - ports: - - containerPort: {{ $node.port }} - {{- with ($node.readinessProbe | default $common.readinessProbe) }} - readinessProbe: - {{- toYaml . | nindent 12 }} - {{- end }} - resources: - {{- toYaml ($node.resources | default $common.resources) | nindent 12 }} - {{- if or $node.persistence.enabled $cred.enabled }} - volumeMounts: - {{- if $node.persistence.enabled }} - - name: stage-volume - mountPath: "/parseable/staging" - {{- end }} - {{- if $cred.enabled }} - - name: {{ $cred.secretName }} - mountPath: {{ $cred.mountPath }} - readOnly: true - {{- end }} - {{- end }} - {{- if $node.persistence.enabled }} - volumeClaimTemplates: - - metadata: - name: stage-volume - spec: - accessModes: - - {{ $node.persistence.accessMode | quote }} - storageClassName: {{ $node.persistence.storageClass | quote }} - resources: - requests: - storage: {{ $node.persistence.size | quote }} - {{- end }} -{{- end }} diff --git a/helm/templates/ingestor.yaml b/helm/templates/ingestor.yaml new file mode 100644 index 000000000..891ca1021 --- /dev/null +++ b/helm/templates/ingestor.yaml @@ -0,0 +1,253 @@ +{{- if eq .Values.parseable.deploymentMode "distributed" }} +{{- $p := .Values.parseable }} +{{- $ent := $p.enterprise }} +{{- $node := $p.ingestor }} +{{- $store := $p.store }} +{{- $secret := $store.secretName }} +{{- $gcs := eq $store.type "gcs-store" }} +{{- $image := $ent.enabled | ternary (printf "%s:%s" $ent.image.repository ($ent.image.tag | default .Chart.AppVersion)) (printf "%s:%s" $p.image.repository ($p.image.tag | default .Chart.AppVersion)) }} +{{- $pullPolicy := $ent.enabled | ternary $ent.image.pullPolicy $p.image.pullPolicy }} +{{- $pullSecrets := $ent.enabled | ternary $ent.imagePullSecrets $p.imagePullSecrets }} +{{- $binary := $ent.enabled | ternary "parseable-enterprise" "/usr/bin/parseable" }} +{{- $waitFor := $ent.enabled | ternary "prism" "querier" }} +{{- $fullname := include "parseable.fullname" . }} +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullname }}-ingestor-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: ingestor +spec: + clusterIP: None + ports: + - port: 8000 + name: parseable-port + selector: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: ingestor +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullname }}-ingestor-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: ingestor +spec: + type: {{ $node.service.type }} + ports: + - port: {{ $node.service.port }} + targetPort: 8000 + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: ingestor +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ $fullname }}-ingestor + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: ingestor +spec: + serviceName: {{ $fullname }}-ingestor-headless + replicas: {{ $node.replicas }} + minReadySeconds: 2 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: ingestor + template: + metadata: + {{- with $node.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- with $node.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: ingestor + spec: + {{- with $pullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "parseable.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ $node.terminationGracePeriodSeconds }} + securityContext: + {{- toYaml $p.podSecurityContext | nindent 8 }} + {{- with $node.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $node.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $node.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + # ingestors register against the {{ $waitFor }}, so wait for it to be ready first + initContainers: + - name: wait-for-{{ $waitFor }} + image: curlimages/curl:latest + command: + - /bin/sh + - -c + - | + echo "Waiting for {{ $waitFor }} at /api/v1/readiness..." + for i in $(seq 1 60); do + if curl -sf http://{{ $fullname }}-{{ $waitFor }}-service.{{ .Release.Namespace }}/api/v1/readiness; then + echo "{{ $waitFor }} is ready!"; exit 0 + fi + echo "Not ready yet, retrying in 2s..."; sleep 2 + done + echo "{{ $waitFor }} did not become ready in time."; exit 1 + volumes: + {{- if not $node.persistence.staging.enabled }} + - name: stage-volume + emptyDir: {} + {{- end }} + {{- if $gcs }} + - name: gcs-credentials + secret: + secretName: {{ $store.gcsCredentials.secretName }} + {{- end }} + {{- if $ent.enabled }} + - name: license + secret: + secretName: {{ $ent.license.secretName }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml $p.securityContext | nindent 12 }} + image: "{{ $image }}" + imagePullPolicy: {{ $pullPolicy }} + args: [ {{ $binary | quote }}, {{ $store.type | quote }} ] + env: + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: P_MODE + value: "ingest" + - name: P_STAGING_DIR + value: "/parseable/staging" + - name: P_INGESTOR_ENDPOINT + value: "$(HOSTNAME).{{ $fullname }}-ingestor-headless.{{ .Release.Namespace }}.svc.cluster.local:8000" + {{- if $p.clusterSecret.enabled }} + - name: P_CLUSTER_SECRET + valueFrom: + secretKeyRef: + name: {{ $p.clusterSecret.secretName }} + key: {{ $p.clusterSecret.secretKey }} + {{- end }} + {{- range $key, $value := $node.env }} + - name: {{ $key }} + value: {{ tpl (toString $value) $ | quote }} + {{- end }} + # object store credentials + admin user from the store secret + - name: P_ADDR + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: addr } } + - name: P_USERNAME + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: username } } + - name: P_PASSWORD + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: password } } + {{- if eq $store.type "s3-store" }} + - name: P_S3_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.url } } + - name: P_S3_ACCESS_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.access.key } } + - name: P_S3_SECRET_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.secret.key } } + - name: P_S3_BUCKET + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.bucket } } + - name: P_S3_REGION + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.region } } + {{- else if eq $store.type "blob-store" }} + - name: P_AZR_ACCESS_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.access_key } } + - name: P_AZR_ACCOUNT + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.account } } + - name: P_AZR_CONTAINER + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.container } } + - name: P_AZR_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.url } } + {{- else if eq $store.type "gcs-store" }} + - name: P_GCS_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: gcs.url } } + - name: P_GCS_BUCKET + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: gcs.bucket } } + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "{{ $store.gcsCredentials.mountPath }}/{{ $store.gcsCredentials.secretKey }}" + {{- end }} + {{- if $ent.enabled }} + - name: P_LICENSE_DATA_FILE_PATH + value: "{{ $ent.license.mountPath }}/{{ $ent.license.dataKey }}" + - name: P_LICENSE_SIGNATURE_FILE_PATH + value: "{{ $ent.license.mountPath }}/{{ $ent.license.signatureKey }}" + {{- if $ent.auditLogging.enabled }} + - name: P_AUDIT_LOGGER + value: {{ $ent.auditLogging.server | quote }} + - name: P_AUDIT_USERNAME + value: {{ $ent.auditLogging.username | quote }} + {{- if $ent.auditLogging.existingSecret.name }} + - name: P_AUDIT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ $ent.auditLogging.existingSecret.name }} + key: {{ $ent.auditLogging.existingSecret.key }} + {{- else }} + - name: P_AUDIT_PASSWORD + value: {{ $ent.auditLogging.password | quote }} + {{- end }} + {{- end }} + {{- end }} + ports: + - containerPort: 8000 + {{- with $node.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml $node.resources | nindent 12 }} + volumeMounts: + - name: stage-volume + mountPath: "/parseable/staging" + {{- if $gcs }} + - name: gcs-credentials + mountPath: {{ $store.gcsCredentials.mountPath }} + readOnly: true + {{- end }} + {{- if $ent.enabled }} + - name: license + mountPath: {{ $ent.license.mountPath }} + readOnly: true + {{- end }} + {{- if $node.persistence.staging.enabled }} + volumeClaimTemplates: + - metadata: + name: stage-volume + spec: + accessModes: + - {{ $node.persistence.staging.accessMode | quote }} + storageClassName: {{ $node.persistence.staging.storageClass | quote }} + resources: + requests: + storage: {{ $node.persistence.staging.size | quote }} + {{- end }} +{{- end }} diff --git a/helm/templates/prism.yaml b/helm/templates/prism.yaml new file mode 100644 index 000000000..addea1435 --- /dev/null +++ b/helm/templates/prism.yaml @@ -0,0 +1,225 @@ +{{- if and (eq .Values.parseable.deploymentMode "distributed") .Values.parseable.enterprise.enabled }} +{{- $p := .Values.parseable }} +{{- $ent := $p.enterprise }} +{{- $node := $p.prism }} +{{- $store := $p.store }} +{{- $secret := $store.secretName }} +{{- $gcs := eq $store.type "gcs-store" }} +{{- $image := printf "%s:%s" $ent.image.repository ($ent.image.tag | default .Chart.AppVersion) }} +{{- $fullname := include "parseable.fullname" . }} +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullname }}-prism-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: prism +spec: + clusterIP: None + ports: + - port: 8000 + name: parseable-port + selector: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: prism +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullname }}-prism-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: prism +spec: + type: {{ $node.service.type }} + ports: + - port: {{ $node.service.port }} + targetPort: 8000 + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: prism +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ $fullname }}-prism + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: prism +spec: + serviceName: {{ $fullname }}-prism-headless + replicas: {{ $node.replicas }} + minReadySeconds: 2 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: prism + template: + metadata: + {{- with $node.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- with $node.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: prism + spec: + {{- with $ent.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "parseable.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ $node.terminationGracePeriodSeconds }} + securityContext: + {{- toYaml $p.podSecurityContext | nindent 8 }} + {{- with $node.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $node.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $node.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if not $node.persistence.enabled }} + - name: stage-volume + emptyDir: {} + {{- end }} + {{- if $gcs }} + - name: gcs-credentials + secret: + secretName: {{ $store.gcsCredentials.secretName }} + {{- end }} + - name: license + secret: + secretName: {{ $ent.license.secretName }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml $p.securityContext | nindent 12 }} + image: "{{ $image }}" + imagePullPolicy: {{ $ent.image.pullPolicy }} + args: [ "parseable-enterprise", {{ $store.type | quote }} ] + env: + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: P_MODE + value: "prism" + - name: P_STAGING_DIR + value: "/parseable/staging" + {{- if $p.clusterSecret.enabled }} + - name: P_CLUSTER_SECRET + valueFrom: + secretKeyRef: + name: {{ $p.clusterSecret.secretName }} + key: {{ $p.clusterSecret.secretKey }} + {{- end }} + {{- range $key, $value := $node.env }} + - name: {{ $key }} + value: {{ tpl (toString $value) $ | quote }} + {{- end }} + # object store credentials + admin user from the store secret + - name: P_ADDR + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: addr } } + - name: P_USERNAME + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: username } } + - name: P_PASSWORD + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: password } } + {{- if eq $store.type "s3-store" }} + - name: P_S3_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.url } } + - name: P_S3_ACCESS_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.access.key } } + - name: P_S3_SECRET_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.secret.key } } + - name: P_S3_BUCKET + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.bucket } } + - name: P_S3_REGION + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.region } } + {{- else if eq $store.type "blob-store" }} + - name: P_AZR_ACCESS_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.access_key } } + - name: P_AZR_ACCOUNT + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.account } } + - name: P_AZR_CONTAINER + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.container } } + - name: P_AZR_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.url } } + {{- else if eq $store.type "gcs-store" }} + - name: P_GCS_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: gcs.url } } + - name: P_GCS_BUCKET + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: gcs.bucket } } + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "{{ $store.gcsCredentials.mountPath }}/{{ $store.gcsCredentials.secretKey }}" + {{- end }} + - name: P_LICENSE_DATA_FILE_PATH + value: "{{ $ent.license.mountPath }}/{{ $ent.license.dataKey }}" + - name: P_LICENSE_SIGNATURE_FILE_PATH + value: "{{ $ent.license.mountPath }}/{{ $ent.license.signatureKey }}" + {{- if $ent.auditLogging.enabled }} + - name: P_AUDIT_LOGGER + value: {{ $ent.auditLogging.server | quote }} + - name: P_AUDIT_USERNAME + value: {{ $ent.auditLogging.username | quote }} + {{- if $ent.auditLogging.existingSecret.name }} + - name: P_AUDIT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ $ent.auditLogging.existingSecret.name }} + key: {{ $ent.auditLogging.existingSecret.key }} + {{- else }} + - name: P_AUDIT_PASSWORD + value: {{ $ent.auditLogging.password | quote }} + {{- end }} + {{- end }} + ports: + - containerPort: 8000 + {{- with $node.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml $node.resources | nindent 12 }} + volumeMounts: + - name: stage-volume + mountPath: "/parseable/staging" + {{- if $gcs }} + - name: gcs-credentials + mountPath: {{ $store.gcsCredentials.mountPath }} + readOnly: true + {{- end }} + - name: license + mountPath: {{ $ent.license.mountPath }} + readOnly: true + {{- if $node.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: stage-volume + spec: + accessModes: + - {{ $node.persistence.accessMode | quote }} + storageClassName: {{ $node.persistence.storageClass | quote }} + resources: + requests: + storage: {{ $node.persistence.size | quote }} + {{- end }} +{{- end }} diff --git a/helm/templates/querier-service.yaml b/helm/templates/querier-service.yaml deleted file mode 100644 index 537eb4825..000000000 --- a/helm/templates/querier-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.parseable.highAvailability.enabled }} -{{- $svc := .Values.parseable.nodes.query.service }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "parseable.fullname" . }}-querier-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "parseable.labelsSelector" . | nindent 4 }} -spec: - type: {{ $svc.type }} - ports: - - port: {{ $svc.port }} - targetPort: 8000 - protocol: TCP - selector: - {{- include "parseable.querierLabelsSelector" . | nindent 4 }} -{{- end }} diff --git a/helm/templates/querier-statefulset.yaml b/helm/templates/querier-statefulset.yaml deleted file mode 100644 index b59f6cb53..000000000 --- a/helm/templates/querier-statefulset.yaml +++ /dev/null @@ -1,152 +0,0 @@ -{{- if .Values.parseable.highAvailability.enabled }} -{{- $common := .Values.parseable.common }} -{{- $node := .Values.parseable.nodes.query }} -{{- $secret := .Values.parseable.secrets }} -{{- $cred := .Values.parseable.credentialFile }} -{{- $audit := .Values.parseable.auditLogging }} -{{- $env := merge (deepCopy ($node.env | default dict)) ($common.env | default dict) }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "parseable.fullname" . }}-querier-headless - namespace: {{ .Release.Namespace }} -spec: - ports: - - port: 8000 - name: "parseable-port" - clusterIP: None - selector: - {{- include "parseable.querierLabelsSelector" . | nindent 4 }} ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ include "parseable.fullname" . }}-querier - namespace: {{ .Release.Namespace }} - labels: - {{- include "parseable.querierLabels" . | nindent 4 }} -spec: - selector: - matchLabels: - {{- include "parseable.querierLabelsSelector" . | nindent 6 }} - serviceName: {{ include "parseable.fullname" . }}-querier-headless - replicas: 1 - minReadySeconds: 2 - template: - metadata: - {{- with ($node.podAnnotations | default $common.podAnnotations) }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- with ($node.podLabels | default $common.podLabels) }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- include "parseable.querierLabelsSelector" . | nindent 8 }} - spec: - terminationGracePeriodSeconds: 10 - serviceAccountName: {{ include "parseable.serviceAccountName" . }} - securityContext: - {{- toYaml $common.podSecurityContext | nindent 8 }} - {{- with ($node.nodeSelector | default $common.nodeSelector) }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with ($node.tolerations | default $common.tolerations) }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with ($node.affinity | default $common.affinity) }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - volumes: - {{- if $cred.enabled }} - - name: {{ $cred.secretName }} - secret: - secretName: {{ $cred.secretName }} - {{- end }} - - name: stage-volume - emptyDir: {} - containers: - - name: {{ .Chart.Name }} - securityContext: - {{- toYaml $common.securityContext | nindent 12 }} - image: "{{ .Values.parseable.image.repository }}:{{ .Values.parseable.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.parseable.image.pullPolicy }} - args: [ "/usr/bin/parseable", {{ .Values.parseable.store | quote }} ] - env: - - name: HOSTNAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.name - - name: P_MODE - value: "query" - {{- if $node.persistence.enabled }} - - name: P_HOT_TIER_DIR - value: "/parseable/hot-tier" - - name: P_MAX_DISK_USAGE_PERCENT - value: "95.0" - {{- end }} - # common.env merged with nodes.query.env (node wins) - {{- range $key, $value := $env }} - - name: {{ $key }} - value: {{ tpl $value $ | quote }} - {{- end }} - # credentials from the secret in .Values.parseable.secrets - {{- if and $secret $secret.name $secret.keys }} - {{- $prefix := $secret.prefix | default "" | upper }} - {{- range $key := $secret.keys }} - - name: {{ $prefix }}{{ $key | upper | replace "." "_" | replace "-" "_" }} - valueFrom: - secretKeyRef: - name: {{ $secret.name }} - key: {{ $key }} - {{- end }} - {{- end }} - {{- if $cred.enabled }} - - name: GOOGLE_APPLICATION_CREDENTIALS - value: "{{ $cred.mountPath }}/{{ $cred.secretKey }}" - {{- end }} - {{- if $audit.enabled }} - - name: P_AUDIT_LOGGER - value: {{ $audit.p_server | quote }} - - name: P_AUDIT_USERNAME - value: {{ $audit.p_username | quote }} - - name: P_AUDIT_PASSWORD - value: {{ $audit.p_password | quote }} - {{- end }} - ports: - - containerPort: 8000 - {{- with ($node.readinessProbe | default $common.readinessProbe) }} - readinessProbe: - {{- toYaml . | nindent 12 }} - {{- end }} - resources: - {{- toYaml ($node.resources | default $common.resources) | nindent 12 }} - volumeMounts: - - name: stage-volume - mountPath: "/parseable/staging" - {{- if $node.persistence.enabled }} - - name: hot-tier-volume - mountPath: "/parseable/hot-tier" - {{- end }} - {{- if $cred.enabled }} - - name: {{ $cred.secretName }} - mountPath: {{ $cred.mountPath }} - readOnly: true - {{- end }} - {{- if $node.persistence.enabled }} - volumeClaimTemplates: - - metadata: - name: hot-tier-volume - spec: - accessModes: - - {{ $node.persistence.accessMode | quote }} - storageClassName: {{ $node.persistence.storageClass | quote }} - resources: - requests: - storage: {{ $node.persistence.size | quote }} - {{- end }} -{{- end }} diff --git a/helm/templates/querier.yaml b/helm/templates/querier.yaml new file mode 100644 index 000000000..6c7f3a25e --- /dev/null +++ b/helm/templates/querier.yaml @@ -0,0 +1,263 @@ +{{- if eq .Values.parseable.deploymentMode "distributed" }} +{{- $p := .Values.parseable }} +{{- $ent := $p.enterprise }} +{{- $node := $p.querier }} +{{- $store := $p.store }} +{{- $secret := $store.secretName }} +{{- $gcs := eq $store.type "gcs-store" }} +{{- $hotTier := $node.persistence.hotTier }} +{{- $image := $ent.enabled | ternary (printf "%s:%s" $ent.image.repository ($ent.image.tag | default .Chart.AppVersion)) (printf "%s:%s" $p.image.repository ($p.image.tag | default .Chart.AppVersion)) }} +{{- $pullPolicy := $ent.enabled | ternary $ent.image.pullPolicy $p.image.pullPolicy }} +{{- $pullSecrets := $ent.enabled | ternary $ent.imagePullSecrets $p.imagePullSecrets }} +{{- $binary := $ent.enabled | ternary "parseable-enterprise" "/usr/bin/parseable" }} +{{- $fullname := include "parseable.fullname" . }} +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullname }}-querier-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: querier +spec: + clusterIP: None + ports: + - port: 8000 + name: parseable-port + selector: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: querier +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullname }}-querier-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: querier +spec: + type: {{ $node.service.type }} + ports: + - port: {{ $node.service.port }} + targetPort: 8000 + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: querier +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ $fullname }}-querier + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: querier +spec: + serviceName: {{ $fullname }}-querier-headless + replicas: {{ $node.replicas }} + minReadySeconds: 2 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: querier + template: + metadata: + {{- with $node.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- with $node.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: querier + spec: + {{- with $pullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "parseable.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ $node.terminationGracePeriodSeconds }} + securityContext: + {{- toYaml $p.podSecurityContext | nindent 8 }} + {{- with $node.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $node.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $node.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if $ent.enabled }} + # Enterprise: the querier registers with prism, so wait for it first + initContainers: + - name: wait-for-prism + image: curlimages/curl:latest + command: + - /bin/sh + - -c + - | + echo "Waiting for prism at /api/v1/readiness..." + for i in $(seq 1 60); do + if curl -sf http://{{ $fullname }}-prism-service.{{ .Release.Namespace }}/api/v1/readiness; then + echo "Prism is ready!"; exit 0 + fi + echo "Not ready yet, retrying in 2s..."; sleep 2 + done + echo "Prism did not become ready in time."; exit 1 + {{- end }} + volumes: + - name: stage-volume + emptyDir: {} + {{- if not $hotTier.enabled }} + - name: hot-tier-volume + emptyDir: {} + {{- end }} + {{- if $gcs }} + - name: gcs-credentials + secret: + secretName: {{ $store.gcsCredentials.secretName }} + {{- end }} + {{- if $ent.enabled }} + - name: license + secret: + secretName: {{ $ent.license.secretName }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml $p.securityContext | nindent 12 }} + image: "{{ $image }}" + imagePullPolicy: {{ $pullPolicy }} + args: [ {{ $binary | quote }}, {{ $store.type | quote }} ] + env: + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: P_MODE + value: "query" + - name: P_STAGING_DIR + value: "/parseable/staging" + - name: P_HOT_TIER_DIR + value: "/parseable/hot-tier" + - name: P_MAX_DISK_USAGE_PERCENT + value: "95.0" + - name: P_QUERIER_ENDPOINT + value: "$(HOSTNAME).{{ $fullname }}-querier-headless.{{ .Release.Namespace }}.svc.cluster.local:8000" + {{- if $p.clusterSecret.enabled }} + - name: P_CLUSTER_SECRET + valueFrom: + secretKeyRef: + name: {{ $p.clusterSecret.secretName }} + key: {{ $p.clusterSecret.secretKey }} + {{- end }} + {{- range $key, $value := $node.env }} + - name: {{ $key }} + value: {{ tpl (toString $value) $ | quote }} + {{- end }} + # object store credentials + admin user from the store secret + - name: P_ADDR + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: addr } } + - name: P_USERNAME + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: username } } + - name: P_PASSWORD + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: password } } + {{- if eq $store.type "s3-store" }} + - name: P_S3_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.url } } + - name: P_S3_ACCESS_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.access.key } } + - name: P_S3_SECRET_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.secret.key } } + - name: P_S3_BUCKET + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.bucket } } + - name: P_S3_REGION + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.region } } + {{- else if eq $store.type "blob-store" }} + - name: P_AZR_ACCESS_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.access_key } } + - name: P_AZR_ACCOUNT + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.account } } + - name: P_AZR_CONTAINER + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.container } } + - name: P_AZR_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.url } } + {{- else if eq $store.type "gcs-store" }} + - name: P_GCS_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: gcs.url } } + - name: P_GCS_BUCKET + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: gcs.bucket } } + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "{{ $store.gcsCredentials.mountPath }}/{{ $store.gcsCredentials.secretKey }}" + {{- end }} + {{- if $ent.enabled }} + - name: P_LICENSE_DATA_FILE_PATH + value: "{{ $ent.license.mountPath }}/{{ $ent.license.dataKey }}" + - name: P_LICENSE_SIGNATURE_FILE_PATH + value: "{{ $ent.license.mountPath }}/{{ $ent.license.signatureKey }}" + {{- if $ent.auditLogging.enabled }} + - name: P_AUDIT_LOGGER + value: {{ $ent.auditLogging.server | quote }} + - name: P_AUDIT_USERNAME + value: {{ $ent.auditLogging.username | quote }} + {{- if $ent.auditLogging.existingSecret.name }} + - name: P_AUDIT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ $ent.auditLogging.existingSecret.name }} + key: {{ $ent.auditLogging.existingSecret.key }} + {{- else }} + - name: P_AUDIT_PASSWORD + value: {{ $ent.auditLogging.password | quote }} + {{- end }} + {{- end }} + {{- end }} + ports: + - containerPort: 8000 + {{- with $node.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml $node.resources | nindent 12 }} + volumeMounts: + - name: stage-volume + mountPath: "/parseable/staging" + - name: hot-tier-volume + mountPath: "/parseable/hot-tier" + {{- if $gcs }} + - name: gcs-credentials + mountPath: {{ $store.gcsCredentials.mountPath }} + readOnly: true + {{- end }} + {{- if $ent.enabled }} + - name: license + mountPath: {{ $ent.license.mountPath }} + readOnly: true + {{- end }} + {{- if $hotTier.enabled }} + volumeClaimTemplates: + - metadata: + name: hot-tier-volume + spec: + accessModes: + - {{ $hotTier.accessMode | quote }} + storageClassName: {{ $hotTier.storageClass | quote }} + resources: + requests: + storage: {{ $hotTier.size | quote }} + {{- end }} +{{- end }} diff --git a/helm/templates/serviceaccount.yaml b/helm/templates/serviceaccount.yaml index 608e6a4cf..4e3c767aa 100644 --- a/helm/templates/serviceaccount.yaml +++ b/helm/templates/serviceaccount.yaml @@ -1,11 +1,12 @@ -{{- if $.Values.parseable.serviceAccount.create -}} +{{- if .Values.parseable.serviceAccount.create -}} apiVersion: v1 kind: ServiceAccount metadata: name: {{ include "parseable.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} labels: {{- include "parseable.labels" . | nindent 4 }} - {{- with $.Values.parseable.serviceAccount.annotations }} + {{- with .Values.parseable.serviceAccount.annotations }} annotations: {{- toYaml . | nindent 4 }} {{- end }} diff --git a/helm/templates/servicemonitor.yaml b/helm/templates/servicemonitor.yaml new file mode 100644 index 000000000..e31d4c3a2 --- /dev/null +++ b/helm/templates/servicemonitor.yaml @@ -0,0 +1,38 @@ +{{- if .Values.parseable.metrics.serviceMonitor.enabled }} +{{- $p := .Values.parseable }} +{{- $sm := $p.metrics.serviceMonitor }} +{{- $fullname := include "parseable.fullname" . }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ $fullname }} + namespace: {{ default .Release.Namespace $sm.namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + {{- with $sm.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: {{ $sm.port }} + path: {{ $sm.path }} + interval: {{ $sm.interval }} + {{- with $sm.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with $sm.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $sm.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/templates/stage-pvc.yaml b/helm/templates/stage-pvc.yaml deleted file mode 100644 index f4de56b72..000000000 --- a/helm/templates/stage-pvc.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- $p := .Values.parseable.nodes.standalone.persistence.staging }} -{{- if and (not .Values.parseable.highAvailability.enabled) $p.enabled }} -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ include "parseable.fullname" . }}-staging-pvc - labels: - {{- include "parseable.labels" . | nindent 4 }} -spec: - accessModes: - - {{ $p.accessMode | quote }} - resources: - requests: - storage: {{ $p.size | quote }} - storageClassName: "{{ $p.storageClass }}" -{{- end }} diff --git a/helm/templates/standalone-deployment.yaml b/helm/templates/standalone-deployment.yaml deleted file mode 100644 index 4bdfa6527..000000000 --- a/helm/templates/standalone-deployment.yaml +++ /dev/null @@ -1,132 +0,0 @@ -{{- if not .Values.parseable.highAvailability.enabled }} -{{- $common := .Values.parseable.common }} -{{- $node := .Values.parseable.nodes.standalone }} -{{- $secret := .Values.parseable.secrets }} -{{- $cred := .Values.parseable.credentialFile }} -{{- $audit := .Values.parseable.auditLogging }} -{{- $env := merge (deepCopy ($node.env | default dict)) ($common.env | default dict) }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "parseable.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "parseable.labels" . | nindent 4 }} -spec: - replicas: 1 - selector: - matchLabels: - {{- include "parseable.labelsSelector" . | nindent 6 }} - template: - metadata: - {{- with ($node.podAnnotations | default $common.podAnnotations) }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- with ($node.podLabels | default $common.podLabels) }} - {{- toYaml . | nindent 8 }} - {{- end }} - {{- include "parseable.labelsSelector" . | nindent 8 }} - spec: - {{- with .Values.parseable.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "parseable.serviceAccountName" . }} - securityContext: - {{- toYaml $common.podSecurityContext | nindent 8 }} - containers: - - name: {{ .Chart.Name }} - securityContext: - {{- toYaml $common.securityContext | nindent 12 }} - image: "{{ .Values.parseable.image.repository }}:{{ .Values.parseable.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.parseable.image.pullPolicy }} - args: [ "/usr/bin/parseable", {{ .Values.parseable.store | quote }} ] - env: - - name: HOSTNAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.name - # common.env merged with nodes.standalone.env (node wins) - {{- range $key, $value := $env }} - - name: {{ $key }} - value: {{ tpl $value $ | quote }} - {{- end }} - # credentials from the secret in .Values.parseable.secrets - {{- if and $secret $secret.name $secret.keys }} - {{- $prefix := $secret.prefix | default "" | upper }} - {{- range $key := $secret.keys }} - - name: {{ $prefix }}{{ $key | upper | replace "." "_" | replace "-" "_" }} - valueFrom: - secretKeyRef: - name: {{ $secret.name }} - key: {{ $key }} - {{- end }} - {{- end }} - {{- if $cred.enabled }} - - name: GOOGLE_APPLICATION_CREDENTIALS - value: "{{ $cred.mountPath }}/{{ $cred.secretKey }}" - {{- end }} - {{- if $audit.enabled }} - - name: P_AUDIT_LOGGER - value: {{ $audit.p_server | quote }} - - name: P_AUDIT_USERNAME - value: {{ $audit.p_username | quote }} - - name: P_AUDIT_PASSWORD - value: {{ $audit.p_password | quote }} - {{- end }} - ports: - - containerPort: 8000 - {{- with ($node.readinessProbe | default $common.readinessProbe) }} - readinessProbe: - {{- toYaml . | nindent 12 }} - {{- end }} - resources: - {{- toYaml ($node.resources | default $common.resources) | nindent 12 }} - volumeMounts: - {{- if $cred.enabled }} - - name: {{ $cred.secretName }} - mountPath: {{ $cred.mountPath }} - readOnly: true - {{- end }} - - name: data-volume - mountPath: "/parseable/data" - - name: stage-volume - mountPath: "/parseable/staging" - volumes: - {{- if $cred.enabled }} - - name: {{ $cred.secretName }} - secret: - secretName: {{ $cred.secretName }} - {{- end }} - {{- if $node.persistence.staging.enabled }} - - name: stage-volume - persistentVolumeClaim: - claimName: {{ include "parseable.fullname" . }}-staging-pvc - {{- else }} - - name: stage-volume - emptyDir: {} - {{- end }} - {{- if $node.persistence.data.enabled }} - - name: data-volume - persistentVolumeClaim: - claimName: {{ include "parseable.fullname" . }}-data-pvc - {{- else }} - - name: data-volume - emptyDir: {} - {{- end }} - {{- with ($node.nodeSelector | default $common.nodeSelector) }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with ($node.tolerations | default $common.tolerations) }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with ($node.affinity | default $common.affinity) }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} -{{- end }} diff --git a/helm/templates/standalone-service.yaml b/helm/templates/standalone-service.yaml deleted file mode 100644 index 6484f9cb9..000000000 --- a/helm/templates/standalone-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if not .Values.parseable.highAvailability.enabled }} -{{- $svc := .Values.parseable.nodes.standalone.service }} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "parseable.fullname" . }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "parseable.labelsSelector" . | nindent 4 }} -spec: - type: {{ $svc.type }} - ports: - - port: {{ $svc.port }} - targetPort: 8000 - protocol: TCP - selector: - {{- include "parseable.labelsSelector" . | nindent 4 }} -{{- end }} diff --git a/helm/templates/standalone.yaml b/helm/templates/standalone.yaml new file mode 100644 index 000000000..e1ce45e1a --- /dev/null +++ b/helm/templates/standalone.yaml @@ -0,0 +1,212 @@ +{{- if eq .Values.parseable.deploymentMode "standalone" }} +{{- if .Values.parseable.enterprise.enabled }} +{{- fail "enterprise.enabled requires deploymentMode: distributed (standalone runs P_MODE=all, which Enterprise does not support)" }} +{{- end }} +{{- $p := .Values.parseable }} +{{- $node := $p.standalone }} +{{- $store := $p.store }} +{{- $secret := $store.secretName }} +{{- $gcs := and (eq $store.type "gcs-store") $store.gcsCredentials }} +{{- $image := printf "%s:%s" $p.image.repository ($p.image.tag | default .Chart.AppVersion) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "parseable.fullname" . }}-standalone + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} + app.parseable.com/type: standalone +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: standalone + template: + metadata: + {{- with $node.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- with $node.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: standalone + spec: + {{- with $p.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "parseable.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ $node.terminationGracePeriodSeconds }} + securityContext: + {{- toYaml $p.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml $p.securityContext | nindent 12 }} + image: "{{ $image }}" + imagePullPolicy: {{ $p.image.pullPolicy }} + args: [ "/usr/bin/parseable", {{ $store.type | quote }} ] + env: + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: P_MODE + value: "all" + - name: P_STAGING_DIR + value: "/parseable/staging" + {{- if eq $store.type "local-store" }} + - name: P_FS_DIR + value: "/parseable/data" + {{- end }} + {{- range $key, $value := $node.env }} + - name: {{ $key }} + value: {{ tpl (toString $value) $ | quote }} + {{- end }} + # object store credentials + admin user from the store secret + - name: P_ADDR + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: addr } } + - name: P_USERNAME + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: username } } + - name: P_PASSWORD + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: password } } + {{- if eq $store.type "s3-store" }} + - name: P_S3_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.url } } + - name: P_S3_ACCESS_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.access.key } } + - name: P_S3_SECRET_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.secret.key } } + - name: P_S3_BUCKET + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.bucket } } + - name: P_S3_REGION + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: s3.region } } + {{- else if eq $store.type "blob-store" }} + - name: P_AZR_ACCESS_KEY + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.access_key } } + - name: P_AZR_ACCOUNT + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.account } } + - name: P_AZR_CONTAINER + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.container } } + - name: P_AZR_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: azr.url } } + {{- else if eq $store.type "gcs-store" }} + - name: P_GCS_URL + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: gcs.url } } + - name: P_GCS_BUCKET + valueFrom: { secretKeyRef: { name: {{ $secret }}, key: gcs.bucket } } + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "{{ $store.gcsCredentials.mountPath }}/{{ $store.gcsCredentials.secretKey }}" + {{- end }} + ports: + - containerPort: 8000 + {{- with $node.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml $node.resources | nindent 12 }} + volumeMounts: + - name: stage-volume + mountPath: "/parseable/staging" + - name: data-volume + mountPath: "/parseable/data" + {{- if $gcs }} + - name: gcs-credentials + mountPath: {{ $store.gcsCredentials.mountPath }} + readOnly: true + {{- end }} + volumes: + {{- if $node.persistence.staging.enabled }} + - name: stage-volume + persistentVolumeClaim: + claimName: {{ include "parseable.fullname" . }}-standalone-staging + {{- else }} + - name: stage-volume + emptyDir: {} + {{- end }} + {{- if $node.persistence.data.enabled }} + - name: data-volume + persistentVolumeClaim: + claimName: {{ include "parseable.fullname" . }}-standalone-data + {{- else }} + - name: data-volume + emptyDir: {} + {{- end }} + {{- if $gcs }} + - name: gcs-credentials + secret: + secretName: {{ $store.gcsCredentials.secretName }} + {{- end }} + {{- with $node.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $node.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $node.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- if $node.persistence.staging.enabled }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "parseable.fullname" . }}-standalone-staging + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} +spec: + accessModes: + - {{ $node.persistence.staging.accessMode | quote }} + storageClassName: {{ $node.persistence.staging.storageClass | quote }} + resources: + requests: + storage: {{ $node.persistence.staging.size | quote }} +{{- end }} +{{- if $node.persistence.data.enabled }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "parseable.fullname" . }}-standalone-data + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} +spec: + accessModes: + - {{ $node.persistence.data.accessMode | quote }} + storageClassName: {{ $node.persistence.data.storageClass | quote }} + resources: + requests: + storage: {{ $node.persistence.data.size | quote }} +{{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "parseable.fullname" . }}-standalone-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "parseable.labels" . | nindent 4 }} +spec: + type: {{ $node.service.type }} + ports: + - port: {{ $node.service.port }} + targetPort: 8000 + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "parseable.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.parseable.com/type: standalone +{{- end }} diff --git a/helm/values-aws.yaml b/helm/values-aws.yaml index d7dd2a882..03b5105b1 100644 --- a/helm/values-aws.yaml +++ b/helm/values-aws.yaml @@ -1,33 +1,19 @@ -# Parseable on AWS (S3), distributed mode +# Parseable on AWS (S3), distributed mode. parseable: - store: s3-store - highAvailability: - enabled: true + deploymentMode: distributed + store: + type: s3-store + secretName: parseable-env-secret - secrets: - name: parseable-env-secret - prefix: P_ - keys: - - addr - - username - - password - - staging.dir - - fs.dir - - s3.url - - s3.access.key - - s3.secret.key - - s3.bucket - - s3.region + ingestor: + replicas: 3 + persistence: + staging: + storageClass: gp3 + size: 5Gi - nodes: - query: - persistence: - enabled: true + querier: + persistence: + hotTier: storageClass: gp3 size: 100Gi - ingestor: - count: 3 - persistence: - enabled: true - storageClass: gp3 - size: 5Gi diff --git a/helm/values-azure.yaml b/helm/values-azure.yaml index 6299d51bd..19f66faed 100644 --- a/helm/values-azure.yaml +++ b/helm/values-azure.yaml @@ -1,32 +1,19 @@ -# Parseable on Azure (Blob), distributed mode +# Parseable on Azure (Blob), distributed mode. parseable: - store: blob-store - highAvailability: - enabled: true + deploymentMode: distributed + store: + type: blob-store + secretName: parseable-env-secret - secrets: - name: parseable-env-secret - prefix: P_ - keys: - - addr - - username - - password - - staging.dir - - fs.dir - - azr.access_key - - azr.account - - azr.container - - azr.url + ingestor: + replicas: 3 + persistence: + staging: + storageClass: managed-csi + size: 5Gi - nodes: - query: - persistence: - enabled: true + querier: + persistence: + hotTier: storageClass: managed-csi size: 100Gi - ingestor: - count: 3 - persistence: - enabled: true - storageClass: managed-csi - size: 5Gi diff --git a/helm/values-gcp.yaml b/helm/values-gcp.yaml index 5d2fb94c1..3350d5a27 100644 --- a/helm/values-gcp.yaml +++ b/helm/values-gcp.yaml @@ -1,37 +1,23 @@ -# Parseable on GCP (GCS), distributed mode +# Parseable on GCP (GCS), distributed mode. parseable: - store: gcs-store - highAvailability: - enabled: true - - secrets: - name: parseable-env-secret - prefix: P_ - keys: - - addr - - username - - password - - staging.dir - - fs.dir - - gcs.url - - gcs.bucket - - # GCS service-account key mounted from the same secret (key.json) - credentialFile: - enabled: true + deploymentMode: distributed + store: + type: gcs-store secretName: parseable-env-secret - secretKey: key.json - mountPath: /var/secrets/google + gcsCredentials: + secretName: parseable-gcs-key + secretKey: key.json + mountPath: /var/secrets/google - nodes: - query: - persistence: - enabled: true - storageClass: standard-rwo - size: 100Gi - ingestor: - count: 3 - persistence: - enabled: true + ingestor: + replicas: 3 + persistence: + staging: storageClass: standard-rwo size: 5Gi + + querier: + persistence: + hotTier: + storageClass: standard-rwo + size: 100Gi diff --git a/helm/values.yaml b/helm/values.yaml index b9ecf7b07..20a389ab6 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -1,53 +1,173 @@ +## Parseable Helm chart +## Single chart for both OSS and Enterprise editions of Parseable. OSS and +## Enterprise ship as separate images (see `image` vs `enterprise.image` +## below); which one gets used is controlled by `enterprise.enabled`, not by +## the node type. +## +## Node types below map 1:1 to Parseable's P_MODE values: +## standalone -> P_MODE=all (OSS only, single all-in-one pod --> Best for testing) +## ingestor -> P_MODE=ingest (OSS + Enterprise, distributed mode) +## querier -> P_MODE=query (Maximum 1 in OSS + Enterprise, distributed mode) +## prism -> P_MODE=prism (Enterprise only, cluster coordinator) +## +## Each node type section below is self-contained: its own replicas, env, +## resources, persistence, service and scheduling. There are no shared +## "common" blocks to hunt through - what you see in a section is everything +## that applies to that node type. +## +## Docs: https://www.parseable.com/docs/installation/kubernetes-helm + parseable: + nameOverride: "" + fullnameOverride: "" + + ## deploymentMode: standalone | distributed + ## standalone - a single all-in-one pod (the `standalone` section below). + ## Simplest way to run Parseable, does not scale horizontally. + ## OSS only. + ## distributed - separate ingestor + querier pods (the `ingestor` / + ## `querier` sections below), plus `prism` when + ## `enterprise.enabled` is true. Required for Enterprise. + deploymentMode: standalone + + ## OSS image, used by every node type unless enterprise.enabled is true + ## (see enterprise.image below, which takes over in that case). image: repository: quay.io/parseablehq/parseable - tag: "v2.8.0" - pullPolicy: Always + tag: "" # defaults to .Chart.AppVersion + pullPolicy: IfNotPresent + ## Names of imagePullSecrets for pulling the image above, e.g. from a private registry. imagePullSecrets: [] - # local-store, s3-store, blob-store or gcs-store - store: local-store + ## ----------------------------------------------------------------------- + ## Object store + ## ----------------------------------------------------------------------- + store: + ## One of: local-store, s3-store, blob-store, gcs-store. + ## local-store keeps data on the pod's own volumes and only works with + ## deploymentMode: standalone - it is not valid for distributed deployments. + type: local-store + + ## Name of a pre-existing Kubernetes Secret holding the connection details + ## for the selected store type, plus the Parseable admin credentials. + ## The chart never creates or reads plaintext secrets from values.yaml. + ## + ## Create it with kubectl, using the keys expected for your store type: + ## + ## local-store: + ## kubectl create secret generic parseable-env-secret \ + ## --from-literal=addr=0.0.0.0:8000 \ + ## --from-literal=username=admin \ + ## --from-literal=password=admin + ## + ## s3-store (adds): + ## --from-literal=s3.url= \ + ## --from-literal=s3.access.key= \ + ## --from-literal=s3.secret.key= \ + ## --from-literal=s3.bucket= \ + ## --from-literal=s3.region= + ## + ## blob-store (adds): + ## --from-literal=azr.access_key= \ + ## --from-literal=azr.account= \ + ## --from-literal=azr.container= \ + ## --from-literal=azr.url= + ## + ## gcs-store (adds): + ## --from-literal=gcs.url= \ + ## --from-literal=gcs.bucket= \ + ## and a service-account key file, see `store.gcsCredentials` below. + secretName: parseable-env-secret + + ## Only used when store.type is gcs-store. Points at a Secret containing + ## the GCS service-account JSON key, which is mounted into every pod. + ## kubectl create secret generic parseable-gcs-key \ + ## --from-file=key.json= + gcsCredentials: + secretName: parseable-gcs-key + secretKey: key.json + mountPath: /var/secrets/google + + ## Optional shared secret to authenticate intra-cluster requests between + ## nodes. When enabled, P_CLUSTER_SECRET is injected into every distributed + ## node from this secret; leave disabled to authenticate with admin + ## credentials only. Not used in standalone mode. + ## kubectl create secret generic parseable-cluster-secret \ + ## --from-literal=cluster-secret=<16-char-alphanumeric-string> + clusterSecret: + enabled: false + secretName: parseable-cluster-secret + secretKey: cluster-secret - # false = single Deployment; true = querier + ingestors (needs an object store) - highAvailability: + ## ----------------------------------------------------------------------- + ## Enterprise edition + ## ----------------------------------------------------------------------- + ## Flip `enabled: true` to run Parseable Enterprise instead of OSS. Requires + ## deploymentMode: distributed. Unlocks the `prism` node-type + ## sections below, plus license validation and audit logging. + enterprise: enabled: false + ## Enterprise runs a different image than OSS. Used by every node type + ## instead of the top-level `image` above whenever enabled is true. + image: + repository: quay.io/parseablehq/parseable-enterprise + tag: "" # defaults to .Chart.AppVersion + pullPolicy: IfNotPresent + imagePullSecrets: [] + + ## License is validated at startup; the server refuses to start without one. + ## Mounted read-only at `license.mountPath` on every node; the Enterprise + ## binary reads the license files from that directory. + ## kubectl create secret generic parseable-license \ + ## --from-file=parseable_license.json=resources/parseable_license.json \ + ## --from-file=parseable_license.sig=resources/parseable_license.sig + license: + secretName: parseable-license + mountPath: /tmp/license + dataKey: parseable_license.json + signatureKey: parseable_license.sig + + ## Ships an audit trail of API activity to another Parseable instance/stream. + ## Applied to every node type (ingestor/querier/prism). + auditLogging: + enabled: false + server: "http://parseable-querier-service.parseable.svc.cluster.local" + username: admin + password: admin + ## Reference to a Secret key holding the password instead of the + ## plaintext `password` field above. + existingSecret: + name: "" + key: "" + + ## ----------------------------------------------------------------------- + ## Shared identity / security (applies to every node type's pod) + ## ----------------------------------------------------------------------- serviceAccount: create: true name: "parseable" annotations: {} - nameOverride: "" - fullnameOverride: "" + securityContext: + allowPrivilegeEscalation: false - # each key is set as an env var: prefix + upper-cased key, "." "-" -> "_" - secrets: - name: parseable-env-secret - prefix: P_ - keys: - - addr - - username - - password - - staging.dir - - fs.dir - - # file credential (e.g. GCS key.json); sets GOOGLE_APPLICATION_CREDENTIALS - credentialFile: - enabled: false - secretName: parseable-env-secret - secretKey: key.json - mountPath: /var/secrets/google + podSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: "Always" - auditLogging: - enabled: false - p_server: "" - p_username: "" - p_password: "" + ## ========================================================================= + ## Node types + ## ========================================================================= - # defaults for every node; a node under nodes: can override any of these - common: + ## --- standalone --- (deploymentMode: standalone, OSS only) --------------- + ## Single pod running every function (ingest + query + storage). + standalone: env: RUST_LOG: warn + P_CHECK_UPDATE: "false" resources: limits: cpu: 500m @@ -55,66 +175,184 @@ parseable: requests: cpu: 250m memory: 1Gi + service: + type: ClusterIP + port: 80 + persistence: + ## Data directory - only needed when store.type is local-store. + data: + enabled: false + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + staging: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "80" + prometheus.io/path: "/api/v1/metrics" + podLabels: + app: parseable + component: standalone + nodeSelector: {} + tolerations: [] + affinity: {} + terminationGracePeriodSeconds: 30 readinessProbe: httpGet: path: /api/v1/readiness port: 8000 - securityContext: - allowPrivilegeEscalation: false - podSecurityContext: - runAsUser: 1000 - runAsGroup: 1000 - fsGroup: 1000 - fsGroupChangePolicy: "Always" + + ## --- ingestor --- (deploymentMode: distributed, OSS + Enterprise) -------- + ## Receives and stages incoming events. + ingestor: + replicas: 3 + env: + RUST_LOG: warn + P_CHECK_UPDATE: "false" + # General Kafka Configuration + # P_KAFKA_BOOTSTRAP_SERVERS: "my-kafka.kafka.svc.cluster.local:9092" # Comma-separated list of Kafka bootstrap servers + # P_KAFKA_PARTITION_LISTENER_CONCURRENCY: "2" # Number of parallel threads for Kafka partition listeners + # P_KAFKA_CONSUMER_TOPICS: "test-log-stream-0,test-log-stream-1" + # P_KAFKA_CLIENT_ID: "parseable-connect" # Client ID for Kafka connection + # P_CONNECTOR_BAD_DATA_POLICY: "fail" # Default Policy for handling bad data + # See https://www.parseable.com/docs for the full list of Kafka consumer/security options. + resources: + limits: + cpu: 500m + memory: 4Gi + requests: + cpu: 250m + memory: 1Gi + service: + type: ClusterIP + port: 80 + ## Local disk for staging incoming events before they are sent to the object store. + persistence: + staging: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi podAnnotations: prometheus.io/scrape: "true" prometheus.io/port: "80" prometheus.io/path: "/api/v1/metrics" - podLabels: {} + podLabels: + app: parseable + component: ingestor nodeSelector: {} tolerations: [] affinity: {} + terminationGracePeriodSeconds: 30 + readinessProbe: + httpGet: + path: /api/v1/readiness + port: 8000 - # per-node overrides; env is merged with common (node wins), rest replaces - nodes: - standalone: - env: {} - service: - type: ClusterIP - port: 80 - persistence: - staging: - enabled: true - storageClass: "" - accessMode: ReadWriteOnce - size: 5Gi - data: - enabled: false - storageClass: "" - accessMode: ReadWriteOnce - size: 5Gi - - query: - env: {} - service: - type: ClusterIP - port: 80 - # enables the hot tier; not supported with local-store - persistence: - enabled: false - storageClass: "" - accessMode: ReadWriteOnce - size: 100Gi - - ingestor: - count: 3 - port: 8000 - env: {} - service: - type: ClusterIP - port: 80 - persistence: - enabled: false + ## --- querier --- (deploymentMode: distributed, OSS + Enterprise) --------- + ## Serves queries and the console. OSS supports a single querier; Enterprise + ## can run multiple queriers behind `prism`. + querier: + replicas: 1 + env: + RUST_LOG: warn + P_CHECK_UPDATE: "false" + resources: + limits: + cpu: 500m + memory: 4Gi + requests: + cpu: 250m + memory: 1Gi + service: + type: ClusterIP + port: 80 + ## Local disk used as the hot-tier query cache, mounted at /parseable/hot-tier. + ## Required for Enterprise query nodes; recommended for OSS performance. + persistence: + hotTier: + enabled: true storageClass: "" accessMode: ReadWriteOnce size: 5Gi + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "80" + prometheus.io/path: "/api/v1/metrics" + podLabels: + app: parseable + component: querier + nodeSelector: {} + tolerations: [] + affinity: {} + terminationGracePeriodSeconds: 30 + readinessProbe: + httpGet: + path: /api/v1/readiness + port: 8000 + + ## --- prism --- (deploymentMode: distributed, Enterprise only) ----------- + ## Cluster coordinator, fronts the querier fleet. Deployed automatically + ## whenever enterprise.enabled is true. + prism: + replicas: 1 + env: + RUST_LOG: warn + P_CHECK_UPDATE: "false" + resources: + limits: + cpu: "1" + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi + service: + type: ClusterIP + port: 80 + ## Local disk for Prism's own state. Optional. + persistence: + enabled: false + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "80" + prometheus.io/path: "/api/v1/metrics" + podLabels: + app: parseable + component: prism + nodeSelector: {} + tolerations: [] + affinity: {} + terminationGracePeriodSeconds: 30 + readinessProbe: + httpGet: + path: /api/v1/readiness + port: 8000 + + ## Create datasets and set their retention on install/upgrade. + ## datasets is a list of objects, each with a name and retention policy. Example: + ## - name: "sample-dataset" + ## retention: + ## action: "delete" + ## duration: "30d" + datasets: [] + + ## ServiceMonitor for this Parseable deployment. Read more on ServiceMonitor + ## here: https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1.ServiceMonitor + metrics: + serviceMonitor: + enabled: false + labels: {} + namespace: "" + interval: 30s + scrapeTimeout: "" + path: /api/v1/metrics + port: http + relabelings: [] + metricRelabelings: [] From 2dbb1550637f2c260fce993cc3e877343643cb43 Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Sun, 12 Jul 2026 15:55:45 +0530 Subject: [PATCH 4/7] helm: add standalone values overlay --- helm/values-standalone.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 helm/values-standalone.yaml diff --git a/helm/values-standalone.yaml b/helm/values-standalone.yaml new file mode 100644 index 000000000..f6817ae6a --- /dev/null +++ b/helm/values-standalone.yaml @@ -0,0 +1,20 @@ +# Parseable standalone: a single all-in-one pod on local-store. +# Simplest way to run Parseable; does not scale horizontally (OSS only). +parseable: + deploymentMode: standalone + store: + type: local-store + + standalone: + persistence: + # local-store keeps ingested data on this volume, so persist it + data: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 10Gi + staging: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi From d6e06990e7c9e777317fb9dd8a8e83445a81cdab Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Sun, 12 Jul 2026 18:36:06 +0530 Subject: [PATCH 5/7] helm: enterprise pods run as root (panorama ML needs writable HOME) --- helm/templates/ingestor.yaml | 4 ++++ helm/templates/prism.yaml | 4 ++-- helm/templates/querier.yaml | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/helm/templates/ingestor.yaml b/helm/templates/ingestor.yaml index 891ca1021..84eee76fc 100644 --- a/helm/templates/ingestor.yaml +++ b/helm/templates/ingestor.yaml @@ -86,8 +86,12 @@ spec: {{- end }} serviceAccountName: {{ include "parseable.serviceAccountName" . }} terminationGracePeriodSeconds: {{ $node.terminationGracePeriodSeconds }} + {{- if not $ent.enabled }} + # OSS runs as non-root; the Enterprise image runs as its default user (root), + # which it needs for its bundled ML (panorama) cache directories. securityContext: {{- toYaml $p.podSecurityContext | nindent 8 }} + {{- end }} {{- with $node.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm/templates/prism.yaml b/helm/templates/prism.yaml index addea1435..e612760e8 100644 --- a/helm/templates/prism.yaml +++ b/helm/templates/prism.yaml @@ -82,8 +82,8 @@ spec: {{- end }} serviceAccountName: {{ include "parseable.serviceAccountName" . }} terminationGracePeriodSeconds: {{ $node.terminationGracePeriodSeconds }} - securityContext: - {{- toYaml $p.podSecurityContext | nindent 8 }} + # prism runs the Enterprise image as its default user (root), which it needs + # for its bundled ML (panorama) cache directories. {{- with $node.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm/templates/querier.yaml b/helm/templates/querier.yaml index 6c7f3a25e..dcca977ce 100644 --- a/helm/templates/querier.yaml +++ b/helm/templates/querier.yaml @@ -86,8 +86,12 @@ spec: {{- end }} serviceAccountName: {{ include "parseable.serviceAccountName" . }} terminationGracePeriodSeconds: {{ $node.terminationGracePeriodSeconds }} + {{- if not $ent.enabled }} + # OSS runs as non-root; the Enterprise image runs as its default user (root), + # which it needs for its bundled ML (panorama) cache directories. securityContext: {{- toYaml $p.podSecurityContext | nindent 8 }} + {{- end }} {{- with $node.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} From 621614675666e38399a2fbda51b354a0b42612a5 Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Sun, 12 Jul 2026 18:40:31 +0530 Subject: [PATCH 6/7] helm: move overlays into overlays/ and add enterprise overlay --- helm/README.md | 28 ++++++++++++++----- helm/{values-aws.yaml => overlays/aws.yaml} | 0 .../azure.yaml} | 0 helm/overlays/enterprise.yaml | 13 +++++++++ helm/{values-gcp.yaml => overlays/gcp.yaml} | 0 .../standalone.yaml} | 0 6 files changed, 34 insertions(+), 7 deletions(-) rename helm/{values-aws.yaml => overlays/aws.yaml} (100%) rename helm/{values-azure.yaml => overlays/azure.yaml} (100%) create mode 100644 helm/overlays/enterprise.yaml rename helm/{values-gcp.yaml => overlays/gcp.yaml} (100%) rename helm/{values-standalone.yaml => overlays/standalone.yaml} (100%) diff --git a/helm/README.md b/helm/README.md index 9ee2e5899..ed8f490c6 100644 --- a/helm/README.md +++ b/helm/README.md @@ -1,5 +1,17 @@ # Parseable Helm Chart +`values.yaml` holds the defaults. Layer an overlay from `overlays/` with `-f` to +pick a topology / store, and stack `overlays/enterprise.yaml` for Enterprise. + +``` +overlays/ + standalone.yaml single all-in-one pod (local-store) + aws.yaml distributed on S3 + gcp.yaml distributed on GCS + azure.yaml distributed on Azure Blob + enterprise.yaml adds prism; layer on top of a store overlay +``` + ## Standalone (single pod, local-store) ```sh @@ -10,7 +22,7 @@ kubectl -n parseable create secret generic parseable-env-secret \ --from-literal=username=admin \ --from-literal=password=admin -helm install parseable ./ -n parseable +helm install parseable ./ -n parseable -f overlays/standalone.yaml ``` ## Distributed (querier + ingestors) @@ -31,7 +43,7 @@ kubectl -n parseable create secret generic parseable-env-secret \ --from-literal=s3.access.key= --from-literal=s3.secret.key= \ --from-literal=s3.bucket= --from-literal=s3.region= -helm install parseable ./ -n parseable -f values-aws.yaml +helm install parseable ./ -n parseable -f overlays/aws.yaml ``` ### GCP (GCS) @@ -45,7 +57,7 @@ kubectl -n parseable create secret generic parseable-env-secret \ kubectl -n parseable create secret generic parseable-gcs-key \ --from-file=key.json= -helm install parseable ./ -n parseable -f values-gcp.yaml +helm install parseable ./ -n parseable -f overlays/gcp.yaml ``` ### Azure (Blob) @@ -58,23 +70,25 @@ kubectl -n parseable create secret generic parseable-env-secret \ --from-literal=azr.container= \ --from-literal=azr.url=https://.blob.core.windows.net -helm install parseable ./ -n parseable -f values-azure.yaml +helm install parseable ./ -n parseable -f overlays/azure.yaml ``` ## Enterprise (adds prism) +Stack `overlays/enterprise.yaml` on top of a store overlay, and create the license secret. + ```sh kubectl -n parseable create secret generic parseable-license \ --from-file=parseable_license.json=/parseable_license.json \ --from-file=parseable_license.sig=/parseable_license.sig -helm install parseable ./ -n parseable -f values-aws.yaml \ - --set parseable.enterprise.enabled=true +helm install parseable ./ -n parseable \ + -f overlays/aws.yaml -f overlays/enterprise.yaml ``` ## Upgrade / Uninstall ```sh -helm upgrade parseable ./ -n parseable -f values-aws.yaml +helm upgrade parseable ./ -n parseable -f overlays/aws.yaml helm uninstall parseable -n parseable ``` diff --git a/helm/values-aws.yaml b/helm/overlays/aws.yaml similarity index 100% rename from helm/values-aws.yaml rename to helm/overlays/aws.yaml diff --git a/helm/values-azure.yaml b/helm/overlays/azure.yaml similarity index 100% rename from helm/values-azure.yaml rename to helm/overlays/azure.yaml diff --git a/helm/overlays/enterprise.yaml b/helm/overlays/enterprise.yaml new file mode 100644 index 000000000..d17e5e4f9 --- /dev/null +++ b/helm/overlays/enterprise.yaml @@ -0,0 +1,13 @@ +# Parseable Enterprise (adds the prism coordinator). +# Layer this on top of a store overlay, e.g.: +# helm install parseable ./ -n parseable -f overlays/aws.yaml -f overlays/enterprise.yaml +# Requires a license secret (parseable-license) with keys +# parseable_license.json and parseable_license.sig. +parseable: + deploymentMode: distributed + enterprise: + enabled: true + image: + repository: quay.io/parseablehq/parseable-enterprise + tag: "" # defaults to .Chart.AppVersion + pullPolicy: IfNotPresent diff --git a/helm/values-gcp.yaml b/helm/overlays/gcp.yaml similarity index 100% rename from helm/values-gcp.yaml rename to helm/overlays/gcp.yaml diff --git a/helm/values-standalone.yaml b/helm/overlays/standalone.yaml similarity index 100% rename from helm/values-standalone.yaml rename to helm/overlays/standalone.yaml From ed24bd99756f621bc3a4b95ed263474e550f7e1e Mon Sep 17 00:00:00 2001 From: AdheipSingh Date: Sun, 12 Jul 2026 19:04:59 +0530 Subject: [PATCH 7/7] helm: group node configs as standalone.unified and distributed.{ingestor,querier,prism} --- helm/overlays/aws.yaml | 24 +-- helm/overlays/azure.yaml | 24 +-- helm/overlays/gcp.yaml | 24 +-- helm/overlays/standalone.yaml | 25 +-- helm/templates/ingestor.yaml | 2 +- helm/templates/prism.yaml | 2 +- helm/templates/querier.yaml | 2 +- helm/templates/standalone.yaml | 2 +- helm/values.yaml | 361 +++++++++++++++++---------------- 9 files changed, 234 insertions(+), 232 deletions(-) diff --git a/helm/overlays/aws.yaml b/helm/overlays/aws.yaml index 03b5105b1..5ca3780b0 100644 --- a/helm/overlays/aws.yaml +++ b/helm/overlays/aws.yaml @@ -5,15 +5,15 @@ parseable: type: s3-store secretName: parseable-env-secret - ingestor: - replicas: 3 - persistence: - staging: - storageClass: gp3 - size: 5Gi - - querier: - persistence: - hotTier: - storageClass: gp3 - size: 100Gi + distributed: + ingestor: + replicas: 3 + persistence: + staging: + storageClass: gp3 + size: 5Gi + querier: + persistence: + hotTier: + storageClass: gp3 + size: 100Gi diff --git a/helm/overlays/azure.yaml b/helm/overlays/azure.yaml index 19f66faed..592e325db 100644 --- a/helm/overlays/azure.yaml +++ b/helm/overlays/azure.yaml @@ -5,15 +5,15 @@ parseable: type: blob-store secretName: parseable-env-secret - ingestor: - replicas: 3 - persistence: - staging: - storageClass: managed-csi - size: 5Gi - - querier: - persistence: - hotTier: - storageClass: managed-csi - size: 100Gi + distributed: + ingestor: + replicas: 3 + persistence: + staging: + storageClass: managed-csi + size: 5Gi + querier: + persistence: + hotTier: + storageClass: managed-csi + size: 100Gi diff --git a/helm/overlays/gcp.yaml b/helm/overlays/gcp.yaml index 3350d5a27..a4b93aad9 100644 --- a/helm/overlays/gcp.yaml +++ b/helm/overlays/gcp.yaml @@ -9,15 +9,15 @@ parseable: secretKey: key.json mountPath: /var/secrets/google - ingestor: - replicas: 3 - persistence: - staging: - storageClass: standard-rwo - size: 5Gi - - querier: - persistence: - hotTier: - storageClass: standard-rwo - size: 100Gi + distributed: + ingestor: + replicas: 3 + persistence: + staging: + storageClass: standard-rwo + size: 5Gi + querier: + persistence: + hotTier: + storageClass: standard-rwo + size: 100Gi diff --git a/helm/overlays/standalone.yaml b/helm/overlays/standalone.yaml index f6817ae6a..0f2e7d317 100644 --- a/helm/overlays/standalone.yaml +++ b/helm/overlays/standalone.yaml @@ -6,15 +6,16 @@ parseable: type: local-store standalone: - persistence: - # local-store keeps ingested data on this volume, so persist it - data: - enabled: true - storageClass: "" - accessMode: ReadWriteOnce - size: 10Gi - staging: - enabled: true - storageClass: "" - accessMode: ReadWriteOnce - size: 5Gi + unified: + persistence: + # local-store keeps ingested data on this volume, so persist it + data: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 10Gi + staging: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi diff --git a/helm/templates/ingestor.yaml b/helm/templates/ingestor.yaml index 84eee76fc..8cc98bff3 100644 --- a/helm/templates/ingestor.yaml +++ b/helm/templates/ingestor.yaml @@ -1,7 +1,7 @@ {{- if eq .Values.parseable.deploymentMode "distributed" }} {{- $p := .Values.parseable }} {{- $ent := $p.enterprise }} -{{- $node := $p.ingestor }} +{{- $node := $p.distributed.ingestor }} {{- $store := $p.store }} {{- $secret := $store.secretName }} {{- $gcs := eq $store.type "gcs-store" }} diff --git a/helm/templates/prism.yaml b/helm/templates/prism.yaml index e612760e8..4c9bde759 100644 --- a/helm/templates/prism.yaml +++ b/helm/templates/prism.yaml @@ -1,7 +1,7 @@ {{- if and (eq .Values.parseable.deploymentMode "distributed") .Values.parseable.enterprise.enabled }} {{- $p := .Values.parseable }} {{- $ent := $p.enterprise }} -{{- $node := $p.prism }} +{{- $node := $p.distributed.prism }} {{- $store := $p.store }} {{- $secret := $store.secretName }} {{- $gcs := eq $store.type "gcs-store" }} diff --git a/helm/templates/querier.yaml b/helm/templates/querier.yaml index dcca977ce..b25370321 100644 --- a/helm/templates/querier.yaml +++ b/helm/templates/querier.yaml @@ -1,7 +1,7 @@ {{- if eq .Values.parseable.deploymentMode "distributed" }} {{- $p := .Values.parseable }} {{- $ent := $p.enterprise }} -{{- $node := $p.querier }} +{{- $node := $p.distributed.querier }} {{- $store := $p.store }} {{- $secret := $store.secretName }} {{- $gcs := eq $store.type "gcs-store" }} diff --git a/helm/templates/standalone.yaml b/helm/templates/standalone.yaml index e1ce45e1a..051447626 100644 --- a/helm/templates/standalone.yaml +++ b/helm/templates/standalone.yaml @@ -3,7 +3,7 @@ {{- fail "enterprise.enabled requires deploymentMode: distributed (standalone runs P_MODE=all, which Enterprise does not support)" }} {{- end }} {{- $p := .Values.parseable }} -{{- $node := $p.standalone }} +{{- $node := $p.standalone.unified }} {{- $store := $p.store }} {{- $secret := $store.secretName }} {{- $gcs := and (eq $store.type "gcs-store") $store.gcsCredentials }} diff --git a/helm/values.yaml b/helm/values.yaml index 20a389ab6..a94423250 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -4,16 +4,15 @@ ## below); which one gets used is controlled by `enterprise.enabled`, not by ## the node type. ## -## Node types below map 1:1 to Parseable's P_MODE values: -## standalone -> P_MODE=all (OSS only, single all-in-one pod --> Best for testing) -## ingestor -> P_MODE=ingest (OSS + Enterprise, distributed mode) -## querier -> P_MODE=query (Maximum 1 in OSS + Enterprise, distributed mode) -## prism -> P_MODE=prism (Enterprise only, cluster coordinator) +## Node types map 1:1 to Parseable's P_MODE values and are grouped by mode: +## standalone.unified -> P_MODE=all (OSS only, single all-in-one pod) +## distributed.ingestor -> P_MODE=ingest (OSS + Enterprise) +## distributed.querier -> P_MODE=query (OSS + Enterprise) +## distributed.prism -> P_MODE=prism (Enterprise only, cluster coordinator) ## -## Each node type section below is self-contained: its own replicas, env, -## resources, persistence, service and scheduling. There are no shared -## "common" blocks to hunt through - what you see in a section is everything -## that applies to that node type. +## Each node section is self-contained: its own replicas, env, resources, +## persistence, service and scheduling. There are no shared "common" blocks - +## what you see in a section is everything that applies to that node type. ## ## Docs: https://www.parseable.com/docs/installation/kubernetes-helm @@ -22,12 +21,12 @@ parseable: fullnameOverride: "" ## deploymentMode: standalone | distributed - ## standalone - a single all-in-one pod (the `standalone` section below). + ## standalone - a single all-in-one pod (the `standalone.unified` section). ## Simplest way to run Parseable, does not scale horizontally. ## OSS only. - ## distributed - separate ingestor + querier pods (the `ingestor` / - ## `querier` sections below), plus `prism` when - ## `enterprise.enabled` is true. Required for Enterprise. + ## distributed - separate ingestor + querier pods (the `distributed.ingestor` + ## / `distributed.querier` sections), plus `distributed.prism` + ## when `enterprise.enabled` is true. Required for Enterprise. deploymentMode: standalone ## OSS image, used by every node type unless enterprise.enabled is true @@ -103,8 +102,8 @@ parseable: ## Enterprise edition ## ----------------------------------------------------------------------- ## Flip `enabled: true` to run Parseable Enterprise instead of OSS. Requires - ## deploymentMode: distributed. Unlocks the `prism` node-type - ## sections below, plus license validation and audit logging. + ## deploymentMode: distributed. Unlocks the `distributed.prism` node type, + ## plus license validation and audit logging. enterprise: enabled: false @@ -152,6 +151,8 @@ parseable: securityContext: allowPrivilegeEscalation: false + ## Pod-level security context. Applied to OSS pods only; Enterprise pods run + ## as the image's default user (root), which its bundled ML feature needs. podSecurityContext: runAsUser: 1000 runAsGroup: 1000 @@ -163,177 +164,177 @@ parseable: ## ========================================================================= ## --- standalone --- (deploymentMode: standalone, OSS only) --------------- - ## Single pod running every function (ingest + query + storage). standalone: - env: - RUST_LOG: warn - P_CHECK_UPDATE: "false" - resources: - limits: - cpu: 500m - memory: 4Gi - requests: - cpu: 250m - memory: 1Gi - service: - type: ClusterIP - port: 80 - persistence: - ## Data directory - only needed when store.type is local-store. - data: - enabled: false - storageClass: "" - accessMode: ReadWriteOnce - size: 5Gi - staging: - enabled: true - storageClass: "" - accessMode: ReadWriteOnce - size: 5Gi - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "80" - prometheus.io/path: "/api/v1/metrics" - podLabels: - app: parseable - component: standalone - nodeSelector: {} - tolerations: [] - affinity: {} - terminationGracePeriodSeconds: 30 - readinessProbe: - httpGet: - path: /api/v1/readiness - port: 8000 + ## Single pod running every function (ingest + query + storage). + unified: + env: + RUST_LOG: warn + P_CHECK_UPDATE: "false" + resources: + limits: + cpu: 500m + memory: 4Gi + requests: + cpu: 250m + memory: 1Gi + service: + type: ClusterIP + port: 80 + persistence: + ## Data directory - only needed when store.type is local-store. + data: + enabled: false + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + staging: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "80" + prometheus.io/path: "/api/v1/metrics" + podLabels: + app: parseable + component: standalone + nodeSelector: {} + tolerations: [] + affinity: {} + terminationGracePeriodSeconds: 30 + readinessProbe: + httpGet: + path: /api/v1/readiness + port: 8000 - ## --- ingestor --- (deploymentMode: distributed, OSS + Enterprise) -------- - ## Receives and stages incoming events. - ingestor: - replicas: 3 - env: - RUST_LOG: warn - P_CHECK_UPDATE: "false" - # General Kafka Configuration - # P_KAFKA_BOOTSTRAP_SERVERS: "my-kafka.kafka.svc.cluster.local:9092" # Comma-separated list of Kafka bootstrap servers - # P_KAFKA_PARTITION_LISTENER_CONCURRENCY: "2" # Number of parallel threads for Kafka partition listeners - # P_KAFKA_CONSUMER_TOPICS: "test-log-stream-0,test-log-stream-1" - # P_KAFKA_CLIENT_ID: "parseable-connect" # Client ID for Kafka connection - # P_CONNECTOR_BAD_DATA_POLICY: "fail" # Default Policy for handling bad data - # See https://www.parseable.com/docs for the full list of Kafka consumer/security options. - resources: - limits: - cpu: 500m - memory: 4Gi - requests: - cpu: 250m - memory: 1Gi - service: - type: ClusterIP - port: 80 - ## Local disk for staging incoming events before they are sent to the object store. - persistence: - staging: - enabled: true - storageClass: "" - accessMode: ReadWriteOnce - size: 5Gi - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "80" - prometheus.io/path: "/api/v1/metrics" - podLabels: - app: parseable - component: ingestor - nodeSelector: {} - tolerations: [] - affinity: {} - terminationGracePeriodSeconds: 30 - readinessProbe: - httpGet: - path: /api/v1/readiness - port: 8000 + ## --- distributed --- (deploymentMode: distributed) ---------------------- + distributed: + ## ingestor (OSS + Enterprise) - receives and stages incoming events. + ingestor: + replicas: 3 + env: + RUST_LOG: warn + P_CHECK_UPDATE: "false" + # General Kafka Configuration + # P_KAFKA_BOOTSTRAP_SERVERS: "my-kafka.kafka.svc.cluster.local:9092" # Comma-separated list of Kafka bootstrap servers + # P_KAFKA_PARTITION_LISTENER_CONCURRENCY: "2" # Number of parallel threads for Kafka partition listeners + # P_KAFKA_CONSUMER_TOPICS: "test-log-stream-0,test-log-stream-1" + # P_KAFKA_CLIENT_ID: "parseable-connect" # Client ID for Kafka connection + # P_CONNECTOR_BAD_DATA_POLICY: "fail" # Default Policy for handling bad data + # See https://www.parseable.com/docs for the full list of Kafka consumer/security options. + resources: + limits: + cpu: 500m + memory: 4Gi + requests: + cpu: 250m + memory: 1Gi + service: + type: ClusterIP + port: 80 + ## Local disk for staging incoming events before they are sent to the object store. + persistence: + staging: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "80" + prometheus.io/path: "/api/v1/metrics" + podLabels: + app: parseable + component: ingestor + nodeSelector: {} + tolerations: [] + affinity: {} + terminationGracePeriodSeconds: 30 + readinessProbe: + httpGet: + path: /api/v1/readiness + port: 8000 + + ## querier (OSS + Enterprise) - serves queries and the console. OSS supports + ## a single querier; Enterprise can run multiple queriers behind prism. + querier: + replicas: 1 + env: + RUST_LOG: warn + P_CHECK_UPDATE: "false" + resources: + limits: + cpu: 500m + memory: 4Gi + requests: + cpu: 250m + memory: 1Gi + service: + type: ClusterIP + port: 80 + ## Local disk used as the hot-tier query cache, mounted at /parseable/hot-tier. + ## Required for Enterprise query nodes; recommended for OSS performance. + persistence: + hotTier: + enabled: true + storageClass: "" + accessMode: ReadWriteOnce + size: 5Gi + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "80" + prometheus.io/path: "/api/v1/metrics" + podLabels: + app: parseable + component: querier + nodeSelector: {} + tolerations: [] + affinity: {} + terminationGracePeriodSeconds: 30 + readinessProbe: + httpGet: + path: /api/v1/readiness + port: 8000 - ## --- querier --- (deploymentMode: distributed, OSS + Enterprise) --------- - ## Serves queries and the console. OSS supports a single querier; Enterprise - ## can run multiple queriers behind `prism`. - querier: - replicas: 1 - env: - RUST_LOG: warn - P_CHECK_UPDATE: "false" - resources: - limits: - cpu: 500m - memory: 4Gi - requests: - cpu: 250m - memory: 1Gi - service: - type: ClusterIP - port: 80 - ## Local disk used as the hot-tier query cache, mounted at /parseable/hot-tier. - ## Required for Enterprise query nodes; recommended for OSS performance. - persistence: - hotTier: - enabled: true + ## prism (Enterprise only) - cluster coordinator, fronts the querier fleet. + ## Deployed automatically whenever enterprise.enabled is true. + prism: + replicas: 1 + env: + RUST_LOG: warn + P_CHECK_UPDATE: "false" + resources: + limits: + cpu: "1" + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi + service: + type: ClusterIP + port: 80 + ## Local disk for Prism's own state. Optional. + persistence: + enabled: false storageClass: "" accessMode: ReadWriteOnce size: 5Gi - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "80" - prometheus.io/path: "/api/v1/metrics" - podLabels: - app: parseable - component: querier - nodeSelector: {} - tolerations: [] - affinity: {} - terminationGracePeriodSeconds: 30 - readinessProbe: - httpGet: - path: /api/v1/readiness - port: 8000 - - ## --- prism --- (deploymentMode: distributed, Enterprise only) ----------- - ## Cluster coordinator, fronts the querier fleet. Deployed automatically - ## whenever enterprise.enabled is true. - prism: - replicas: 1 - env: - RUST_LOG: warn - P_CHECK_UPDATE: "false" - resources: - limits: - cpu: "1" - memory: 2Gi - requests: - cpu: 500m - memory: 1Gi - service: - type: ClusterIP - port: 80 - ## Local disk for Prism's own state. Optional. - persistence: - enabled: false - storageClass: "" - accessMode: ReadWriteOnce - size: 5Gi - podAnnotations: - prometheus.io/scrape: "true" - prometheus.io/port: "80" - prometheus.io/path: "/api/v1/metrics" - podLabels: - app: parseable - component: prism - nodeSelector: {} - tolerations: [] - affinity: {} - terminationGracePeriodSeconds: 30 - readinessProbe: - httpGet: - path: /api/v1/readiness - port: 8000 + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "80" + prometheus.io/path: "/api/v1/metrics" + podLabels: + app: parseable + component: prism + nodeSelector: {} + tolerations: [] + affinity: {} + terminationGracePeriodSeconds: 30 + readinessProbe: + httpGet: + path: /api/v1/readiness + port: 8000 ## Create datasets and set their retention on install/upgrade. ## datasets is a list of objects, each with a name and retention policy. Example: